diff --git a/.changeset/oauth-device-verification-docs.md b/.changeset/oauth-device-verification-docs.md new file mode 100644 index 00000000000..37316627ebf --- /dev/null +++ b/.changeset/oauth-device-verification-docs.md @@ -0,0 +1,5 @@ +--- +'@clerk/shared': patch +--- + +Document the public fields, actions, and parameter types for OAuth device verification flows. diff --git a/.typedoc/__tests__/relative-link-replacements.test.ts b/.typedoc/__tests__/relative-link-replacements.test.ts index cf98e65efb9..18fd59fcab3 100644 --- a/.typedoc/__tests__/relative-link-replacements.test.ts +++ b/.typedoc/__tests__/relative-link-replacements.test.ts @@ -50,6 +50,31 @@ describe('applyRelativeLinkReplacements', () => { '[x](billing-proration-credit-detail.mdx)', '[x](/docs/reference/types/billing-proration-credit-detail)', ], + [ + 'OAuth device verification info routes to its future standalone page', + '[x](o-auth-device-verification-info.mdx)', + '[x](/docs/reference/types/oauth-device-verification-info)', + ], + [ + 'OAuth device verification result routes to its future standalone page', + '[x](o-auth-device-verification-result.mdx)', + '[x](/docs/reference/types/oauth-device-verification-result)', + ], + [ + 'lookup OAuth device verification params route to their future standalone page', + '[x](lookup-o-auth-device-verification-params.mdx)', + '[x](/docs/reference/types/lookup-oauth-device-verification-params)', + ], + [ + 'submit OAuth device verification params route to their future standalone page', + '[x](submit-o-auth-device-verification-params.mdx)', + '[x](/docs/reference/types/submit-oauth-device-verification-params)', + ], + [ + 'useOAuthDeviceVerification return routes to the future hook returns section', + '[x](use-o-auth-device-verification-return.mdx)', + '[x](/docs/reference/hooks/use-oauth-device-verification#returns)', + ], [ 'resolves relative path prefixes', '[x](../../types/billing-credits.mdx)', diff --git a/.typedoc/custom-plugin.mjs b/.typedoc/custom-plugin.mjs index 6b0b71db41f..4b39b6e4888 100644 --- a/.typedoc/custom-plugin.mjs +++ b/.typedoc/custom-plugin.mjs @@ -40,6 +40,7 @@ const FILES_WITHOUT_HEADINGS = [ 'use-organization-creation-defaults-params.mdx', 'use-o-auth-consent-params.mdx', 'use-o-auth-consent-return.mdx', + 'use-o-auth-device-verification-return.mdx', 'create-organization-domain-params.mdx', ]; @@ -75,6 +76,11 @@ const LINK_REPLACEMENTS = [ ['o-auth-application-namespace', '/docs/reference/types/oauth-application'], ['o-auth-consent-info', '/docs/reference/types/oauth-consent-info'], ['o-auth-consent-scope', '/docs/reference/types/oauth-consent-scope'], + ['lookup-o-auth-device-verification-params', '/docs/reference/types/lookup-oauth-device-verification-params'], + ['o-auth-device-verification-info', '/docs/reference/types/oauth-device-verification-info'], + ['o-auth-device-verification-result', '/docs/reference/types/oauth-device-verification-result'], + ['submit-o-auth-device-verification-params', '/docs/reference/types/submit-oauth-device-verification-params'], + ['use-o-auth-device-verification-return', '/docs/reference/hooks/use-oauth-device-verification#returns'], ['o-auth-strategy', '/docs/reference/types/sso#o-auth-strategy'], ['o-auth-provider', '/docs/reference/types/sso#o-auth-provider'], ['session', '/docs/reference/backend/types/backend-session'], diff --git a/packages/shared/src/react/hooks/useOAuthDeviceVerification.types.ts b/packages/shared/src/react/hooks/useOAuthDeviceVerification.types.ts index 9b223a58caf..878a58f67ab 100644 --- a/packages/shared/src/react/hooks/useOAuthDeviceVerification.types.ts +++ b/packages/shared/src/react/hooks/useOAuthDeviceVerification.types.ts @@ -7,16 +7,44 @@ import type { SubmitOAuthDeviceVerificationParams, } from '../../types'; -type DecisionParams = Omit; - +/** + * @interface + */ export type UseOAuthDeviceVerificationReturn = { + /** + * Information about the device authorization returned by the latest successful lookup, or `undefined` if no lookup has succeeded. + */ data: OAuthDeviceVerificationInfo | undefined; + /** + * The result of the latest approval or denial, or `undefined` if no decision has succeeded. + */ result: OAuthDeviceVerificationResult | undefined; + /** + * The latest error recorded by a lookup or submission operation, or `null` if no error has been recorded since the state was last cleared. Preflight rejections (Clerk not loaded, or a conflicting request already in progress) reject the returned promise without setting this, so callers must also handle rejections from `lookup`, `approve`, and `deny`. + */ error: ClerkAPIResponseError | ClerkRuntimeError | null; + /** + * Whether a device authorization lookup is in progress. + */ isLoading: boolean; + /** + * Whether an approval or denial is in progress. + */ isSubmitting: boolean; + /** + * Looks up a device authorization by its user code. + */ lookup: (params: LookupOAuthDeviceVerificationParams) => Promise; - approve: (params: DecisionParams) => Promise; + /** + * Approves a device authorization. + */ + approve: (params: Omit) => Promise; + /** + * Denies a device authorization. + */ deny: (params: LookupOAuthDeviceVerificationParams) => Promise; + /** + * Clears the current device authorization state. + */ reset: () => void; }; diff --git a/packages/shared/src/types/oauthApplication.ts b/packages/shared/src/types/oauthApplication.ts index 584c976bc65..f0a5f1fc922 100644 --- a/packages/shared/src/types/oauthApplication.ts +++ b/packages/shared/src/types/oauthApplication.ts @@ -101,31 +101,81 @@ export type OAuthConsentInfo = { scopes: OAuthConsentScope[]; }; -export type OAuthDeviceVerificationStatus = 'pending' | 'approved' | 'denied' | 'consumed'; +/** + * The current status of an OAuth device authorization. + * + * @inline + */ +export type OAuthDeviceVerificationStatus = + /** + * The device authorization is awaiting approval or denial. + */ + | 'pending' + /** + * The device authorization was approved. + */ + | 'approved' + /** + * The device authorization was denied. + */ + | 'denied' + /** + * The approved device authorization has already been used by the device. + */ + | 'consumed'; /** * A scope requested by an OAuth device authorization. + * + * @interface */ export type OAuthDeviceVerificationScope = OAuthConsentScope; /** - * Information about an OAuth device authorization awaiting verification. + * Information about an OAuth device authorization. + * + * @interface */ export type OAuthDeviceVerificationInfo = { + /** + * The display name of the OAuth application requesting authorization. + */ oauthApplicationName: string; + /** + * The URL of the OAuth application's logo image, or `null` if no logo is available. + */ oauthApplicationLogoUrl: string | null; + /** + * The OAuth `client_id` that identifies the application requesting authorization. + */ clientId: string; + /** + * The scopes the OAuth application is requesting. + */ scopes: OAuthDeviceVerificationScope[]; + /** + * The current status of the device authorization. + */ status: OAuthDeviceVerificationStatus; - /** Expiration time as Unix milliseconds. */ + /** + * The expiration time of the device authorization, as a Unix timestamp in milliseconds. + */ expiresAt: number; }; /** * The result of approving or denying an OAuth device authorization. + * + * @interface */ export type OAuthDeviceVerificationResult = { + /** + * The type of the resource. + */ object: 'oauth_device_verification'; + /** + * The final decision for the device authorization. + */ status: Extract; }; @@ -138,13 +188,35 @@ export type GetOAuthConsentInfoParams = { redirectUri?: string; }; +/** + * The parameters for looking up an OAuth device authorization. + * + * @interface + */ export type LookupOAuthDeviceVerificationParams = { + /** + * The user code displayed by the device requesting authorization. + */ userCode: string; }; +/** + * The parameters for approving or denying an OAuth device authorization. + * + * @interface + */ export type SubmitOAuthDeviceVerificationParams = { + /** + * The user code displayed by the device requesting authorization. + */ userCode: string; + /** + * Whether to approve or deny the authorization request. + */ approved: boolean; + /** + * The ID of the Organization to authorize the request for. Omit this to authorize the request for the user's personal account. + */ organizationId?: string; };