diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8abca405..ca2833fe 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,5 +7,8 @@ version: 2 updates: - package-ecosystem: "npm" # See documentation for possible values directory: "/" # Location of package manifests + target-branch: "dependencies" + commit-message: + prefix: "⬆️" schedule: interval: "daily" diff --git a/packages/backend/src/__tests__/errors.test.ts b/packages/backend/src/__tests__/gcal.util.test.ts similarity index 67% rename from packages/backend/src/__tests__/errors.test.ts rename to packages/backend/src/__tests__/gcal.util.test.ts index 5a60c273..b09bd249 100644 --- a/packages/backend/src/__tests__/errors.test.ts +++ b/packages/backend/src/__tests__/gcal.util.test.ts @@ -2,6 +2,7 @@ import { invalidSyncTokenError } from "./__mocks__/error.invalidSyncToken"; import { invalidValueError } from "./__mocks__/error.google.invalidValue"; import { invalidGrant400Error } from "./__mocks__/error.google.invalidGrant"; import { + getEmailFromUrl, isFullSyncRequired, isGoogleTokenExpired, isInvalidValue, @@ -14,8 +15,15 @@ describe("Google Error Parsing", () => { it("recognizes invalid (sync)value error", () => { expect(isInvalidValue(invalidValueError)).toBe(true); }); - it("recognizes expired refresh token", () => { expect(isGoogleTokenExpired(invalidGrant400Error)).toBe(true); }); }); + +describe("Gaxios response parsing", () => { + it("returns email with @", () => { + const url = + "https://www.googleapis.com/calendar/v3/calendars/foo%40bar.com/events?syncToken=!!!!!!!!!!!!!!!jqgYQwNWZ_QyyHyycChpiZHJvaGl1aHyyyyyyymxvZmMwaXZodjN2ZxoMCO7Xj6sGEICGncADwD4B"; + expect(getEmailFromUrl(url)).toBe("foo@bar.com"); + }); +}); diff --git a/packages/backend/src/common/errors/handlers/error.express.handler.ts b/packages/backend/src/common/errors/handlers/error.express.handler.ts index 7719e31d..5fc9df23 100644 --- a/packages/backend/src/common/errors/handlers/error.express.handler.ts +++ b/packages/backend/src/common/errors/handlers/error.express.handler.ts @@ -11,10 +11,12 @@ import { isFullSyncRequired, isGoogleError, isInvalidValue, + getEmailFromUrl, } from "@backend/common/services/gcal/gcal.utils"; +import compassAuthService from "@backend/auth/services/compass.auth.service"; import { getSyncByToken } from "@backend/sync/util/sync.queries"; import userService from "@backend/user/services/user.service"; -import compassAuthService from "@backend/auth/services/compass.auth.service"; +import { findCompassUserBy } from "@backend/user/queries/user.queries"; import { errorHandler } from "./error.handler"; @@ -46,6 +48,16 @@ const parseUserId = async (res: SessionResponse, e: Error) => { if (sync) { return sync.user; } + + if (e.config.url) { + const email = getEmailFromUrl(e.config.url); + if (email) { + const user = await findCompassUserBy("email", email); + if (user) { + return user._id.toString(); + } + } + } } } @@ -66,7 +78,7 @@ export const handleExpressError = async ( const userId = await parseUserId(res, e); if (!userId) { logger.error( - "Express error occured, but couldnt handle due to missing userId" + "Express error occured, but couldn't handle due to missing userId" ); res.status(Status.UNSURE).send(UserError.MissingUserIdField); return; diff --git a/packages/backend/src/common/services/gcal/gcal.utils.ts b/packages/backend/src/common/services/gcal/gcal.utils.ts index 8baf6ac9..6024289e 100644 --- a/packages/backend/src/common/services/gcal/gcal.utils.ts +++ b/packages/backend/src/common/services/gcal/gcal.utils.ts @@ -21,6 +21,16 @@ export const cancelledEventsIds = (events: gSchema$Event[]) => { return cancelledIds; }; +export const getEmailFromUrl = (url: string) => { + const emailMatch = url.match(/\/calendars\/([^/]+)\/events/); + + if (emailMatch && emailMatch[1]) { + return emailMatch[1].replace("%40", "@"); + } + + return null; +}; + export const getPrimaryGcalId = (calendarList: Schema_CalendarList) => { const primaryGCal = calendarList.google.items[0]; const gCalendarId = primaryGCal!.id as string;