Files
supabase/apps/studio/components/interfaces/Auth/OAuthApps/OAuthEndpointsTable.tsx
Francesco Sansalvadore 82f798f75a chore(studio): show oauth server endpoints in oauth server settings (#41783)
Show OAuth server endpoints in oauth server settings page.

Preview: [OAuth Server
settings](https://studio-staging-git-chore-show-oauth-server-endpoints-supabase.vercel.app/dashboard/project/_/auth/oauth-server)

<img width="1138" height="496" alt="Screenshot 2026-01-09 at 12 00 31"
src="https://github.com/user-attachments/assets/eeca7726-0426-4abe-990d-271b702e4f7b"
/>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added an OAuth endpoints table showing Authorization, Token, JWKS, and
Discovery/OpenID URLs with copy-to-clipboard and a masked preview mode.
* Inline preview of the Authorization URL when an authorization path is
set.

* **Improvements**
* Reorganized OAuth server settings for clearer enable/disable flow,
conditional field visibility, and disable confirmation.
* Dynamic loading of the endpoints table, improved loading skeletons,
layout refinements, and form reset to reflect saved defaults.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-04-09 16:01:26 +02:00

91 lines
2.5 KiB
TypeScript

import { useParams } from 'common'
import { Card, CardContent, cn } from 'ui'
import {
PageSection,
PageSectionContent,
PageSectionDescription,
PageSectionMeta,
PageSectionSummary,
PageSectionTitle,
} from 'ui-patterns'
import { Input } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
import { useOpenIDConfigurationQuery } from '@/data/oauth-server-apps/oauth-openid-configuration-query'
interface OAuthEndpointsTableProps {
isLoading?: boolean
className?: string
}
export const OAuthEndpointsTable = ({
isLoading: isLoadingProp = false,
className,
}: OAuthEndpointsTableProps) => {
const { ref: projectRef } = useParams()
const { data: openidConfig, isLoading: isEndpointsLoading } = useOpenIDConfigurationQuery(
{ projectRef },
{ enabled: !isLoadingProp }
)
const isLoading = isLoadingProp || isEndpointsLoading
const endpoints = [
{
name: 'Authorization endpoint',
value: openidConfig?.authorization_endpoint,
},
{
name: 'Token endpoint',
value: openidConfig?.token_endpoint,
},
{
name: 'JWKS endpoint',
value: openidConfig?.jwks_uri,
},
{
name: 'OIDC discovery',
value: openidConfig?.issuer
? `${openidConfig.issuer}/.well-known/openid-configuration`
: undefined,
},
]
return (
<PageSection className={cn(className)}>
<PageSectionMeta>
<PageSectionSummary>
<PageSectionTitle>OAuth Endpoints</PageSectionTitle>
<PageSectionDescription>
Share these endpoints with third-party applications that need to integrate with your
OAuth 2.1 server.
</PageSectionDescription>
</PageSectionSummary>
</PageSectionMeta>
<PageSectionContent>
<Card>
<CardContent className="flex flex-col gap-4 pt-0 divide-y">
{isLoading ? (
<GenericSkeletonLoader className="mt-4" />
) : (
endpoints.map((endpoint) => (
<FormItemLayout
key={endpoint.name}
layout="horizontal"
isReactForm={false}
label={endpoint.name}
className="mt-4"
>
<Input readOnly copy value={endpoint.value ?? ''} />
</FormItemLayout>
))
)}
</CardContent>
</Card>
</PageSectionContent>
</PageSection>
)
}