1204 lines
54 KiB
TypeScript
1204 lines
54 KiB
TypeScript
import {
|
|
IExecuteFunctions,
|
|
INodeExecutionData,
|
|
INodeType,
|
|
INodeTypeDescription,
|
|
IHttpRequestMethods,
|
|
NodeApiError,
|
|
NodeOperationError,
|
|
} from 'n8n-workflow';
|
|
|
|
interface LibreBookingSession {
|
|
sessionToken: string;
|
|
userId: number;
|
|
sessionExpires: string;
|
|
}
|
|
|
|
/**
|
|
* Authentifizierung bei LibreBooking
|
|
*/
|
|
async function authenticate(
|
|
executeFunctions: IExecuteFunctions,
|
|
baseUrl: string,
|
|
username: string,
|
|
password: string,
|
|
): Promise<LibreBookingSession> {
|
|
try {
|
|
const response = await executeFunctions.helpers.httpRequest({
|
|
method: 'POST',
|
|
url: `${baseUrl}/Web/Services/index.php/Authentication/Authenticate`,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: { username, password },
|
|
json: true,
|
|
});
|
|
|
|
if (!response.isAuthenticated) {
|
|
throw new NodeOperationError(
|
|
executeFunctions.getNode(),
|
|
'Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihre Credentials.',
|
|
);
|
|
}
|
|
|
|
return {
|
|
sessionToken: response.sessionToken,
|
|
userId: response.userId,
|
|
sessionExpires: response.sessionExpires,
|
|
};
|
|
} catch (error: any) {
|
|
throw new NodeApiError(executeFunctions.getNode(), error, {
|
|
message: 'Authentifizierung fehlgeschlagen',
|
|
description: 'Überprüfen Sie die LibreBooking URL und Ihre Zugangsdaten.',
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Abmeldung von LibreBooking
|
|
*/
|
|
async function signOut(
|
|
executeFunctions: IExecuteFunctions,
|
|
baseUrl: string,
|
|
session: LibreBookingSession,
|
|
): Promise<void> {
|
|
try {
|
|
await executeFunctions.helpers.httpRequest({
|
|
method: 'POST',
|
|
url: `${baseUrl}/Web/Services/index.php/Authentication/SignOut`,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: {
|
|
userId: session.userId,
|
|
sessionToken: session.sessionToken,
|
|
},
|
|
json: true,
|
|
});
|
|
} catch (error) {
|
|
// Ignoriere SignOut-Fehler
|
|
}
|
|
}
|
|
|
|
/**
|
|
* API-Request mit Session-Authentifizierung
|
|
*/
|
|
async function makeApiRequest(
|
|
executeFunctions: IExecuteFunctions,
|
|
baseUrl: string,
|
|
session: LibreBookingSession,
|
|
method: IHttpRequestMethods,
|
|
endpoint: string,
|
|
body?: any,
|
|
qs?: any,
|
|
): Promise<any> {
|
|
const options: any = {
|
|
method,
|
|
url: `${baseUrl}/Web/Services/index.php${endpoint}`,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Booked-SessionToken': session.sessionToken,
|
|
'X-Booked-UserId': session.userId.toString(),
|
|
},
|
|
json: true,
|
|
};
|
|
|
|
if (body && Object.keys(body).length > 0) {
|
|
options.body = body;
|
|
}
|
|
|
|
if (qs && Object.keys(qs).length > 0) {
|
|
options.qs = qs;
|
|
}
|
|
|
|
try {
|
|
return await executeFunctions.helpers.httpRequest(options);
|
|
} catch (error: any) {
|
|
if (error.statusCode === 401) {
|
|
throw new NodeApiError(executeFunctions.getNode(), error, {
|
|
message: 'Authentifizierung abgelaufen',
|
|
description: 'Der Session-Token ist abgelaufen. Bitte erneut ausführen.',
|
|
});
|
|
} else if (error.statusCode === 403) {
|
|
throw new NodeApiError(executeFunctions.getNode(), error, {
|
|
message: 'Zugriff verweigert',
|
|
description: 'Sie haben keine Berechtigung für diese Operation. Admin-Rechte erforderlich?',
|
|
});
|
|
} else if (error.statusCode === 404) {
|
|
throw new NodeApiError(executeFunctions.getNode(), error, {
|
|
message: 'Nicht gefunden',
|
|
description: 'Die angeforderte Ressource wurde nicht gefunden.',
|
|
});
|
|
}
|
|
throw new NodeApiError(executeFunctions.getNode(), error, {
|
|
message: `API-Fehler: ${error.message}`,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hilfsfunktion: String zu Array von Zahlen
|
|
*/
|
|
function parseIdList(value: string | undefined): number[] {
|
|
if (!value || value.trim() === '') return [];
|
|
return value.split(',').map(id => parseInt(id.trim(), 10)).filter(id => !isNaN(id));
|
|
}
|
|
|
|
/**
|
|
* LibreBooking n8n Node
|
|
*
|
|
* Vollständige Integration für die LibreBooking API.
|
|
* Unterstützt alle wichtigen Ressourcen und Operationen.
|
|
*/
|
|
export class LibreBooking implements INodeType {
|
|
description: INodeTypeDescription = {
|
|
displayName: 'LibreBooking',
|
|
name: 'libreBooking',
|
|
icon: 'file:librebooking.svg',
|
|
group: ['transform'],
|
|
version: 1,
|
|
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
description: 'Verwalten Sie Reservierungen, Ressourcen, Benutzer und mehr mit LibreBooking',
|
|
defaults: {
|
|
name: 'LibreBooking',
|
|
},
|
|
inputs: ['main'],
|
|
outputs: ['main'],
|
|
credentials: [
|
|
{
|
|
name: 'libreBookingApi',
|
|
required: true,
|
|
},
|
|
],
|
|
properties: [
|
|
// =====================================================
|
|
// RESOURCE SELECTOR
|
|
// =====================================================
|
|
{
|
|
displayName: 'Ressource',
|
|
name: 'resource',
|
|
type: 'options',
|
|
noDataExpression: true,
|
|
options: [
|
|
{
|
|
name: 'Reservierung',
|
|
value: 'reservation',
|
|
description: 'Reservierungen verwalten',
|
|
},
|
|
{
|
|
name: 'Ressource',
|
|
value: 'resource',
|
|
description: 'Ressourcen (Räume, Equipment) verwalten',
|
|
},
|
|
{
|
|
name: 'Zeitplan',
|
|
value: 'schedule',
|
|
description: 'Zeitpläne abrufen',
|
|
},
|
|
{
|
|
name: 'Benutzer',
|
|
value: 'user',
|
|
description: 'Benutzer verwalten (Admin-Rechte erforderlich)',
|
|
},
|
|
{
|
|
name: 'Konto',
|
|
value: 'account',
|
|
description: 'Eigenes Konto verwalten',
|
|
},
|
|
{
|
|
name: 'Gruppe',
|
|
value: 'group',
|
|
description: 'Benutzergruppen verwalten',
|
|
},
|
|
{
|
|
name: 'Zubehör',
|
|
value: 'accessory',
|
|
description: 'Zubehör abrufen',
|
|
},
|
|
{
|
|
name: 'Attribut',
|
|
value: 'attribute',
|
|
description: 'Benutzerdefinierte Attribute verwalten',
|
|
},
|
|
],
|
|
default: 'reservation',
|
|
},
|
|
|
|
// =====================================================
|
|
// RESERVATION OPERATIONS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Operation',
|
|
name: 'operation',
|
|
type: 'options',
|
|
noDataExpression: true,
|
|
displayOptions: {
|
|
show: {
|
|
resource: ['reservation'],
|
|
},
|
|
},
|
|
options: [
|
|
{ name: 'Erstellen', value: 'create', description: 'Neue Reservierung erstellen', action: 'Reservierung erstellen' },
|
|
{ name: 'Abrufen', value: 'get', description: 'Reservierung abrufen', action: 'Reservierung abrufen' },
|
|
{ name: 'Alle Abrufen', value: 'getAll', description: 'Alle Reservierungen abrufen', action: 'Alle Reservierungen abrufen' },
|
|
{ name: 'Aktualisieren', value: 'update', description: 'Reservierung aktualisieren', action: 'Reservierung aktualisieren' },
|
|
{ name: 'Löschen', value: 'delete', description: 'Reservierung löschen', action: 'Reservierung löschen' },
|
|
{ name: 'Genehmigen', value: 'approve', description: 'Ausstehende Reservierung genehmigen', action: 'Reservierung genehmigen' },
|
|
{ name: 'Check-In', value: 'checkIn', description: 'In Reservierung einchecken', action: 'In Reservierung einchecken' },
|
|
{ name: 'Check-Out', value: 'checkOut', description: 'Aus Reservierung auschecken', action: 'Aus Reservierung auschecken' },
|
|
],
|
|
default: 'getAll',
|
|
},
|
|
|
|
// =====================================================
|
|
// RESOURCE OPERATIONS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Operation',
|
|
name: 'operation',
|
|
type: 'options',
|
|
noDataExpression: true,
|
|
displayOptions: { show: { resource: ['resource'] } },
|
|
options: [
|
|
{ name: 'Alle Abrufen', value: 'getAll', description: 'Alle Ressourcen abrufen', action: 'Alle Ressourcen abrufen' },
|
|
{ name: 'Abrufen', value: 'get', description: 'Ressource abrufen', action: 'Ressource abrufen' },
|
|
{ name: 'Verfügbarkeit Prüfen', value: 'getAvailability', description: 'Verfügbarkeit von Ressourcen prüfen', action: 'Verfügbarkeit prüfen' },
|
|
{ name: 'Gruppen Abrufen', value: 'getGroups', description: 'Ressourcen-Gruppen abrufen', action: 'Ressourcen-Gruppen abrufen' },
|
|
{ name: 'Typen Abrufen', value: 'getTypes', description: 'Ressourcen-Typen abrufen', action: 'Ressourcen-Typen abrufen' },
|
|
{ name: 'Status Abrufen', value: 'getStatuses', description: 'Verfügbare Status abrufen', action: 'Status abrufen' },
|
|
{ name: 'Erstellen', value: 'create', description: 'Neue Ressource erstellen (Admin)', action: 'Ressource erstellen' },
|
|
{ name: 'Aktualisieren', value: 'update', description: 'Ressource aktualisieren (Admin)', action: 'Ressource aktualisieren' },
|
|
{ name: 'Löschen', value: 'delete', description: 'Ressource löschen (Admin)', action: 'Ressource löschen' },
|
|
],
|
|
default: 'getAll',
|
|
},
|
|
|
|
// =====================================================
|
|
// SCHEDULE OPERATIONS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Operation',
|
|
name: 'operation',
|
|
type: 'options',
|
|
noDataExpression: true,
|
|
displayOptions: { show: { resource: ['schedule'] } },
|
|
options: [
|
|
{ name: 'Alle Abrufen', value: 'getAll', description: 'Alle Zeitpläne abrufen', action: 'Alle Zeitpläne abrufen' },
|
|
{ name: 'Abrufen', value: 'get', description: 'Zeitplan abrufen', action: 'Zeitplan abrufen' },
|
|
{ name: 'Slots Abrufen', value: 'getSlots', description: 'Verfügbare Slots abrufen', action: 'Slots abrufen' },
|
|
],
|
|
default: 'getAll',
|
|
},
|
|
|
|
// =====================================================
|
|
// USER OPERATIONS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Operation',
|
|
name: 'operation',
|
|
type: 'options',
|
|
noDataExpression: true,
|
|
displayOptions: { show: { resource: ['user'] } },
|
|
options: [
|
|
{ name: 'Alle Abrufen', value: 'getAll', description: 'Alle Benutzer abrufen', action: 'Alle Benutzer abrufen' },
|
|
{ name: 'Abrufen', value: 'get', description: 'Benutzer abrufen', action: 'Benutzer abrufen' },
|
|
{ name: 'Erstellen', value: 'create', description: 'Neuen Benutzer erstellen (Admin)', action: 'Benutzer erstellen' },
|
|
{ name: 'Aktualisieren', value: 'update', description: 'Benutzer aktualisieren (Admin)', action: 'Benutzer aktualisieren' },
|
|
{ name: 'Passwort Ändern', value: 'updatePassword', description: 'Benutzer-Passwort ändern (Admin)', action: 'Passwort ändern' },
|
|
{ name: 'Löschen', value: 'delete', description: 'Benutzer löschen (Admin)', action: 'Benutzer löschen' },
|
|
],
|
|
default: 'getAll',
|
|
},
|
|
|
|
// =====================================================
|
|
// ACCOUNT OPERATIONS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Operation',
|
|
name: 'operation',
|
|
type: 'options',
|
|
noDataExpression: true,
|
|
displayOptions: { show: { resource: ['account'] } },
|
|
options: [
|
|
{ name: 'Abrufen', value: 'get', description: 'Eigene Kontoinformationen abrufen', action: 'Konto abrufen' },
|
|
{ name: 'Erstellen', value: 'create', description: 'Neues Konto erstellen (Registrierung)', action: 'Konto erstellen' },
|
|
{ name: 'Aktualisieren', value: 'update', description: 'Eigenes Konto aktualisieren', action: 'Konto aktualisieren' },
|
|
{ name: 'Passwort Ändern', value: 'updatePassword', description: 'Eigenes Passwort ändern', action: 'Passwort ändern' },
|
|
],
|
|
default: 'get',
|
|
},
|
|
|
|
// =====================================================
|
|
// GROUP OPERATIONS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Operation',
|
|
name: 'operation',
|
|
type: 'options',
|
|
noDataExpression: true,
|
|
displayOptions: { show: { resource: ['group'] } },
|
|
options: [
|
|
{ name: 'Alle Abrufen', value: 'getAll', description: 'Alle Gruppen abrufen', action: 'Alle Gruppen abrufen' },
|
|
{ name: 'Abrufen', value: 'get', description: 'Gruppe abrufen', action: 'Gruppe abrufen' },
|
|
{ name: 'Erstellen', value: 'create', description: 'Neue Gruppe erstellen (Admin)', action: 'Gruppe erstellen' },
|
|
{ name: 'Aktualisieren', value: 'update', description: 'Gruppe aktualisieren (Admin)', action: 'Gruppe aktualisieren' },
|
|
{ name: 'Löschen', value: 'delete', description: 'Gruppe löschen (Admin)', action: 'Gruppe löschen' },
|
|
{ name: 'Rollen Ändern', value: 'changeRoles', description: 'Gruppenrollen ändern (Admin)', action: 'Rollen ändern' },
|
|
{ name: 'Berechtigungen Ändern', value: 'changePermissions', description: 'Gruppenberechtigungen ändern (Admin)', action: 'Berechtigungen ändern' },
|
|
{ name: 'Benutzer Ändern', value: 'changeUsers', description: 'Gruppenbenutzer ändern (Admin)', action: 'Benutzer ändern' },
|
|
],
|
|
default: 'getAll',
|
|
},
|
|
|
|
// =====================================================
|
|
// ACCESSORY OPERATIONS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Operation',
|
|
name: 'operation',
|
|
type: 'options',
|
|
noDataExpression: true,
|
|
displayOptions: { show: { resource: ['accessory'] } },
|
|
options: [
|
|
{ name: 'Alle Abrufen', value: 'getAll', description: 'Alle Zubehörteile abrufen', action: 'Alle Zubehörteile abrufen' },
|
|
{ name: 'Abrufen', value: 'get', description: 'Zubehörteil abrufen', action: 'Zubehörteil abrufen' },
|
|
],
|
|
default: 'getAll',
|
|
},
|
|
|
|
// =====================================================
|
|
// ATTRIBUTE OPERATIONS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Operation',
|
|
name: 'operation',
|
|
type: 'options',
|
|
noDataExpression: true,
|
|
displayOptions: { show: { resource: ['attribute'] } },
|
|
options: [
|
|
{ name: 'Abrufen', value: 'get', description: 'Attribut abrufen', action: 'Attribut abrufen' },
|
|
{ name: 'Nach Kategorie Abrufen', value: 'getByCategory', description: 'Attribute einer Kategorie abrufen', action: 'Attribute nach Kategorie abrufen' },
|
|
{ name: 'Erstellen', value: 'create', description: 'Neues Attribut erstellen (Admin)', action: 'Attribut erstellen' },
|
|
{ name: 'Aktualisieren', value: 'update', description: 'Attribut aktualisieren (Admin)', action: 'Attribut aktualisieren' },
|
|
{ name: 'Löschen', value: 'delete', description: 'Attribut löschen (Admin)', action: 'Attribut löschen' },
|
|
],
|
|
default: 'getByCategory',
|
|
},
|
|
|
|
// =====================================================
|
|
// RESERVATION PARAMETERS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Referenznummer',
|
|
name: 'referenceNumber',
|
|
type: 'string',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['reservation'], operation: ['get', 'update', 'delete', 'approve', 'checkIn', 'checkOut'] } },
|
|
default: '',
|
|
description: 'Die eindeutige Referenznummer der Reservierung',
|
|
},
|
|
{
|
|
displayName: 'Ressourcen-ID',
|
|
name: 'resourceId',
|
|
type: 'number',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['reservation'], operation: ['create'] } },
|
|
default: 1,
|
|
description: 'Die ID der zu reservierenden Ressource',
|
|
},
|
|
{
|
|
displayName: 'Startzeit',
|
|
name: 'startDateTime',
|
|
type: 'dateTime',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['reservation'], operation: ['create', 'update'] } },
|
|
default: '',
|
|
description: 'Startzeitpunkt der Reservierung (ISO 8601 Format)',
|
|
},
|
|
{
|
|
displayName: 'Endzeit',
|
|
name: 'endDateTime',
|
|
type: 'dateTime',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['reservation'], operation: ['create', 'update'] } },
|
|
default: '',
|
|
description: 'Endzeitpunkt der Reservierung (ISO 8601 Format)',
|
|
},
|
|
{
|
|
displayName: 'Titel',
|
|
name: 'title',
|
|
type: 'string',
|
|
displayOptions: { show: { resource: ['reservation'], operation: ['create', 'update'] } },
|
|
default: '',
|
|
description: 'Titel der Reservierung',
|
|
},
|
|
{
|
|
displayName: 'Aktualisierungsbereich',
|
|
name: 'updateScope',
|
|
type: 'options',
|
|
displayOptions: { show: { resource: ['reservation'], operation: ['update', 'delete'] } },
|
|
options: [
|
|
{ name: 'Nur Diese', value: 'this', description: 'Nur diese Instanz ändern' },
|
|
{ name: 'Zukünftige', value: 'future', description: 'Diese und alle zukünftigen Instanzen ändern' },
|
|
{ name: 'Alle', value: 'full', description: 'Alle Instanzen der Serie ändern' },
|
|
],
|
|
default: 'this',
|
|
},
|
|
{
|
|
displayName: 'Zusätzliche Felder',
|
|
name: 'additionalFields',
|
|
type: 'collection',
|
|
placeholder: 'Feld hinzufügen',
|
|
default: {},
|
|
displayOptions: { show: { resource: ['reservation'], operation: ['create', 'update'] } },
|
|
options: [
|
|
{ displayName: 'Beschreibung', name: 'description', type: 'string', default: '' },
|
|
{ displayName: 'Benutzer-ID', name: 'userId', type: 'number', default: '' },
|
|
{ displayName: 'Zusätzliche Ressourcen', name: 'resources', type: 'string', default: '', description: 'Komma-getrennte Liste' },
|
|
{ displayName: 'Teilnehmer', name: 'participants', type: 'string', default: '', description: 'Komma-getrennte Benutzer-IDs' },
|
|
{ displayName: 'Eingeladene', name: 'invitees', type: 'string', default: '', description: 'Komma-getrennte Benutzer-IDs' },
|
|
{ displayName: 'Teilnahme Erlauben', name: 'allowParticipation', type: 'boolean', default: true },
|
|
{ displayName: 'Nutzungsbedingungen Akzeptiert', name: 'termsAccepted', type: 'boolean', default: true },
|
|
],
|
|
},
|
|
{
|
|
displayName: 'Filter',
|
|
name: 'filters',
|
|
type: 'collection',
|
|
placeholder: 'Filter hinzufügen',
|
|
default: {},
|
|
displayOptions: { show: { resource: ['reservation'], operation: ['getAll'] } },
|
|
options: [
|
|
{ displayName: 'Benutzer-ID', name: 'userId', type: 'number', default: '' },
|
|
{ displayName: 'Ressourcen-ID', name: 'resourceId', type: 'number', default: '' },
|
|
{ displayName: 'Zeitplan-ID', name: 'scheduleId', type: 'number', default: '' },
|
|
{ displayName: 'Startzeit', name: 'startDateTime', type: 'dateTime', default: '' },
|
|
{ displayName: 'Endzeit', name: 'endDateTime', type: 'dateTime', default: '' },
|
|
],
|
|
},
|
|
|
|
// =====================================================
|
|
// RESOURCE PARAMETERS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Ressourcen-ID',
|
|
name: 'resourceIdParam',
|
|
type: 'number',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['resource'], operation: ['get', 'update', 'delete'] } },
|
|
default: 1,
|
|
},
|
|
{
|
|
displayName: 'Ressourcen-ID (Optional)',
|
|
name: 'resourceIdOptional',
|
|
type: 'number',
|
|
displayOptions: { show: { resource: ['resource'], operation: ['getAvailability'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Datum/Zeit',
|
|
name: 'availabilityDateTime',
|
|
type: 'dateTime',
|
|
displayOptions: { show: { resource: ['resource'], operation: ['getAvailability'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Ressourcen-Name',
|
|
name: 'resourceName',
|
|
type: 'string',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['resource'], operation: ['create', 'update'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Zeitplan-ID',
|
|
name: 'scheduleIdForResource',
|
|
type: 'number',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['resource'], operation: ['create'] } },
|
|
default: 1,
|
|
},
|
|
{
|
|
displayName: 'Ressourcen-Optionen',
|
|
name: 'resourceOptions',
|
|
type: 'collection',
|
|
placeholder: 'Option hinzufügen',
|
|
default: {},
|
|
displayOptions: { show: { resource: ['resource'], operation: ['create', 'update'] } },
|
|
options: [
|
|
{ displayName: 'Standort', name: 'location', type: 'string', default: '' },
|
|
{ displayName: 'Kontakt', name: 'contact', type: 'string', default: '' },
|
|
{ displayName: 'Beschreibung', name: 'description', type: 'string', default: '' },
|
|
{ displayName: 'Notizen', name: 'notes', type: 'string', default: '' },
|
|
{ displayName: 'Max. Teilnehmer', name: 'maxParticipants', type: 'number', default: 0 },
|
|
{ displayName: 'Genehmigung Erforderlich', name: 'requiresApproval', type: 'boolean', default: false },
|
|
{ displayName: 'Mehrtägig Erlauben', name: 'allowMultiday', type: 'boolean', default: false },
|
|
{ displayName: 'Check-In Erforderlich', name: 'requiresCheckIn', type: 'boolean', default: false },
|
|
{ displayName: 'Auto-Release Minuten', name: 'autoReleaseMinutes', type: 'number', default: 0 },
|
|
{ displayName: 'Farbe', name: 'color', type: 'string', default: '' },
|
|
{ displayName: 'Status-ID', name: 'statusId', type: 'options', options: [{ name: 'Versteckt', value: 0 }, { name: 'Verfügbar', value: 1 }, { name: 'Nicht Verfügbar', value: 2 }], default: 1 },
|
|
],
|
|
},
|
|
|
|
// =====================================================
|
|
// SCHEDULE PARAMETERS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Zeitplan-ID',
|
|
name: 'scheduleId',
|
|
type: 'number',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['schedule'], operation: ['get', 'getSlots'] } },
|
|
default: 1,
|
|
},
|
|
{
|
|
displayName: 'Slots-Filter',
|
|
name: 'slotsFilters',
|
|
type: 'collection',
|
|
placeholder: 'Filter hinzufügen',
|
|
default: {},
|
|
displayOptions: { show: { resource: ['schedule'], operation: ['getSlots'] } },
|
|
options: [
|
|
{ displayName: 'Ressourcen-ID', name: 'resourceId', type: 'number', default: '' },
|
|
{ displayName: 'Startzeit', name: 'startDateTime', type: 'dateTime', default: '' },
|
|
{ displayName: 'Endzeit', name: 'endDateTime', type: 'dateTime', default: '' },
|
|
],
|
|
},
|
|
|
|
// =====================================================
|
|
// USER PARAMETERS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Benutzer-ID',
|
|
name: 'userId',
|
|
type: 'number',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['user'], operation: ['get', 'update', 'updatePassword', 'delete'] } },
|
|
default: 1,
|
|
},
|
|
{
|
|
displayName: 'E-Mail',
|
|
name: 'emailAddress',
|
|
type: 'string',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['user'], operation: ['create'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Benutzername',
|
|
name: 'userName',
|
|
type: 'string',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['user'], operation: ['create'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Passwort',
|
|
name: 'password',
|
|
type: 'string',
|
|
typeOptions: { password: true },
|
|
required: true,
|
|
displayOptions: { show: { resource: ['user'], operation: ['create', 'updatePassword'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Vorname',
|
|
name: 'firstName',
|
|
type: 'string',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['user'], operation: ['create', 'update'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Nachname',
|
|
name: 'lastName',
|
|
type: 'string',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['user'], operation: ['create', 'update'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Benutzer-Filter',
|
|
name: 'userFilters',
|
|
type: 'collection',
|
|
placeholder: 'Filter hinzufügen',
|
|
default: {},
|
|
displayOptions: { show: { resource: ['user'], operation: ['getAll'] } },
|
|
options: [
|
|
{ displayName: 'Benutzername', name: 'username', type: 'string', default: '' },
|
|
{ displayName: 'E-Mail', name: 'email', type: 'string', default: '' },
|
|
{ displayName: 'Vorname', name: 'firstName', type: 'string', default: '' },
|
|
{ displayName: 'Nachname', name: 'lastName', type: 'string', default: '' },
|
|
{ displayName: 'Organisation', name: 'organization', type: 'string', default: '' },
|
|
],
|
|
},
|
|
{
|
|
displayName: 'Benutzer-Optionen',
|
|
name: 'userOptions',
|
|
type: 'collection',
|
|
placeholder: 'Option hinzufügen',
|
|
default: {},
|
|
displayOptions: { show: { resource: ['user'], operation: ['create', 'update'] } },
|
|
options: [
|
|
{ displayName: 'Zeitzone', name: 'timezone', type: 'string', default: 'Europe/Berlin' },
|
|
{ displayName: 'Sprache', name: 'language', type: 'string', default: 'de_de' },
|
|
{ displayName: 'Telefon', name: 'phone', type: 'string', default: '' },
|
|
{ displayName: 'Organisation', name: 'organization', type: 'string', default: '' },
|
|
{ displayName: 'Position', name: 'position', type: 'string', default: '' },
|
|
{ displayName: 'Gruppen', name: 'groups', type: 'string', default: '', description: 'Komma-getrennte Gruppen-IDs' },
|
|
],
|
|
},
|
|
|
|
// =====================================================
|
|
// ACCOUNT PARAMETERS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Benutzer-ID',
|
|
name: 'accountUserId',
|
|
type: 'number',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['account'], operation: ['get', 'update', 'updatePassword'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Account-Daten',
|
|
name: 'accountData',
|
|
type: 'collection',
|
|
placeholder: 'Feld hinzufügen',
|
|
default: {},
|
|
displayOptions: { show: { resource: ['account'], operation: ['create', 'update'] } },
|
|
options: [
|
|
{ displayName: 'E-Mail', name: 'emailAddress', type: 'string', default: '' },
|
|
{ displayName: 'Benutzername', name: 'userName', type: 'string', default: '' },
|
|
{ displayName: 'Passwort', name: 'password', type: 'string', typeOptions: { password: true }, default: '' },
|
|
{ displayName: 'Vorname', name: 'firstName', type: 'string', default: '' },
|
|
{ displayName: 'Nachname', name: 'lastName', type: 'string', default: '' },
|
|
{ displayName: 'Zeitzone', name: 'timezone', type: 'string', default: 'Europe/Berlin' },
|
|
{ displayName: 'Sprache', name: 'language', type: 'string', default: 'de_de' },
|
|
{ displayName: 'Telefon', name: 'phone', type: 'string', default: '' },
|
|
{ displayName: 'Organisation', name: 'organization', type: 'string', default: '' },
|
|
{ displayName: 'Position', name: 'position', type: 'string', default: '' },
|
|
{ displayName: 'AGB Akzeptiert', name: 'acceptTermsOfService', type: 'boolean', default: true },
|
|
],
|
|
},
|
|
{
|
|
displayName: 'Passwort-Änderung',
|
|
name: 'passwordChange',
|
|
type: 'fixedCollection',
|
|
default: {},
|
|
displayOptions: { show: { resource: ['account'], operation: ['updatePassword'] } },
|
|
options: [
|
|
{
|
|
name: 'passwords',
|
|
displayName: 'Passwörter',
|
|
values: [
|
|
{ displayName: 'Aktuelles Passwort', name: 'currentPassword', type: 'string', typeOptions: { password: true }, default: '' },
|
|
{ displayName: 'Neues Passwort', name: 'newPassword', type: 'string', typeOptions: { password: true }, default: '' },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
|
|
// =====================================================
|
|
// GROUP PARAMETERS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Gruppen-ID',
|
|
name: 'groupId',
|
|
type: 'number',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['group'], operation: ['get', 'update', 'delete', 'changeRoles', 'changePermissions', 'changeUsers'] } },
|
|
default: 1,
|
|
},
|
|
{
|
|
displayName: 'Gruppen-Name',
|
|
name: 'groupName',
|
|
type: 'string',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['group'], operation: ['create', 'update'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Standard-Gruppe',
|
|
name: 'isDefault',
|
|
type: 'boolean',
|
|
displayOptions: { show: { resource: ['group'], operation: ['create', 'update'] } },
|
|
default: false,
|
|
},
|
|
{
|
|
displayName: 'Rollen-IDs',
|
|
name: 'roleIds',
|
|
type: 'string',
|
|
displayOptions: { show: { resource: ['group'], operation: ['changeRoles'] } },
|
|
default: '',
|
|
description: '1=Gruppenadmin, 2=App-Admin, 3=Ressourcen-Admin, 4=Zeitplan-Admin',
|
|
},
|
|
{
|
|
displayName: 'Ressourcen-IDs',
|
|
name: 'permissionResourceIds',
|
|
type: 'string',
|
|
displayOptions: { show: { resource: ['group'], operation: ['changePermissions'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Benutzer-IDs',
|
|
name: 'groupUserIds',
|
|
type: 'string',
|
|
displayOptions: { show: { resource: ['group'], operation: ['changeUsers'] } },
|
|
default: '',
|
|
},
|
|
|
|
// =====================================================
|
|
// ACCESSORY PARAMETERS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Zubehör-ID',
|
|
name: 'accessoryId',
|
|
type: 'number',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['accessory'], operation: ['get'] } },
|
|
default: 1,
|
|
},
|
|
|
|
// =====================================================
|
|
// ATTRIBUTE PARAMETERS
|
|
// =====================================================
|
|
{
|
|
displayName: 'Attribut-ID',
|
|
name: 'attributeId',
|
|
type: 'number',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['attribute'], operation: ['get', 'update', 'delete'] } },
|
|
default: 1,
|
|
},
|
|
{
|
|
displayName: 'Kategorie-ID',
|
|
name: 'categoryId',
|
|
type: 'options',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['attribute'], operation: ['getByCategory', 'create'] } },
|
|
options: [
|
|
{ name: 'Reservierung', value: 1 },
|
|
{ name: 'Benutzer', value: 2 },
|
|
{ name: 'Ressource', value: 4 },
|
|
{ name: 'Ressourcen-Typ', value: 5 },
|
|
],
|
|
default: 1,
|
|
},
|
|
{
|
|
displayName: 'Attribut-Label',
|
|
name: 'attributeLabel',
|
|
type: 'string',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['attribute'], operation: ['create', 'update'] } },
|
|
default: '',
|
|
},
|
|
{
|
|
displayName: 'Attribut-Typ',
|
|
name: 'attributeType',
|
|
type: 'options',
|
|
required: true,
|
|
displayOptions: { show: { resource: ['attribute'], operation: ['create', 'update'] } },
|
|
options: [
|
|
{ name: 'Einzeilig', value: 1 },
|
|
{ name: 'Mehrzeilig', value: 2 },
|
|
{ name: 'Auswahlliste', value: 3 },
|
|
{ name: 'Checkbox', value: 4 },
|
|
{ name: 'Datum/Zeit', value: 5 },
|
|
],
|
|
default: 1,
|
|
},
|
|
{
|
|
displayName: 'Attribut-Optionen',
|
|
name: 'attributeOptions',
|
|
type: 'collection',
|
|
placeholder: 'Option hinzufügen',
|
|
default: {},
|
|
displayOptions: { show: { resource: ['attribute'], operation: ['create', 'update'] } },
|
|
options: [
|
|
{ displayName: 'Erforderlich', name: 'required', type: 'boolean', default: false },
|
|
{ displayName: 'Nur Admin', name: 'adminOnly', type: 'boolean', default: false },
|
|
{ displayName: 'Privat', name: 'isPrivate', type: 'boolean', default: false },
|
|
{ displayName: 'Sortierung', name: 'sortOrder', type: 'number', default: 0 },
|
|
{ displayName: 'Regex-Validierung', name: 'regex', type: 'string', default: '' },
|
|
{ displayName: 'Mögliche Werte', name: 'possibleValues', type: 'string', default: '', description: 'Komma-getrennt' },
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
|
|
const items = this.getInputData();
|
|
const returnData: INodeExecutionData[] = [];
|
|
|
|
const credentials = await this.getCredentials('libreBookingApi');
|
|
const baseUrl = (credentials.url as string).replace(/\/$/, '');
|
|
const username = credentials.username as string;
|
|
const pw = credentials.password as string;
|
|
|
|
const session = await authenticate(this, baseUrl, username, pw);
|
|
|
|
try {
|
|
for (let i = 0; i < items.length; i++) {
|
|
try {
|
|
const resource = this.getNodeParameter('resource', i) as string;
|
|
const operation = this.getNodeParameter('operation', i) as string;
|
|
let responseData: any;
|
|
|
|
// RESERVATION
|
|
if (resource === 'reservation') {
|
|
if (operation === 'getAll') {
|
|
const filters = this.getNodeParameter('filters', i, {}) as any;
|
|
const qs: any = {};
|
|
if (filters.userId) qs.userId = filters.userId;
|
|
if (filters.resourceId) qs.resourceId = filters.resourceId;
|
|
if (filters.scheduleId) qs.scheduleId = filters.scheduleId;
|
|
if (filters.startDateTime) qs.startDateTime = filters.startDateTime;
|
|
if (filters.endDateTime) qs.endDateTime = filters.endDateTime;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Reservations/', undefined, qs);
|
|
} else if (operation === 'get') {
|
|
const referenceNumber = this.getNodeParameter('referenceNumber', i) as string;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Reservations/${referenceNumber}`);
|
|
} else if (operation === 'create') {
|
|
const resourceId = this.getNodeParameter('resourceId', i) as number;
|
|
const startDateTime = this.getNodeParameter('startDateTime', i) as string;
|
|
const endDateTime = this.getNodeParameter('endDateTime', i) as string;
|
|
const title = this.getNodeParameter('title', i, '') as string;
|
|
const additionalFields = this.getNodeParameter('additionalFields', i, {}) as any;
|
|
const body: any = { resourceId, startDateTime: new Date(startDateTime).toISOString(), endDateTime: new Date(endDateTime).toISOString() };
|
|
if (title) body.title = title;
|
|
if (additionalFields.description) body.description = additionalFields.description;
|
|
if (additionalFields.userId) body.userId = additionalFields.userId;
|
|
if (additionalFields.resources) body.resources = parseIdList(additionalFields.resources);
|
|
if (additionalFields.participants) body.participants = parseIdList(additionalFields.participants);
|
|
if (additionalFields.invitees) body.invitees = parseIdList(additionalFields.invitees);
|
|
if (additionalFields.allowParticipation !== undefined) body.allowParticipation = additionalFields.allowParticipation;
|
|
if (additionalFields.termsAccepted !== undefined) body.termsAccepted = additionalFields.termsAccepted;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Reservations/', body);
|
|
} else if (operation === 'update') {
|
|
const referenceNumber = this.getNodeParameter('referenceNumber', i) as string;
|
|
const startDateTime = this.getNodeParameter('startDateTime', i) as string;
|
|
const endDateTime = this.getNodeParameter('endDateTime', i) as string;
|
|
const title = this.getNodeParameter('title', i, '') as string;
|
|
const updateScope = this.getNodeParameter('updateScope', i, 'this') as string;
|
|
const additionalFields = this.getNodeParameter('additionalFields', i, {}) as any;
|
|
const body: any = { startDateTime: new Date(startDateTime).toISOString(), endDateTime: new Date(endDateTime).toISOString() };
|
|
if (title) body.title = title;
|
|
if (additionalFields.description) body.description = additionalFields.description;
|
|
if (additionalFields.resourceId) body.resourceId = additionalFields.resourceId;
|
|
if (additionalFields.userId) body.userId = additionalFields.userId;
|
|
if (additionalFields.resources) body.resources = parseIdList(additionalFields.resources);
|
|
if (additionalFields.participants) body.participants = parseIdList(additionalFields.participants);
|
|
if (additionalFields.invitees) body.invitees = parseIdList(additionalFields.invitees);
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}?updateScope=${updateScope}`, body);
|
|
} else if (operation === 'delete') {
|
|
const referenceNumber = this.getNodeParameter('referenceNumber', i) as string;
|
|
const updateScope = this.getNodeParameter('updateScope', i, 'this') as string;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Reservations/${referenceNumber}?updateScope=${updateScope}`);
|
|
} else if (operation === 'approve') {
|
|
const referenceNumber = this.getNodeParameter('referenceNumber', i) as string;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/Approval`);
|
|
} else if (operation === 'checkIn') {
|
|
const referenceNumber = this.getNodeParameter('referenceNumber', i) as string;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/CheckIn`);
|
|
} else if (operation === 'checkOut') {
|
|
const referenceNumber = this.getNodeParameter('referenceNumber', i) as string;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Reservations/${referenceNumber}/CheckOut`);
|
|
}
|
|
}
|
|
|
|
// RESOURCE
|
|
else if (resource === 'resource') {
|
|
if (operation === 'getAll') {
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/');
|
|
} else if (operation === 'get') {
|
|
const resourceIdParam = this.getNodeParameter('resourceIdParam', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Resources/${resourceIdParam}`);
|
|
} else if (operation === 'getAvailability') {
|
|
const resourceIdOptional = this.getNodeParameter('resourceIdOptional', i, '') as number | '';
|
|
const availabilityDateTime = this.getNodeParameter('availabilityDateTime', i, '') as string;
|
|
let endpoint = '/Resources/Availability';
|
|
if (resourceIdOptional) endpoint = `/Resources/${resourceIdOptional}/Availability`;
|
|
const qs: any = {};
|
|
if (availabilityDateTime) qs.dateTime = new Date(availabilityDateTime).toISOString();
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', endpoint, undefined, qs);
|
|
} else if (operation === 'getGroups') {
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Groups');
|
|
} else if (operation === 'getTypes') {
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Types');
|
|
} else if (operation === 'getStatuses') {
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Resources/Status');
|
|
} else if (operation === 'create') {
|
|
const resourceName = this.getNodeParameter('resourceName', i) as string;
|
|
const scheduleIdForResource = this.getNodeParameter('scheduleIdForResource', i) as number;
|
|
const resourceOptions = this.getNodeParameter('resourceOptions', i, {}) as any;
|
|
const body: any = { name: resourceName, scheduleId: scheduleIdForResource };
|
|
if (resourceOptions.location) body.location = resourceOptions.location;
|
|
if (resourceOptions.contact) body.contact = resourceOptions.contact;
|
|
if (resourceOptions.description) body.description = resourceOptions.description;
|
|
if (resourceOptions.notes) body.notes = resourceOptions.notes;
|
|
if (resourceOptions.maxParticipants) body.maxParticipants = resourceOptions.maxParticipants;
|
|
if (resourceOptions.requiresApproval !== undefined) body.requiresApproval = resourceOptions.requiresApproval;
|
|
if (resourceOptions.allowMultiday !== undefined) body.allowMultiday = resourceOptions.allowMultiday;
|
|
if (resourceOptions.requiresCheckIn !== undefined) body.requiresCheckIn = resourceOptions.requiresCheckIn;
|
|
if (resourceOptions.autoReleaseMinutes) body.autoReleaseMinutes = resourceOptions.autoReleaseMinutes;
|
|
if (resourceOptions.color) body.color = resourceOptions.color;
|
|
if (resourceOptions.statusId !== undefined) body.statusId = resourceOptions.statusId;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Resources/', body);
|
|
} else if (operation === 'update') {
|
|
const resourceIdParam = this.getNodeParameter('resourceIdParam', i) as number;
|
|
const resourceName = this.getNodeParameter('resourceName', i) as string;
|
|
const resourceOptions = this.getNodeParameter('resourceOptions', i, {}) as any;
|
|
const body: any = { name: resourceName };
|
|
if (resourceOptions.location) body.location = resourceOptions.location;
|
|
if (resourceOptions.contact) body.contact = resourceOptions.contact;
|
|
if (resourceOptions.description) body.description = resourceOptions.description;
|
|
if (resourceOptions.notes) body.notes = resourceOptions.notes;
|
|
if (resourceOptions.maxParticipants) body.maxParticipants = resourceOptions.maxParticipants;
|
|
if (resourceOptions.requiresApproval !== undefined) body.requiresApproval = resourceOptions.requiresApproval;
|
|
if (resourceOptions.allowMultiday !== undefined) body.allowMultiday = resourceOptions.allowMultiday;
|
|
if (resourceOptions.requiresCheckIn !== undefined) body.requiresCheckIn = resourceOptions.requiresCheckIn;
|
|
if (resourceOptions.autoReleaseMinutes) body.autoReleaseMinutes = resourceOptions.autoReleaseMinutes;
|
|
if (resourceOptions.color) body.color = resourceOptions.color;
|
|
if (resourceOptions.statusId !== undefined) body.statusId = resourceOptions.statusId;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Resources/${resourceIdParam}`, body);
|
|
} else if (operation === 'delete') {
|
|
const resourceIdParam = this.getNodeParameter('resourceIdParam', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Resources/${resourceIdParam}`);
|
|
}
|
|
}
|
|
|
|
// SCHEDULE
|
|
else if (resource === 'schedule') {
|
|
if (operation === 'getAll') {
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Schedules/');
|
|
} else if (operation === 'get') {
|
|
const scheduleId = this.getNodeParameter('scheduleId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Schedules/${scheduleId}`);
|
|
} else if (operation === 'getSlots') {
|
|
const scheduleId = this.getNodeParameter('scheduleId', i) as number;
|
|
const slotsFilters = this.getNodeParameter('slotsFilters', i, {}) as any;
|
|
const qs: any = {};
|
|
if (slotsFilters.resourceId) qs.resourceId = slotsFilters.resourceId;
|
|
if (slotsFilters.startDateTime) qs.startDateTime = new Date(slotsFilters.startDateTime).toISOString();
|
|
if (slotsFilters.endDateTime) qs.endDateTime = new Date(slotsFilters.endDateTime).toISOString();
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Schedules/${scheduleId}/Slots`, undefined, qs);
|
|
}
|
|
}
|
|
|
|
// USER
|
|
else if (resource === 'user') {
|
|
if (operation === 'getAll') {
|
|
const userFilters = this.getNodeParameter('userFilters', i, {}) as any;
|
|
const qs: any = {};
|
|
if (userFilters.username) qs.username = userFilters.username;
|
|
if (userFilters.email) qs.email = userFilters.email;
|
|
if (userFilters.firstName) qs.firstName = userFilters.firstName;
|
|
if (userFilters.lastName) qs.lastName = userFilters.lastName;
|
|
if (userFilters.organization) qs.organization = userFilters.organization;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Users/', undefined, qs);
|
|
} else if (operation === 'get') {
|
|
const userId = this.getNodeParameter('userId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Users/${userId}`);
|
|
} else if (operation === 'create') {
|
|
const emailAddress = this.getNodeParameter('emailAddress', i) as string;
|
|
const userName = this.getNodeParameter('userName', i) as string;
|
|
const pw = this.getNodeParameter('password', i) as string;
|
|
const firstName = this.getNodeParameter('firstName', i) as string;
|
|
const lastName = this.getNodeParameter('lastName', i) as string;
|
|
const userOptions = this.getNodeParameter('userOptions', i, {}) as any;
|
|
const body: any = { emailAddress, userName, password: pw, firstName, lastName };
|
|
if (userOptions.timezone) body.timezone = userOptions.timezone;
|
|
if (userOptions.language) body.language = userOptions.language;
|
|
if (userOptions.phone) body.phone = userOptions.phone;
|
|
if (userOptions.organization) body.organization = userOptions.organization;
|
|
if (userOptions.position) body.position = userOptions.position;
|
|
if (userOptions.groups) body.groups = parseIdList(userOptions.groups);
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Users/', body);
|
|
} else if (operation === 'update') {
|
|
const userId = this.getNodeParameter('userId', i) as number;
|
|
const firstName = this.getNodeParameter('firstName', i) as string;
|
|
const lastName = this.getNodeParameter('lastName', i) as string;
|
|
const userOptions = this.getNodeParameter('userOptions', i, {}) as any;
|
|
const body: any = { firstName, lastName };
|
|
if (userOptions.timezone) body.timezone = userOptions.timezone;
|
|
if (userOptions.language) body.language = userOptions.language;
|
|
if (userOptions.phone) body.phone = userOptions.phone;
|
|
if (userOptions.organization) body.organization = userOptions.organization;
|
|
if (userOptions.position) body.position = userOptions.position;
|
|
if (userOptions.groups) body.groups = parseIdList(userOptions.groups);
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Users/${userId}`, body);
|
|
} else if (operation === 'updatePassword') {
|
|
const userId = this.getNodeParameter('userId', i) as number;
|
|
const pw = this.getNodeParameter('password', i) as string;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Users/${userId}/Password`, { password: pw });
|
|
} else if (operation === 'delete') {
|
|
const userId = this.getNodeParameter('userId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Users/${userId}`);
|
|
}
|
|
}
|
|
|
|
// ACCOUNT
|
|
else if (resource === 'account') {
|
|
if (operation === 'get') {
|
|
const accountUserId = this.getNodeParameter('accountUserId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Accounts/${accountUserId}`);
|
|
} else if (operation === 'create') {
|
|
const accountData = this.getNodeParameter('accountData', i, {}) as any;
|
|
const body: any = {};
|
|
if (accountData.emailAddress) body.emailAddress = accountData.emailAddress;
|
|
if (accountData.userName) body.userName = accountData.userName;
|
|
if (accountData.password) body.password = accountData.password;
|
|
if (accountData.firstName) body.firstName = accountData.firstName;
|
|
if (accountData.lastName) body.lastName = accountData.lastName;
|
|
if (accountData.timezone) body.timezone = accountData.timezone;
|
|
if (accountData.language) body.language = accountData.language;
|
|
if (accountData.phone) body.phone = accountData.phone;
|
|
if (accountData.organization) body.organization = accountData.organization;
|
|
if (accountData.position) body.position = accountData.position;
|
|
if (accountData.acceptTermsOfService !== undefined) body.acceptTermsOfService = accountData.acceptTermsOfService;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Accounts/', body);
|
|
} else if (operation === 'update') {
|
|
const accountUserId = this.getNodeParameter('accountUserId', i) as number;
|
|
const accountData = this.getNodeParameter('accountData', i, {}) as any;
|
|
const body: any = {};
|
|
if (accountData.emailAddress) body.emailAddress = accountData.emailAddress;
|
|
if (accountData.userName) body.userName = accountData.userName;
|
|
if (accountData.firstName) body.firstName = accountData.firstName;
|
|
if (accountData.lastName) body.lastName = accountData.lastName;
|
|
if (accountData.timezone) body.timezone = accountData.timezone;
|
|
if (accountData.language) body.language = accountData.language;
|
|
if (accountData.phone) body.phone = accountData.phone;
|
|
if (accountData.organization) body.organization = accountData.organization;
|
|
if (accountData.position) body.position = accountData.position;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Accounts/${accountUserId}`, body);
|
|
} else if (operation === 'updatePassword') {
|
|
const accountUserId = this.getNodeParameter('accountUserId', i) as number;
|
|
const passwordChange = this.getNodeParameter('passwordChange', i, {}) as any;
|
|
const passwords = passwordChange.passwords || {};
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Accounts/${accountUserId}/Password`, {
|
|
currentPassword: passwords.currentPassword,
|
|
newPassword: passwords.newPassword,
|
|
});
|
|
}
|
|
}
|
|
|
|
// GROUP
|
|
else if (resource === 'group') {
|
|
if (operation === 'getAll') {
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Groups/');
|
|
} else if (operation === 'get') {
|
|
const groupId = this.getNodeParameter('groupId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Groups/${groupId}`);
|
|
} else if (operation === 'create') {
|
|
const groupName = this.getNodeParameter('groupName', i) as string;
|
|
const isDefault = this.getNodeParameter('isDefault', i, false) as boolean;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Groups/', { name: groupName, isDefault });
|
|
} else if (operation === 'update') {
|
|
const groupId = this.getNodeParameter('groupId', i) as number;
|
|
const groupName = this.getNodeParameter('groupName', i) as string;
|
|
const isDefault = this.getNodeParameter('isDefault', i, false) as boolean;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}`, { name: groupName, isDefault });
|
|
} else if (operation === 'delete') {
|
|
const groupId = this.getNodeParameter('groupId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Groups/${groupId}`);
|
|
} else if (operation === 'changeRoles') {
|
|
const groupId = this.getNodeParameter('groupId', i) as number;
|
|
const roleIds = this.getNodeParameter('roleIds', i, '') as string;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Roles`, { roleIds: parseIdList(roleIds) });
|
|
} else if (operation === 'changePermissions') {
|
|
const groupId = this.getNodeParameter('groupId', i) as number;
|
|
const permissionResourceIds = this.getNodeParameter('permissionResourceIds', i, '') as string;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Permissions`, { resourceIds: parseIdList(permissionResourceIds) });
|
|
} else if (operation === 'changeUsers') {
|
|
const groupId = this.getNodeParameter('groupId', i) as number;
|
|
const groupUserIds = this.getNodeParameter('groupUserIds', i, '') as string;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Groups/${groupId}/Users`, { userIds: parseIdList(groupUserIds) });
|
|
}
|
|
}
|
|
|
|
// ACCESSORY
|
|
else if (resource === 'accessory') {
|
|
if (operation === 'getAll') {
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', '/Accessories/');
|
|
} else if (operation === 'get') {
|
|
const accessoryId = this.getNodeParameter('accessoryId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Accessories/${accessoryId}`);
|
|
}
|
|
}
|
|
|
|
// ATTRIBUTE
|
|
else if (resource === 'attribute') {
|
|
if (operation === 'get') {
|
|
const attributeId = this.getNodeParameter('attributeId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Attributes/${attributeId}`);
|
|
} else if (operation === 'getByCategory') {
|
|
const categoryId = this.getNodeParameter('categoryId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'GET', `/Attributes/Category/${categoryId}`);
|
|
} else if (operation === 'create') {
|
|
const attributeLabel = this.getNodeParameter('attributeLabel', i) as string;
|
|
const attributeType = this.getNodeParameter('attributeType', i) as number;
|
|
const categoryId = this.getNodeParameter('categoryId', i) as number;
|
|
const attributeOptions = this.getNodeParameter('attributeOptions', i, {}) as any;
|
|
const body: any = { label: attributeLabel, type: attributeType, categoryId };
|
|
if (attributeOptions.required !== undefined) body.required = attributeOptions.required;
|
|
if (attributeOptions.adminOnly !== undefined) body.adminOnly = attributeOptions.adminOnly;
|
|
if (attributeOptions.isPrivate !== undefined) body.isPrivate = attributeOptions.isPrivate;
|
|
if (attributeOptions.sortOrder !== undefined) body.sortOrder = attributeOptions.sortOrder;
|
|
if (attributeOptions.regex) body.regex = attributeOptions.regex;
|
|
if (attributeOptions.possibleValues) body.possibleValues = attributeOptions.possibleValues.split(',').map((v: string) => v.trim());
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', '/Attributes/', body);
|
|
} else if (operation === 'update') {
|
|
const attributeId = this.getNodeParameter('attributeId', i) as number;
|
|
const attributeLabel = this.getNodeParameter('attributeLabel', i) as string;
|
|
const attributeType = this.getNodeParameter('attributeType', i) as number;
|
|
const attributeOptions = this.getNodeParameter('attributeOptions', i, {}) as any;
|
|
const body: any = { label: attributeLabel, type: attributeType };
|
|
if (attributeOptions.required !== undefined) body.required = attributeOptions.required;
|
|
if (attributeOptions.adminOnly !== undefined) body.adminOnly = attributeOptions.adminOnly;
|
|
if (attributeOptions.isPrivate !== undefined) body.isPrivate = attributeOptions.isPrivate;
|
|
if (attributeOptions.sortOrder !== undefined) body.sortOrder = attributeOptions.sortOrder;
|
|
if (attributeOptions.regex) body.regex = attributeOptions.regex;
|
|
if (attributeOptions.possibleValues) body.possibleValues = attributeOptions.possibleValues.split(',').map((v: string) => v.trim());
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'POST', `/Attributes/${attributeId}`, body);
|
|
} else if (operation === 'delete') {
|
|
const attributeId = this.getNodeParameter('attributeId', i) as number;
|
|
responseData = await makeApiRequest(this, baseUrl, session, 'DELETE', `/Attributes/${attributeId}`);
|
|
}
|
|
}
|
|
|
|
// Process response
|
|
if (responseData) {
|
|
if (Array.isArray(responseData)) {
|
|
returnData.push(...responseData.map(item => ({ json: item })));
|
|
} else if (responseData.reservations) {
|
|
returnData.push(...responseData.reservations.map((item: any) => ({ json: item })));
|
|
} else if (responseData.resources) {
|
|
returnData.push(...responseData.resources.map((item: any) => ({ json: item })));
|
|
} else if (responseData.schedules) {
|
|
returnData.push(...responseData.schedules.map((item: any) => ({ json: item })));
|
|
} else if (responseData.users) {
|
|
returnData.push(...responseData.users.map((item: any) => ({ json: item })));
|
|
} else if (responseData.groups) {
|
|
returnData.push(...responseData.groups.map((item: any) => ({ json: item })));
|
|
} else if (responseData.accessories) {
|
|
returnData.push(...responseData.accessories.map((item: any) => ({ json: item })));
|
|
} else if (responseData.attributes) {
|
|
returnData.push(...responseData.attributes.map((item: any) => ({ json: item })));
|
|
} else {
|
|
returnData.push({ json: responseData });
|
|
}
|
|
}
|
|
|
|
} catch (error: any) {
|
|
if (this.continueOnFail()) {
|
|
returnData.push({ json: { error: error.message } });
|
|
continue;
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
} finally {
|
|
await signOut(this, baseUrl, session);
|
|
}
|
|
|
|
return [returnData];
|
|
}
|
|
}
|