@@ -4,6 +4,7 @@ const defaultState = require('crypto').randomBytes(10).toString('hex')
44
55const fp = require ( 'fastify-plugin' )
66const oauth2Module = require ( 'simple-oauth2' )
7+ const kGenerateCallbackUriParams = Symbol . for ( 'fastify-oauth2.generate-callback-uri-params' )
78
89const promisify = require ( 'util' ) . promisify
910const callbackify = require ( 'util' ) . callbackify
@@ -20,6 +21,10 @@ function defaultCheckStateFunction (state, callback) {
2021 callback ( new Error ( 'Invalid state' ) )
2122}
2223
24+ function defaultGenerateCallbackUriParams ( callbackUriParams ) {
25+ return callbackUriParams
26+ }
27+
2328const oauthPlugin = fp ( function ( fastify , options , next ) {
2429 if ( typeof options . name !== 'string' ) {
2530 return next ( new Error ( 'options.name should be a string' ) )
@@ -59,13 +64,14 @@ const oauthPlugin = fp(function (fastify, options, next) {
5964 const scope = options . scope
6065 const generateStateFunction = options . generateStateFunction || defaultGenerateStateFunction
6166 const checkStateFunction = options . checkStateFunction || defaultCheckStateFunction
67+ const generateCallbackUriParams = ( credentials . auth && credentials . auth [ kGenerateCallbackUriParams ] ) || defaultGenerateCallbackUriParams
6268 const startRedirectPath = options . startRedirectPath
6369 const tags = options . tags || [ ]
6470 const schema = options . schema || { tags : tags }
6571
6672 function generateAuthorizationUri ( requestObject ) {
6773 const state = generateStateFunction ( requestObject )
68- const urlOptions = Object . assign ( { } , callbackUriParams , {
74+ const urlOptions = Object . assign ( { } , generateCallbackUriParams ( callbackUriParams , requestObject , scope , state ) , {
6975 redirect_uri : callbackUri ,
7076 scope : scope ,
7177 state : state
@@ -149,7 +155,24 @@ oauthPlugin.APPLE_CONFIGURATION = {
149155 authorizeHost : 'https://appleid.apple.com' ,
150156 authorizePath : '/auth/authorize' ,
151157 tokenHost : 'https://appleid.apple.com' ,
152- tokenPath : '/auth/token'
158+ tokenPath : '/auth/token' ,
159+ // kGenerateCallbackUriParams is used for dedicated behavior for each OAuth2.0 provider
160+ // It can update the callbackUriParams based on requestObject, scope and state
161+ //
162+ // Symbol used in here because we would not like the user to modify this behavior and
163+ // do not want to mess up with property name collision
164+ [ kGenerateCallbackUriParams ] : function ( callbackUriParams , requestObject , scope , state ) {
165+ const stringifyScope = Array . isArray ( scope ) ? scope . join ( ' ' ) : scope
166+ // This behavior is not documented on Apple Developer Docs but it display through runtime error.
167+ // Related Docs: https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms
168+ // Related Issue: https://github.com/fastify/fastify-oauth2/issues/116
169+ //
170+ // `response_mode` must be `form_post` when scope include `email` or `name`
171+ if ( stringifyScope . includes ( 'email' ) || stringifyScope . includes ( 'name' ) ) {
172+ callbackUriParams . response_mode = 'form_post'
173+ }
174+ return callbackUriParams
175+ }
153176}
154177
155178oauthPlugin . FACEBOOK_CONFIGURATION = {
0 commit comments