Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
useGoogleLogin as useGoogleLoginBase,
} from "@react-oauth/google";
import { useCallback, useMemo, useState } from "react";
import { buildOAuthStateForClient } from "@core/desktop/desktop-oauth-state.util";
import { buildSignInOAuthState } from "@core/auth/signin-oauth-state.util";
import { GOOGLE_SCOPES } from "@core/providers/google.scopes";
import { MICROSOFT_SCOPES } from "@core/providers/microsoft.scopes";
import { type ProviderKind } from "@core/types/sync/identity.contracts";
Expand Down Expand Up @@ -191,7 +191,7 @@ const useGoogleProviderAuthorizationStrategy: ProviderAuthorizationStrategy = ({
const { state, redirectUri } = useAuthorizationSession(
"google",
(_redirectUri, posthogDistinctId) =>
buildOAuthStateForClient(false, posthogDistinctId),
buildSignInOAuthState({ isDesktopClient: false, posthogDistinctId }),
);

const loginOptions = useMemo<
Expand Down Expand Up @@ -235,7 +235,7 @@ const useMicrosoftProviderAuthorizationStrategy =
getClientId: () => getMicrosoftSignInClientId(),
notConfiguredMessage: "Microsoft sign-in is not configured",
createState: (_redirectUri, posthogDistinctId) =>
buildOAuthStateForClient(false, posthogDistinctId),
buildSignInOAuthState({ isDesktopClient: false, posthogDistinctId }),
buildAuthorizationUrl: ({ clientId, redirectUri, state, prompt }) =>
buildMicrosoftAuthorizationUrl({
clientId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,13 @@ export const DatePickers: FC<Props> = ({
end: selectedEndDate,
});

if (shouldAdjustEnd) {
onScheduleChange({
kind: "allDay",
start: toAllDayDate(start),
end: toAllDayDate(compliment),
});
} else {
onScheduleChange({
kind: "allDay",
start: toAllDayDate(start),
end: currentAllDayBounds().end,
});
}
onScheduleChange({
kind: "allDay",
start: toAllDayDate(start),
end: shouldAdjustEnd
? toAllDayDate(compliment)
: currentAllDayBounds().end,
});
};

const onSelectEndDate = (end: Date) => {
Expand Down
18 changes: 7 additions & 11 deletions packages/core/src/auth/signin-oauth-state.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,25 +109,21 @@ export function parseSignInOAuthState(
};
}

/**
* Apple relays `state` back as its own base64 JSON blob rather than the
* version-prefixed payload above. base64UrlDecode reads both alphabets (it
* only rewrites `-`/`_` and re-pads), so one pass covers plain base64 too.
*/
function posthogDistinctIdFromAppleOAuthState(
state: string,
): string | undefined {
try {
const decoded = base64UrlDecode(state);
const parsed = JSON.parse(decoded) as { ph?: unknown };
const parsed = JSON.parse(base64UrlDecode(state)) as { ph?: unknown };
return typeof parsed.ph === "string" && parsed.ph.length > 0
? parsed.ph
: undefined;
} catch {
try {
const decoded = atob(state);
const parsed = JSON.parse(decoded) as { ph?: unknown };
return typeof parsed.ph === "string" && parsed.ph.length > 0
? parsed.ph
: undefined;
} catch {
return undefined;
}
return undefined;
}
}

Expand Down
17 changes: 8 additions & 9 deletions packages/core/src/desktop/desktop-oauth-state.util.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
buildDesktopConnectRelayUrl,
buildDesktopOAuthRelayUrl,
buildOAuthStateForClient,
DESKTOP_OAUTH_STATE_PREFIX,
hasDesktopOAuthStateMarker,
parseDesktopAuthDeepLink,
Expand All @@ -12,16 +11,16 @@ import {
import { describe, expect, it } from "bun:test";

describe("desktop oauth state", () => {
it("prefixes state when the client is desktop", () => {
const state = buildOAuthStateForClient(true);
expect(state.startsWith(DESKTOP_OAUTH_STATE_PREFIX)).toBe(true);
expect(hasDesktopOAuthStateMarker(state)).toBe(true);
// buildSignInOAuthState owns which states carry the marker, and its own
// test covers that; this is the marker reader on its own.
it("recognizes the desktop marker", () => {
expect(
hasDesktopOAuthStateMarker(`${DESKTOP_OAUTH_STATE_PREFIX}v1.payload`),
).toBe(true);
});

it("leaves browser state unprefixed", () => {
const state = buildOAuthStateForClient(false);
expect(state.startsWith(DESKTOP_OAUTH_STATE_PREFIX)).toBe(false);
expect(hasDesktopOAuthStateMarker(state)).toBe(false);
it("leaves browser state unmarked", () => {
expect(hasDesktopOAuthStateMarker("v1.payload")).toBe(false);
});
});

Expand Down
8 changes: 0 additions & 8 deletions packages/core/src/desktop/desktop-oauth-state.util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { buildSignInOAuthState } from "@core/auth/signin-oauth-state.util";
import {
type ProviderKind,
ProviderKindSchema,
Expand Down Expand Up @@ -30,13 +29,6 @@ const DESKTOP_EVENT_LINK_PREFIX = `${DESKTOP_DEEP_LINK_SCHEME}event/`;
const DESKTOP_DAY_LINK_PATTERN =
/^compass:\/\/day\/(?<date>\d{4}-\d{2}-\d{2})\/?$/;

export function buildOAuthStateForClient(
isDesktopClient: boolean,
posthogDistinctId?: string,
): string {
return buildSignInOAuthState({ isDesktopClient, posthogDistinctId });
}

export function hasDesktopOAuthStateMarker(state: string): boolean {
return state.startsWith(DESKTOP_OAUTH_STATE_PREFIX);
}
Expand Down
Loading