Skip to content

Commit cd09a40

Browse files
jfosheecursoragent
andauthored
feat(ui): Special handling of offline_access scope in OAuth Consent screen (#7627)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent f487dbb commit cd09a40

File tree

4 files changed

+17
-4
lines changed

4 files changed

+17
-4
lines changed

.changeset/quiet-dolphins-swim.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/ui': minor
3+
---
4+
5+
Handle `offline_access` scope in OAuth consent screen by filtering it from the displayed scopes list (as it describes access duration rather than what can be accessed) and appending informational text about staying signed in when the scope is present.

packages/clerk-js/sandbox/app.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,8 @@ void (async () => {
389389
const searchParams = new URLSearchParams(window.location.search);
390390
const scopes = (searchParams.get('scopes')?.split(',') ?? []).map(scope => ({
391391
scope,
392-
description: `Grants access to your ${scope}`,
392+
description: scope === 'offline_access' ? null : `Grants access to your ${scope}`,
393+
requires_consent: true,
393394
}));
394395
Clerk.__internal_mountOAuthConsent(
395396
app,

packages/ui/bundlewatch.config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"files": [
3-
{ "path": "./dist/ui.browser.js", "maxSize": "34KB" },
4-
{ "path": "./dist/ui.legacy.browser.js", "maxSize": "72KB" },
3+
{ "path": "./dist/ui.browser.js", "maxSize": "36KB" },
4+
{ "path": "./dist/ui.legacy.browser.js", "maxSize": "74KB" },
55
{ "path": "./dist/framework*.js", "maxSize": "44KB" },
66
{ "path": "./dist/vendors*.js", "maxSize": "73KB" },
77
{ "path": "./dist/ui-common*.js", "maxSize": "130KB" },

packages/ui/src/components/OAuthConsent/OAuthConsent.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import type { ThemableCssProp } from '@/ui/styledSystem';
1616
import { common } from '@/ui/styledSystem';
1717
import { colors } from '@/ui/utils/colors';
1818

19+
const OFFLINE_ACCESS_SCOPE = 'offline_access';
20+
1921
export function OAuthConsentInternal() {
2022
const { scopes, oAuthApplicationName, oAuthApplicationLogoUrl, oAuthApplicationUrl, redirectUrl, onDeny, onAllow } =
2123
useOAuthConsentContext();
@@ -25,6 +27,10 @@ export function OAuthConsentInternal() {
2527

2628
const primaryEmailAddress = user?.emailAddresses.find(email => email.id === user.primaryEmailAddress?.id);
2729

30+
// Filter out offline_access from displayed scopes as it doesn't describe what can be accessed
31+
const displayedScopes = (scopes || []).filter(item => item.scope !== OFFLINE_ACCESS_SCOPE);
32+
const hasOfflineAccess = (scopes || []).some(item => item.scope === OFFLINE_ACCESS_SCOPE);
33+
2834
function getRootDomain(): string {
2935
try {
3036
const { hostname } = new URL(redirectUrl);
@@ -132,7 +138,7 @@ export function OAuthConsentInternal() {
132138
as='ul'
133139
sx={t => ({ margin: t.sizes.$none, padding: t.sizes.$none })}
134140
>
135-
{(scopes || []).map(item => (
141+
{displayedScopes.map(item => (
136142
<Box
137143
key={item.scope}
138144
sx={t => ({
@@ -240,6 +246,7 @@ export function OAuthConsentInternal() {
240246
</Tooltip.Trigger>
241247
<Tooltip.Content text={`View full URL`} />
242248
</Tooltip.Root>
249+
.{hasOfflineAccess && " You'll stay signed in until you sign out or revoke access."}
243250
</Text>
244251
</Grid>
245252
</Card.Content>

0 commit comments

Comments
 (0)