swagger-tools on node: how to serve swagger-ui from basePath - swagger

using nodejs and swagger-tools v0.8.7 to route endpoints.
"basePath": "/api/myapi" in the api/myapi.json works great, ie: GET, POST, etc... at http://localhost:3000/api/myapi works.
But I still have to access http://localhost:3000/docs/ to get at the UI tool. How can I serve this from http://localhost:3000/api/myapi/docs/ ?
Same question for serving the yaml at /api/myapy/api-docs instead of /api-docs.
Thx.

got what i wanted via:
app.use(middleware.swaggerRouter(
{
swaggerUi: '/myapi.json',
controllers: './lib'
}));
app.use(middleware.swaggerUi(
{
"apiDocs": "/myapi/api",
"swaggerUi": "/myapi.json"
}
));

Related

How fix "Invalid host header" error in vue 3 project?

I'm tring to deploy a simple test app on cloud with digital ocean.
I created a new app with the vue cli (VUE3).
After i dockerized the app and exposed to 8080.
I configured the nginx so that it route traffic from port :80 to :8080 on the container.
Everything is ok, but when i try to visit the page i got this error "Invalid host header".
I searched on google and everybody suggest to create a vue.config.js file with this code:
module.exports = {
devServer: {
disableHostCheck: true
} }
I tried this solution but nothing is changed. How can i fix this error?
I also read that this kind of solution create vulnerabilities, is there a way to fix without this solution?
Thank you in advance for the response
In your vue.config.js file you can try this settings
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
allowedHosts: "all"
}
})
Found the solution!
The mentioned solutions above does not work for me.
I am not sure when the property allowedHosts was changed.
currently, we supposed to provide an array to the allowedHosts property.
devServer: {
allowedHosts: [
'yourdomain.com'
]
}
Just look for the file vue.config.js, then replace: yourdomain.com with your own personal domain.
An alternative to Oren Hahiashvili's answer when you don't know ahead of time what hosts will be accessing the devServer (e.g., when testing on multiple environments) is to set devServer.diableHostCheck in vue.config.js. For example,
module.exports = {
devServer: {
disableHostCheck: true
}
};
Note this is less secure than Oren Hahiashvili's answer, so only use this when you don't know the hosts, and you still need to serve using devServer.

laravel jetstream request api route middleware protected api:sanctum return unauthenticated response

I have a problem with 'domain' => env ('SESSION_DOMAIN', null) in the session.php file. When set SESSION_DOMAIN value in .env file, for example
SESSION_DOMAIN=mysite.test
login don't works and there seems to be a middlaware.
If not set this parameter, login work fine, therefore when I call api protected route with sanctum maiddleware ex.
Route::middleware(['auth:sanctum'])->group(function () {
Route::get('/myroute', function () {
return 'hello world!';
});
});
I have unauthenticated response.
If use web.php file route and insert the same function:
Route::middleware(['auth:sanctum'])->group(function () {
Route::get('/api/myroute', function () {
return 'hello world!';
});
});
with api prefix, its works fines.
I followed laravel 8.x sanctum documentation https://laravel.com/docs/8.x/sanctum. In laravel projects 7.* without jetstream I had no problem.
There's any suggest or explaination for this phenomenon.
Any explanation would be helpful for me! Many Thanks.
I ran into a similar issue where I could not authenticate any API request from my frontend. Turns out the generated Kernel.php did not include the Sanctum middleware for session cookies by default - you have to add it manually in your app/Http/Kernel.php:
'api' => [
EnsureFrontendRequestsAreStateful::class, // <- Add and import this middleware
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
After doing this API requests from my frontend are working again. Maybe this resolves your issue as well.

Add Swagger base path field in Nest.js project

I am trying to use nestjs/swagger to create a swagger file from my back-end and I am facing a problem related to the base path. What I want to achieve is to show version as base path instead of showing it in all the methods available, which is ugly and confusing.
My API, right now, has the following structure (this is a set of what is present in app.module.ts):
const routes: Routes = [
{
path: '/api',
module: ApiModule,
children: [
{
path: '/v1',
module: V1Module,
children: [
{
path: '/orders',
module: OrdersModule
},
{
path: '/users',
module: UsersModule
}
]
}
]
}
];
This way, once I generate and check the swagger, I see all my methods following the /api/v1 prefix. This could be an example:
orders
GET /api/v1/orders
POST /api/v1/orders
GET /api/v1/orders/{order_id}
...
users
GET /api/v1/users
POST /api/v1/users
GET /api/v1/users/{user_id}
...
What I want is to get rid of /api/v1 appearing in any method. I know that SWAGGER has fields for host and basePath, but do not find any way to populate it in Nest.js. Researching, I have found that there were .setBasePath() and .addServer() methods, but they do not work for me (I am pretty sure they are deprecated).
Thank very much for your help.
If you want nestjs to add api/v1 to every endpoint then use setGlobalPrefix('api/v1') to do that.
https://docs.nestjs.com/faq/global-prefix#global-prefix

Workbox offline mode works only on root path

Im working on my PWA application.
So I have one problem that I can't find any info how to fix.
I use workbox with webpack InjectManifest ( but also tried webpack offline-plugin ).
When I access my webpage at the root and go offline, I can see it's working perfectly. But when I change route to '/authorize' or basically any other route and go offline, it doesn't work.
Is there any requirement that it will work only in case that we are on root path? I can't find anything about it except for this: https://github.com/quasarframework/quasar-cli/issues/131
Ok found it.
So basically it all comes to routing.
https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route
https://developers.google.com/web/tools/workbox/modules/workbox-strategies
In my case, I wanted to always serve content as for SPA so I had to add
workbox.routing.registerNavigationRoute('/index.html'); to my workbox config.
At the end it looks like this:
1) Webpack plugin:
const commonPlugins = [
new workboxPlugin.InjectManifest({
swSrc: './src/workbox-sw.js',
swDest: 'workbox-sw.js',
}),
];
2) Content of workbox-sw
/* globals workbox, self */
workbox.setConfig({
debug: true
});
workbox.core.setCacheNameDetails({
prefix: 'sneak-client',
suffix: 'v1',
precache: 'sneak-precache',
runtime: 'sneak-runtime-cache',
});
workbox.routing.registerNavigationRoute('/index.html');
workbox.precaching.precacheAndRoute(self.__precacheManifest);

best way to tell swaggerui where the host is

When I build my swagger.json file I do not know which host to use. However I can work it out when my page that hosts swaggerui loads (in fact I might want to offer the user a choice). I hoped to see an options.host on the config for the swaggerUI object - I dont see one. Is there an existing way of doing this that I cant find or do I simply have to hack my way through the code and add this capability (pointers to the best place to do it would be welcome)
Swagger has a built-in json definition for host config, or can accept multiple inputs.
{
"swagger": "2.0",
"info": {
"title": "Why API",
"description": "Don't make that mistake again",
"version": "0.0.1"
},
"host": "127.0.0.1:3000",
"schemes": [
"https"
]
}
Or
"host": "test.mydomain.com:3000",
"schemes": [
"https"
],
Or you can have a dynamic host by defining a var and calling a hostname or machine name or other environment variables.
dynamic example
if (typeof this.host === 'undefined' || this.host === '') {
this.host = location.host;
}
if (location.port) {
this.host = this.host + ':' + location.port;
}
Here is what I do, since the loaded in document is just a JSON object:
var swaggerDoc = require('./api/swagger.json');
if (process.env.NODE_ENV === 'development') {
swaggerDoc.host="localhost:" + process.env.PORT
}
// Initialize the Swagger middleware
swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) {
// Other initialization
}
This way you don't pollute your API specification with development environment configuration.
In recent versions of Swagger UI it's possible to do this, for example in onComplete:
window.swaggerUi.api.setHost("your.host:4242");
If you are hosting it on same app server, just remove the host key from the json and provide relative path in key "basePath". as -
"basePath": "/rest/createcampaign".
two ways
One modify swagger.js so that it accepts host option. swagger-UI passes options to swagger-js so that works. I submitted a pull to swagger-js with this fix
Second choice is that swagger-UI accepts a 'spec' parameter. This means that the hosting page can load the swagger.json file, JSON.parse it , set 'host' in it and then pass to swaggerUi constructor. This is harder for the caller but doesn't require code changes to swagger
There are 2 ways which you can follow:
Load the index.html and replace the https://petstore.swagger.io/v2/swagger.json with the url where your swagger.json is hosting.
you can expose the local swagger.json on the same server.
When you follow this approach make sure you include static files in the end of above steps.
If you don't want to expose swagger.json as an API, copy the sawgger.json in the dist folder of swagger. The index.html and swagger.json must be in same repository for this. It is inside the index.html of dist folder of swagger-ui-dist.
const ui = SwaggerUIBundle({
spec: location.host,
url: "swagger.json",
dom_id: "#swagger-ui",
deepLinking: true,
presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
plugins: [SwaggerUIBundle.plugins.DownloadUrl],
layout: "StandaloneLayout"
});
// End Swagger UI call region
window.ui = ui;
};
Second way, host parameter in the swagger.yaml/swagger.json either make it empty
"host":""
or omit host parameter.
Swagger take the server's host as host where the swagger ui is hosted.
This is how I did this using the Java client:
DefaultApi api = new DefaultApi();
api.getApiClient().setBasePath("http://localhost:8080");
//call the API
if you use OpenApi 3.0
Variables can have arbitrary values, or may be restricted to an enum. In any case, a default value is required, which will be used if the client does not supply a value.
swagger doc
In the swagger-ui there will be the default value but the field is an input field so it is possible to customize it at runtime.
Swagger UI express itself is giving the following snippet it's getting the current host and publish dynamic with host
app.use('/api-docs', function(req, res, next){
swaggerDocument.host = req.get('host');
req.swaggerDoc = swaggerDocument;
next();
}, swaggerUi.serve, swaggerUi.setup());

Resources