@@ -165,16 +165,8 @@ export class RestServer extends Context implements Server, HttpServerLike {
165
165
config . openApiSpec = config . openApiSpec || { } ;
166
166
config . openApiSpec . endpointMapping =
167
167
config . openApiSpec . endpointMapping || OPENAPI_SPEC_MAPPING ;
168
- config . apiExplorer = config . apiExplorer || { } ;
169
168
170
- const url = config . apiExplorer . url || 'https://explorer.loopback.io' ;
171
-
172
- config . apiExplorer . httpUrl =
173
- config . apiExplorer . httpUrl ||
174
- config . apiExplorer . url ||
175
- 'http://explorer.loopback.io' ;
176
-
177
- config . apiExplorer . url = url ;
169
+ config . apiExplorer = normalizeApiExplorerConfig ( config . apiExplorer ) ;
178
170
179
171
this . config = config ;
180
172
this . bind ( RestBindings . PORT ) . to ( config . port ) ;
@@ -251,7 +243,16 @@ export class RestServer extends Context implements Server, HttpServerLike {
251
243
this . _serveOpenApiSpec ( req , res , mapping [ p ] ) ,
252
244
) ;
253
245
}
254
- this . _expressApp . get ( [ '/swagger-ui' , '/explorer' ] , ( req , res ) =>
246
+
247
+ const explorerConfig = this . config . apiExplorer || { } ;
248
+ if ( explorerConfig . disabled ) {
249
+ debug ( 'Redirect to swagger-ui was disabled by configuration.' ) ;
250
+ return ;
251
+ }
252
+
253
+ const explorerPaths = [ '/swagger-ui' , '/explorer' ] ;
254
+ debug ( 'Setting up redirect to swagger-ui. URL paths: %j' , explorerPaths ) ;
255
+ this . _expressApp . get ( explorerPaths , ( req , res ) =>
255
256
this . _redirectToSwaggerUI ( req , res ) ,
256
257
) ;
257
258
}
@@ -444,11 +445,9 @@ export class RestServer extends Context implements Server, HttpServerLike {
444
445
}
445
446
446
447
private async _redirectToSwaggerUI ( request : Request , response : Response ) {
448
+ const config = this . config . apiExplorer ! ;
447
449
const protocol = this . _getProtocolForRequest ( request ) ;
448
- const baseUrl =
449
- protocol === 'http'
450
- ? this . config . apiExplorer ! . httpUrl
451
- : this . config . apiExplorer ! . url ;
450
+ const baseUrl = protocol === 'http' ? config . httpUrl : config . url ;
452
451
const openApiUrl = `${ this . _getUrlForClient ( request ) } /openapi.json` ;
453
452
const fullUrl = `${ baseUrl } ?url=${ openApiUrl } ` ;
454
453
response . redirect ( 308 , fullUrl ) ;
@@ -822,13 +821,20 @@ export interface ApiExplorerOptions {
822
821
* default to https://loopback.io/api-explorer
823
822
*/
824
823
url ?: string ;
824
+
825
825
/**
826
826
* URL for the API explorer served over `http` protocol to deal with mixed
827
827
* content security imposed by browsers as the spec is exposed over `http` by
828
828
* default.
829
829
* See https://github.com/strongloop/loopback-next/issues/1603
830
830
*/
831
831
httpUrl ?: string ;
832
+
833
+ /**
834
+ * Set this flag to disable the built-in redirect to externally
835
+ * hosted API Explorer UI.
836
+ */
837
+ disabled ?: true ;
832
838
}
833
839
834
840
/**
@@ -848,3 +854,17 @@ export interface RestServerOptions {
848
854
* @interface RestServerConfig
849
855
*/
850
856
export type RestServerConfig = RestServerOptions & HttpServerOptions ;
857
+
858
+ function normalizeApiExplorerConfig (
859
+ input : ApiExplorerOptions | undefined ,
860
+ ) : ApiExplorerOptions {
861
+ const config = input || { } ;
862
+ const url = config . url || 'https://explorer.loopback.io' ;
863
+
864
+ config . httpUrl =
865
+ config . httpUrl || config . url || 'http://explorer.loopback.io' ;
866
+
867
+ config . url = url ;
868
+
869
+ return config ;
870
+ }
0 commit comments