@@ -7,11 +7,6 @@ import { toast } from 'sonner'
77import * as z from 'zod'
88
99import { useParams } from 'common'
10- import {
11- ScaffoldSection ,
12- ScaffoldSectionContent ,
13- ScaffoldSectionTitle ,
14- } from 'components/layouts/Scaffold'
1510import { InlineLink } from 'components/ui/InlineLink'
1611import NoPermission from 'components/ui/NoPermission'
1712import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
@@ -181,44 +176,126 @@ export const OAuthServerSettingsForm = () => {
181176 }
182177
183178 if ( isPermissionsLoaded && ! canReadConfig ) {
184- return (
185- < ScaffoldSection isFullWidth >
186- < ScaffoldSectionTitle className = "mb-4" > OAuth Server</ ScaffoldSectionTitle >
187- < div className = "mt-8" >
188- < NoPermission resourceText = "view OAuth server settings" />
189- </ div >
190- </ ScaffoldSection >
191- )
179+ return < NoPermission resourceText = "view OAuth server settings" />
192180 }
193181
194182 if ( isAuthConfigLoading || isLoadingPermissions ) {
195- return (
196- < div className = "pt-12" >
197- < GenericSkeletonLoader />
198- </ div >
199- )
183+ return < GenericSkeletonLoader />
200184 }
201185
202186 return (
203187 < >
204- < ScaffoldSection isFullWidth >
205- < ScaffoldSectionContent >
206- < Form_Shadcn_ { ...form } >
207- < form onSubmit = { form . handleSubmit ( onSubmit ) } className = "pb-10" >
208- < Card >
188+ < Form_Shadcn_ { ...form } >
189+ < form onSubmit = { form . handleSubmit ( onSubmit ) } className = "pb-10" >
190+ < Card >
191+ < CardContent className = "flex flex-col py-6 gap-y-4" >
192+ < FormField_Shadcn_
193+ control = { form . control }
194+ name = "OAUTH_SERVER_ENABLED"
195+ render = { ( { field } ) => (
196+ < FormItemLayout
197+ layout = "flex-row-reverse"
198+ label = "Enable the Supabase OAuth Server"
199+ description = {
200+ < >
201+ Enable OAuth server functionality for your project to create and manage
202+ OAuth applications.{ ' ' }
203+ < InlineLink href = { `${ DOCS_URL } /guides/auth/oauth-server` } >
204+ Learn more
205+ </ InlineLink >
206+ </ >
207+ }
208+ >
209+ < FormControl_Shadcn_ >
210+ < Switch
211+ checked = { field . value }
212+ onCheckedChange = { handleOAuthServerToggle }
213+ disabled = { ! canUpdateConfig }
214+ />
215+ </ FormControl_Shadcn_ >
216+ </ FormItemLayout >
217+ ) }
218+ />
219+ </ CardContent >
220+ { /* Site URL and Authorization Path - Only show when OAuth Server is enabled */ }
221+ { form . watch ( 'OAUTH_SERVER_ENABLED' ) && (
222+ < >
209223 < CardContent className = "flex flex-col py-6 gap-y-4" >
224+ < FormItemLayout
225+ label = "Site URL"
226+ description = {
227+ < >
228+ The base URL of your application, configured in{ ' ' }
229+ < Link
230+ href = { `/project/${ projectRef } /auth/url-configuration` }
231+ rel = "noreferrer"
232+ className = "text-foreground-light underline hover:text-foreground transition"
233+ >
234+ Auth URL Configuration
235+ </ Link > { ' ' }
236+ settings.
237+ </ >
238+ }
239+ >
240+ < Input_Shadcn_
241+ value = { authConfig ?. SITE_URL }
242+ disabled
243+ placeholder = "https://example.com"
244+ />
245+ </ FormItemLayout >
246+
247+ < FormField_Shadcn_
248+ control = { form . control }
249+ name = "OAUTH_SERVER_AUTHORIZATION_PATH"
250+ render = { ( { field } ) => (
251+ < FormItemLayout
252+ label = "Authorization Path"
253+ description = "Path where you'll implement the OAuth authorization UI (consent screens)."
254+ >
255+ < FormControl_Shadcn_ >
256+ < Input_Shadcn_ { ...field } placeholder = "/auth/authorize" />
257+ </ FormControl_Shadcn_ >
258+ </ FormItemLayout >
259+ ) }
260+ />
261+ { ( ( ) => {
262+ const authorizationUrl = `${ authConfig ?. SITE_URL } ${ form . watch ( 'OAUTH_SERVER_AUTHORIZATION_PATH' ) || '/oauth/consent' } `
263+ return (
264+ < Admonition
265+ type = "tip"
266+ title = "Make sure this path is implemented in your application."
267+ description = {
268+ < >
269+ Preview Authorization URL:{ ' ' }
270+ < a
271+ href = { authorizationUrl }
272+ target = "_blank"
273+ rel = "noreferrer"
274+ className = "text-foreground-light underline hover:text-foreground transition"
275+ >
276+ { authorizationUrl }
277+ </ a >
278+ </ >
279+ }
280+ />
281+ )
282+ } ) ( ) }
283+ </ CardContent >
284+ < CardContent className = "py-6" >
210285 < FormField_Shadcn_
211286 control = { form . control }
212- name = "OAUTH_SERVER_ENABLED "
287+ name = "OAUTH_SERVER_ALLOW_DYNAMIC_REGISTRATION "
213288 render = { ( { field } ) => (
214289 < FormItemLayout
215290 layout = "flex-row-reverse"
216- label = "Enable the Supabase OAuth Server "
291+ label = "Allow Dynamic OAuth Apps "
217292 description = {
218293 < >
219- Enable OAuth server functionality for your project to create and manage
220- OAuth applications.{ ' ' }
221- < InlineLink href = { `${ DOCS_URL } /guides/auth/oauth-server` } >
294+ Enable dynamic OAuth app registration. Apps can be registered
295+ programmatically via APIs.{ ' ' }
296+ < InlineLink
297+ href = { `${ DOCS_URL } /guides/auth/oauth-server/mcp-authentication#oauth-client-setup` }
298+ >
222299 Learn more
223300 </ InlineLink >
224301 </ >
@@ -227,130 +304,33 @@ export const OAuthServerSettingsForm = () => {
227304 < FormControl_Shadcn_ >
228305 < Switch
229306 checked = { field . value }
230- onCheckedChange = { handleOAuthServerToggle }
307+ onCheckedChange = { handleDynamicAppsToggle }
231308 disabled = { ! canUpdateConfig }
232309 />
233310 </ FormControl_Shadcn_ >
234311 </ FormItemLayout >
235312 ) }
236313 />
237314 </ CardContent >
238- { /* Site URL and Authorization Path - Only show when OAuth Server is enabled */ }
239- { form . watch ( 'OAUTH_SERVER_ENABLED' ) && (
240- < >
241- < CardContent className = "flex flex-col py-6 gap-y-4" >
242- < FormItemLayout
243- label = "Site URL"
244- description = {
245- < >
246- The base URL of your application, configured in{ ' ' }
247- < Link
248- href = { `/project/${ projectRef } /auth/url-configuration` }
249- rel = "noreferrer"
250- className = "text-foreground-light underline hover:text-foreground transition"
251- >
252- Auth URL Configuration
253- </ Link > { ' ' }
254- settings.
255- </ >
256- }
257- >
258- < Input_Shadcn_
259- value = { authConfig ?. SITE_URL }
260- disabled
261- placeholder = "https://example.com"
262- />
263- </ FormItemLayout >
264-
265- < FormField_Shadcn_
266- control = { form . control }
267- name = "OAUTH_SERVER_AUTHORIZATION_PATH"
268- render = { ( { field } ) => (
269- < FormItemLayout
270- label = "Authorization Path"
271- description = "Path where you'll implement the OAuth authorization UI (consent screens)."
272- >
273- < FormControl_Shadcn_ >
274- < Input_Shadcn_ { ...field } placeholder = "/auth/authorize" />
275- </ FormControl_Shadcn_ >
276- </ FormItemLayout >
277- ) }
278- />
279- { ( ( ) => {
280- const authorizationUrl = `${ authConfig ?. SITE_URL } ${ form . watch ( 'OAUTH_SERVER_AUTHORIZATION_PATH' ) || '/oauth/consent' } `
281- return (
282- < Admonition
283- type = "tip"
284- title = "Make sure this path is implemented in your application."
285- description = {
286- < >
287- Preview Authorization URL:{ ' ' }
288- < a
289- href = { authorizationUrl }
290- target = "_blank"
291- rel = "noreferrer"
292- className = "text-foreground-light underline hover:text-foreground transition"
293- >
294- { authorizationUrl }
295- </ a >
296- </ >
297- }
298- />
299- )
300- } ) ( ) }
301- </ CardContent >
302- < CardContent className = "py-6" >
303- < FormField_Shadcn_
304- control = { form . control }
305- name = "OAUTH_SERVER_ALLOW_DYNAMIC_REGISTRATION"
306- render = { ( { field } ) => (
307- < FormItemLayout
308- layout = "flex-row-reverse"
309- label = "Allow Dynamic OAuth Apps"
310- description = {
311- < >
312- Enable dynamic OAuth app registration. Apps can be registered
313- programmatically via APIs.{ ' ' }
314- < InlineLink
315- href = { `${ DOCS_URL } /guides/auth/oauth-server/mcp-authentication#oauth-client-setup` }
316- >
317- Learn more
318- </ InlineLink >
319- </ >
320- }
321- >
322- < FormControl_Shadcn_ >
323- < Switch
324- checked = { field . value }
325- onCheckedChange = { handleDynamicAppsToggle }
326- disabled = { ! canUpdateConfig }
327- />
328- </ FormControl_Shadcn_ >
329- </ FormItemLayout >
330- ) }
331- />
332- </ CardContent >
333- </ >
334- ) }
315+ </ >
316+ ) }
335317
336- < CardFooter className = "justify-end space-x-2" >
337- < Button type = "default" onClick = { ( ) => form . reset ( ) } disabled = { isPending } >
338- Cancel
339- </ Button >
340- < Button
341- type = "primary"
342- htmlType = "submit"
343- disabled = { ! canUpdateConfig || ! form . formState . isDirty }
344- loading = { isPending }
345- >
346- Save changes
347- </ Button >
348- </ CardFooter >
349- </ Card >
350- </ form >
351- </ Form_Shadcn_ >
352- </ ScaffoldSectionContent >
353- </ ScaffoldSection >
318+ < CardFooter className = "justify-end space-x-2" >
319+ < Button type = "default" onClick = { ( ) => form . reset ( ) } disabled = { isPending } >
320+ Cancel
321+ </ Button >
322+ < Button
323+ type = "primary"
324+ htmlType = "submit"
325+ disabled = { ! canUpdateConfig || ! form . formState . isDirty }
326+ loading = { isPending }
327+ >
328+ Save changes
329+ </ Button >
330+ </ CardFooter >
331+ </ Card >
332+ </ form >
333+ </ Form_Shadcn_ >
354334
355335 { /* Dynamic Apps Confirmation Modal */ }
356336 < ConfirmationModal
0 commit comments