Use user profile timezone from DB as fallback for CalDAV all-day events (#8755)
* adds timezone pull from user profile in DB * minor fixes * fixes promise return type * comments and minor fixes * minor improvement * fix return type * changes for help in debuggingpull/8810/head^2
parent
2e686d03fa
commit
8ffb5529e6
|
@ -276,6 +276,38 @@ export default abstract class BaseCalendarService implements Calendar {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getUserTimezoneFromDB() retrieves the timezone of a user from the database.
|
||||||
|
*
|
||||||
|
* @param {number} id - The user's unique identifier.
|
||||||
|
* @returns {Promise<string | undefined>} - A Promise that resolves to the user's timezone or "Europe/London" as a default value if the timezone is not found.
|
||||||
|
*/
|
||||||
|
getUserTimezoneFromDB = async (id: number): Promise<string | undefined> => {
|
||||||
|
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
timeZone: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return user?.timeZone;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getUserId() extracts the user ID from the first calendar in an array of IntegrationCalendars.
|
||||||
|
*
|
||||||
|
* @param {IntegrationCalendar[]} selectedCalendars - An array of IntegrationCalendars.
|
||||||
|
* @returns {number | null} - The user ID associated with the first calendar in the array, or null if the array is empty or the user ID is not found.
|
||||||
|
*/
|
||||||
|
getUserId = (selectedCalendars: IntegrationCalendar[]): number | null => {
|
||||||
|
if (selectedCalendars.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return selectedCalendars[0].userId || null;
|
||||||
|
};
|
||||||
|
|
||||||
isValidFormat = (url: string): boolean => {
|
isValidFormat = (url: string): boolean => {
|
||||||
const allowedExtensions = ["eml", "ics"];
|
const allowedExtensions = ["eml", "ics"];
|
||||||
const urlExtension = getFileExtension(url);
|
const urlExtension = getFileExtension(url);
|
||||||
|
@ -299,6 +331,10 @@ export default abstract class BaseCalendarService implements Calendar {
|
||||||
dateTo,
|
dateTo,
|
||||||
headers: this.headers,
|
headers: this.headers,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const userId = this.getUserId(selectedCalendars);
|
||||||
|
// we use the userId from selectedCalendars to fetch the user's timeZone from the database primarily for all-day events without any timezone information
|
||||||
|
const userTimeZone = userId ? await this.getUserTimezoneFromDB(userId) : "Europe/London";
|
||||||
const events: { start: string; end: string }[] = [];
|
const events: { start: string; end: string }[] = [];
|
||||||
objects.forEach((object) => {
|
objects.forEach((object) => {
|
||||||
if (object.data == null || JSON.stringify(object.data) == "{}") return;
|
if (object.data == null || JSON.stringify(object.data) == "{}") return;
|
||||||
|
@ -322,26 +358,31 @@ export default abstract class BaseCalendarService implements Calendar {
|
||||||
const isUTC = timezone === "Z";
|
const isUTC = timezone === "Z";
|
||||||
const tzid: string | undefined = vevent?.getFirstPropertyValue("tzid") || isUTC ? "UTC" : timezone;
|
const tzid: string | undefined = vevent?.getFirstPropertyValue("tzid") || isUTC ? "UTC" : timezone;
|
||||||
// In case of icalendar, when only tzid is available without vtimezone, we need to add vtimezone explicitly to take care of timezone diff
|
// In case of icalendar, when only tzid is available without vtimezone, we need to add vtimezone explicitly to take care of timezone diff
|
||||||
if (!vcalendar.getFirstSubcomponent("vtimezone") && tzid) {
|
if (!vcalendar.getFirstSubcomponent("vtimezone")) {
|
||||||
try {
|
const timezoneToUse = tzid || userTimeZone;
|
||||||
const timezoneComp = new ICAL.Component("vtimezone");
|
if (timezoneToUse) {
|
||||||
timezoneComp.addPropertyWithValue("tzid", tzid);
|
try {
|
||||||
const standard = new ICAL.Component("standard");
|
const timezoneComp = new ICAL.Component("vtimezone");
|
||||||
|
timezoneComp.addPropertyWithValue("tzid", timezoneToUse);
|
||||||
|
const standard = new ICAL.Component("standard");
|
||||||
|
|
||||||
// get timezone offset
|
// get timezone offset
|
||||||
const tzoffsetfrom = dayjs(event.startDate.toJSDate()).tz(tzid).format("Z");
|
const tzoffsetfrom = dayjs(event.startDate.toJSDate()).tz(timezoneToUse).format("Z");
|
||||||
const tzoffsetto = dayjs(event.endDate.toJSDate()).tz(tzid).format("Z");
|
const tzoffsetto = dayjs(event.endDate.toJSDate()).tz(timezoneToUse).format("Z");
|
||||||
|
|
||||||
// set timezone offset
|
// set timezone offset
|
||||||
standard.addPropertyWithValue("tzoffsetfrom", tzoffsetfrom);
|
standard.addPropertyWithValue("tzoffsetfrom", tzoffsetfrom);
|
||||||
standard.addPropertyWithValue("tzoffsetto", tzoffsetto);
|
standard.addPropertyWithValue("tzoffsetto", tzoffsetto);
|
||||||
// provide a standard dtstart
|
// provide a standard dtstart
|
||||||
standard.addPropertyWithValue("dtstart", "1601-01-01T00:00:00");
|
standard.addPropertyWithValue("dtstart", "1601-01-01T00:00:00");
|
||||||
timezoneComp.addSubcomponent(standard);
|
timezoneComp.addSubcomponent(standard);
|
||||||
vcalendar.addSubcomponent(timezoneComp);
|
vcalendar.addSubcomponent(timezoneComp);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Adds try-catch to ensure the code proceeds when Apple Calendar provides non-standard TZIDs
|
// Adds try-catch to ensure the code proceeds when Apple Calendar provides non-standard TZIDs
|
||||||
console.log("error in adding vtimezone", e);
|
console.log("error in adding vtimezone", e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("No timezone found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const vtimezone = vcalendar.getFirstSubcomponent("vtimezone");
|
const vtimezone = vcalendar.getFirstSubcomponent("vtimezone");
|
||||||
|
|
Loading…
Reference in New Issue