Skip to content
Draft
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
182 changes: 180 additions & 2 deletions packages/shared/src/oauth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,187 @@ describe("OAUTH_SCOPES guard", () => {
scopes: OAUTH_SCOPES,
}).toMatchInlineSnapshot(`
{
"scopeVersion": 5,
"scopeVersion": 6,
"scopes": [
"*",
"openid",
"profile",
"email",
"action:read",
"action:write",
"access_control:read",
"access_control:write",
"account:read",
"account:write",
"activity_log:read",
"activity_log:write",
"alert:read",
"alert:write",
"annotation:read",
"annotation:write",
"approvals:read",
"approvals:write",
"batch_export:read",
"batch_export:write",
"batch_import:read",
"batch_import:write",
"business_knowledge:read",
"business_knowledge:write",
"cohort:read",
"cohort:write",
"comment:read",
"comment:write",
"conversation:read",
"conversation:write",
"customer_analytics:read",
"customer_analytics:write",
"customer_journey:read",
"customer_journey:write",
"customer_profile_config:read",
"customer_profile_config:write",
"dashboard:read",
"dashboard:write",
"event_filter:read",
"event_filter:write",
"dashboard_template:read",
"dashboard_template:write",
"dataset:read",
"dataset:write",
"desktop_recording:read",
"desktop_recording:write",
"early_access_feature:read",
"early_access_feature:write",
"endpoint:read",
"endpoint:write",
"engineering_analytics:read",
"engineering_analytics:write",
"error_tracking:read",
"error_tracking:write",
"evaluation:read",
"evaluation:write",
"element:read",
"element:write",
"event_definition:read",
"event_definition:write",
"experiment:read",
"experiment:write",
"experiment_saved_metric:read",
"experiment_saved_metric:write",
"export:read",
"export:write",
"external_data_schema:read",
"external_data_schema:write",
"external_data_source:read",
"external_data_source:write",
"feature_flag:read",
"feature_flag:write",
"file_system:read",
"file_system:write",
"file_system_shortcut:read",
"file_system_shortcut:write",
"group:read",
"group:write",
"health_issue:read",
"health_issue:write",
"heatmap:read",
"heatmap:write",
"hog_flow:read",
"hog_flow:write",
"hog_function:read",
"hog_function:write",
"insight:read",
"insight:write",
"insight_variable:read",
"insight_variable:write",
"integration:read",
"integration:write",
"legal_document:read",
"legal_document:write",
"link:read",
"link:write",
"live_debugger:read",
"live_debugger:write",
"llm_analytics:read",
"llm_analytics:write",
"llm_prompt:read",
"llm_prompt:write",
"llm_provider_key:read",
"llm_provider_key:write",
"llm_skill:read",
"llm_skill:write",
"logs:read",
"logs:write",
"marketing_analytics:read",
"marketing_analytics:write",
"notebook:read",
"notebook:write",
"organization:read",
"organization:write",
"organization_integration:read",
"organization_integration:write",
"organization_member:read",
"organization_member:write",
"person:read",
"person:write",
"persisted_folder:read",
"persisted_folder:write",
"plugin:read",
"plugin:write",
"product_tour:read",
"product_tour:write",
"project:read",
"project:write",
"property_definition:read",
"property_definition:write",
"query:read",
"query:write",
"replay_scanner:read",
"replay_scanner:write",
"revenue_analytics:read",
"revenue_analytics:write",
"session_recording:read",
"session_recording:write",
"session_recording_playlist:read",
"session_recording_playlist:write",
"sharing_configuration:read",
"sharing_configuration:write",
"signal_scout:read",
"signal_scout:write",
"streamlit_app:read",
"streamlit_app:write",
"subscription:read",
"subscription:write",
"survey:read",
"survey:write",
"tagger:read",
"tagger:write",
"ticket:read",
"ticket:write",
"task:read",
"task:write",
"tracing:read",
"tracing:write",
"field_note:read",
"field_note:write",
"uploaded_media:read",
"uploaded_media:write",
"usage_metric:read",
"usage_metric:write",
"user:read",
"user:write",
"user_interview:read",
"user_interview:write",
"visual_review:read",
"visual_review:write",
"warehouse_objects:read",
"warehouse_objects:write",
"warehouse_table:read",
"warehouse_table:write",
"warehouse_view:read",
"warehouse_view:write",
"web_analytics:read",
"web_analytics:write",
"webhook:read",
"webhook:write",
],
}
`);
Comment on lines 9 to 194

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Large inline snapshot should move to an external file

The inline snapshot grew from 3 lines (just "*") to 185 lines. Per the team's style rule, extensive snapshots belong in external .snap files — keeping them inline makes diffs noisy and the test file hard to navigate. Vitest supports toMatchSnapshot() with an auto-managed __snapshots__/oauth.test.ts.snap file that would serve the same guard purpose here.

Rule Used: Avoid using inline snapshots for large test result... (source)

Learned From
PostHog/posthog#32651

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/shared/src/oauth.test.ts
Line: 9-194

Comment:
**Large inline snapshot should move to an external file**

The inline snapshot grew from 3 lines (just `"*"`) to 185 lines. Per the team's style rule, extensive snapshots belong in external `.snap` files — keeping them inline makes diffs noisy and the test file hard to navigate. Vitest supports `toMatchSnapshot()` with an auto-managed `__snapshots__/oauth.test.ts.snap` file that would serve the same guard purpose here.

**Rule Used:** Avoid using inline snapshots for large test result... ([source](https://app.greptile.com/posthog-org-19734/-/custom-context?memory=22c98109-c304-4258-9763-34ef5bd39e6d))

**Learned From**
[PostHog/posthog#32651](https://github.com/PostHog/posthog/pull/32651)

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Expand Down
190 changes: 187 additions & 3 deletions packages/shared/src/oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,194 @@ export const POSTHOG_US_CLIENT_ID = "HCWoE0aRFMYxIxFNTTwkOORn5LBjOt2GVDzwSw5W";
export const POSTHOG_EU_CLIENT_ID = "AIvijgMS0dxKEmr5z6odvRd8Pkh5vts3nPTzgzU9";
export const POSTHOG_DEV_CLIENT_ID = "DC5uRLVbGI02YQ82grxgnK6Qn12SXWpCqdPb60oZ";

// Bump OAUTH_SCOPE_VERSION below whenever OAUTH_SCOPES changes to force re-authentication
export const OAUTH_SCOPES = ["*"];
// Mirrors the scopes PostHog advertises as grantable: OAUTH_SCOPES_SUPPORTED in the API's
// services/mcp/src/lib/oauth-scopes.generated.ts, published as scopes_supported at
// /.well-known/oauth-authorization-server. Requesting this explicit set instead of "*" keeps
// the token least-privilege (no privileged/internal scopes; new scopes are not auto-granted).
// Keep in sync with that generated list; bump OAUTH_SCOPE_VERSION below whenever it changes.
export const OAUTH_SCOPES = [
"openid",
"profile",
"email",
"action:read",
"action:write",
"access_control:read",
"access_control:write",
"account:read",
"account:write",
"activity_log:read",
"activity_log:write",
"alert:read",
"alert:write",
"annotation:read",
"annotation:write",
"approvals:read",
"approvals:write",
"batch_export:read",
"batch_export:write",
"batch_import:read",
"batch_import:write",
"business_knowledge:read",
"business_knowledge:write",
"cohort:read",
"cohort:write",
"comment:read",
"comment:write",
"conversation:read",
"conversation:write",
"customer_analytics:read",
"customer_analytics:write",
"customer_journey:read",
"customer_journey:write",
"customer_profile_config:read",
"customer_profile_config:write",
"dashboard:read",
"dashboard:write",
"event_filter:read",
"event_filter:write",
"dashboard_template:read",
"dashboard_template:write",
"dataset:read",
"dataset:write",
"desktop_recording:read",
"desktop_recording:write",
"early_access_feature:read",
"early_access_feature:write",
"endpoint:read",
"endpoint:write",
"engineering_analytics:read",
"engineering_analytics:write",
"error_tracking:read",
"error_tracking:write",
"evaluation:read",
"evaluation:write",
"element:read",
"element:write",
"event_definition:read",
"event_definition:write",
"experiment:read",
"experiment:write",
"experiment_saved_metric:read",
"experiment_saved_metric:write",
"export:read",
"export:write",
"external_data_schema:read",
"external_data_schema:write",
"external_data_source:read",
"external_data_source:write",
"feature_flag:read",
"feature_flag:write",
"file_system:read",
"file_system:write",
"file_system_shortcut:read",
"file_system_shortcut:write",
"group:read",
"group:write",
"health_issue:read",
"health_issue:write",
"heatmap:read",
"heatmap:write",
"hog_flow:read",
"hog_flow:write",
"hog_function:read",
"hog_function:write",
"insight:read",
"insight:write",
"insight_variable:read",
"insight_variable:write",
"integration:read",
"integration:write",
"legal_document:read",
"legal_document:write",
"link:read",
"link:write",
"live_debugger:read",
"live_debugger:write",
"llm_analytics:read",
"llm_analytics:write",
"llm_prompt:read",
"llm_prompt:write",
"llm_provider_key:read",
"llm_provider_key:write",
"llm_skill:read",
"llm_skill:write",
"logs:read",
"logs:write",
"marketing_analytics:read",
"marketing_analytics:write",
"notebook:read",
"notebook:write",
"organization:read",
"organization:write",
"organization_integration:read",
"organization_integration:write",
"organization_member:read",
"organization_member:write",
"person:read",
"person:write",
"persisted_folder:read",
"persisted_folder:write",
"plugin:read",
"plugin:write",
"product_tour:read",
"product_tour:write",
"project:read",
"project:write",
"property_definition:read",
"property_definition:write",
"query:read",
"query:write",
"replay_scanner:read",
"replay_scanner:write",
"revenue_analytics:read",
"revenue_analytics:write",
"session_recording:read",
"session_recording:write",
"session_recording_playlist:read",
"session_recording_playlist:write",
"sharing_configuration:read",
"sharing_configuration:write",
"signal_scout:read",
"signal_scout:write",
"streamlit_app:read",
"streamlit_app:write",
"subscription:read",
"subscription:write",
"survey:read",
"survey:write",
"tagger:read",
"tagger:write",
"ticket:read",
"ticket:write",
"task:read",
"task:write",
"tracing:read",
"tracing:write",
"field_note:read",
"field_note:write",
"uploaded_media:read",
"uploaded_media:write",
"usage_metric:read",
"usage_metric:write",
"user:read",
"user:write",
"user_interview:read",
"user_interview:write",
"visual_review:read",
"visual_review:write",
"warehouse_objects:read",
"warehouse_objects:write",
"warehouse_table:read",
"warehouse_table:write",
"warehouse_view:read",
"warehouse_view:write",
"web_analytics:read",
"web_analytics:write",
"webhook:read",
"webhook:write",
];

export const OAUTH_SCOPE_VERSION = 5;
export const OAUTH_SCOPE_VERSION = 6;

// Token refresh settings
export const TOKEN_REFRESH_BUFFER_MS = 30 * 60 * 1000; // 30 minutes before expiry
Expand Down
Loading