@@ -3,8 +3,8 @@ import { useRuntimeConfig } from '#imports'
33import { defu } from 'defu'
44import type { H3Event } from 'h3'
55import { createError , eventHandler , getQuery , sendRedirect } from 'h3'
6- import { withQuery } from 'ufo'
7- import { getOAuthRedirectURL , handleAccessTokenErrorResponse , handleInvalidState , handleMissingConfiguration , handlePkceVerifier , handleState , requestAccessToken } from '../utils'
6+ import { QueryObject , withQuery } from 'ufo'
7+ import { getOAuthRedirectURL , handleAccessTokenErrorResponse , handleInvalidState , handleMissingConfiguration , handlePkceVerifier , handleState , requestAccessToken , RequestAccessTokenBody } from '../utils'
88
99export interface OAuthOidcConfig {
1010 /**
@@ -240,7 +240,7 @@ interface OIDCConfiguration {
240240 */
241241export function defineOAuthOidcEventHandler < TUser = OidcUser > ( { config, onSuccess, onError } : OAuthConfig < OAuthOidcConfig , { user : TUser , tokens : OidcTokens } > ) {
242242 return eventHandler ( async ( event : H3Event ) => {
243- config = defu ( config , useRuntimeConfig ( event ) . oauth ? .oidc , {
243+ config = defu ( config , useRuntimeConfig ( event ) . oauth . oidc , {
244244 scope : [ 'openid' ] ,
245245 } satisfies OAuthOidcConfig )
246246
@@ -271,35 +271,49 @@ export function defineOAuthOidcEventHandler<TUser = OidcUser>({ config, onSucces
271271 if ( ! query . code ) {
272272 config . scope = config . scope || [ ]
273273
274- return sendRedirect (
275- event ,
276- withQuery ( oidcConfig . authorization_endpoint , {
277- client_id : config . clientId ,
278- redirect_uri : redirectURL ,
279- scope : config . scope . join ( ' ' ) ,
280- state,
281- response_type : 'code' ,
282- code_challenge : verifier ?. code_challenge ,
283- code_challenge_method : verifier ?. code_challenge_method ,
284- ...config . parameters ?. authorization_endpoint ,
285- } ) ,
274+ const authQuery : QueryObject = {
275+ client_id : config . clientId ,
276+ redirect_uri : redirectURL ,
277+ scope : config . scope . join ( ' ' ) ,
278+ state,
279+ response_type : 'code' ,
280+ ...config . parameters ?. authorization_endpoint ,
281+ }
282+
283+ // when using PKCE, we need to set the code_challenge in the request
284+ // since some OIDC providers fail with an error if those parameters are set with "undefined" value
285+ // we make sure to only include them at all if they are set
286+ if ( verifier ) {
287+ authQuery . code_challenge = verifier . code_challenge
288+ authQuery . code_challenge_method = verifier . code_challenge_method
289+ }
290+
291+ return sendRedirect ( event , withQuery ( oidcConfig . authorization_endpoint , authQuery ) ,
286292 )
287293 }
288294
289295 if ( query . state !== state ) {
290296 return handleInvalidState ( event , 'oidc' , onError )
291297 }
292298
299+ const tokenQuery : RequestAccessTokenBody = {
300+ grant_type : 'authorization_code' ,
301+ client_id : config . clientId ,
302+ client_secret : config . clientSecret ,
303+ redirect_uri : redirectURL ,
304+ code : query . code ,
305+ ...config . parameters ?. token_endpoint ,
306+ }
307+
308+ // when using PKCE, we need to set the code_challenge in the request
309+ // since some OIDC providers fail with an error if those parameters are set with "undefined" value
310+ // we make sure to only include them at all if they are set
311+ if ( verifier ) {
312+ tokenQuery . code_verifier = verifier . code_verifier
313+ }
314+
293315 const tokens = await requestAccessToken < OidcTokens & { error ?: unknown } > ( oidcConfig . token_endpoint , {
294- body : {
295- grant_type : 'authorization_code' ,
296- client_id : config . clientId ,
297- client_secret : config . clientSecret ,
298- redirect_uri : redirectURL ,
299- code : query . code ,
300- code_verifier : verifier ?. code_verifier ,
301- ...config . parameters ?. token_endpoint ,
302- } ,
316+ body : tokenQuery ,
303317 } )
304318
305319 if ( tokens . error ) {
0 commit comments