A zero-dependency AT Protocol Personal Data Server written in JavaScript
atproto pds

refactor: use validateAuthorizationParameters in handleOAuthPar

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Changed files
+9 -45
src
+9 -45
src/pds.js
··· 3844 3844 const codeChallengeMethod = data.code_challenge_method; 3845 3845 const loginHint = data.login_hint; 3846 3846 3847 - if (!clientId) 3848 - return errorResponse('invalid_request', 'client_id required', 400); 3849 - if (!redirectUri) 3850 - return errorResponse('invalid_request', 'redirect_uri required', 400); 3851 - if (responseType !== 'code') 3852 - return errorResponse( 3853 - 'unsupported_response_type', 3854 - 'response_type must be code', 3855 - 400, 3856 - ); 3857 - if (!codeChallenge || codeChallengeMethod !== 'S256') { 3858 - return errorResponse('invalid_request', 'PKCE with S256 required', 400); 3859 - } 3860 - 3861 - let clientMetadata; 3862 - try { 3863 - clientMetadata = await getClientMetadata(clientId); 3864 - } catch (err) { 3865 - return errorResponse('invalid_client', err.message, 400); 3866 - } 3867 - 3868 - // Validate redirect_uri against registered URIs 3869 - // For loopback clients (RFC 8252), allow any path on the same origin 3870 - const isLoopback = 3871 - clientId.startsWith('http://localhost') || 3872 - clientId.startsWith('http://127.0.0.1'); 3873 - const redirectUriValid = clientMetadata.redirect_uris.some((uri) => { 3874 - if (isLoopback) { 3875 - // For loopback, check origin match (any path allowed) 3876 - try { 3877 - const registered = new URL(uri); 3878 - const requested = new URL(redirectUri); 3879 - return registered.origin === requested.origin; 3880 - } catch { 3881 - return false; 3882 - } 3883 - } 3884 - return uri === redirectUri; 3847 + // Use shared validation 3848 + const validationResult = await this.validateAuthorizationParameters({ 3849 + clientId, 3850 + redirectUri, 3851 + responseType, 3852 + codeChallenge, 3853 + codeChallengeMethod, 3885 3854 }); 3886 - if (!redirectUriValid) { 3887 - return errorResponse( 3888 - 'invalid_request', 3889 - 'redirect_uri not registered for this client', 3890 - 400, 3891 - ); 3892 - } 3855 + if ('error' in validationResult) return validationResult.error; 3856 + const { clientMetadata } = validationResult; 3893 3857 3894 3858 const requestId = crypto.randomUUID(); 3895 3859 const requestUri = `urn:ietf:params:oauth:request_uri:${requestId}`;