Browse Source

fix: swagger UI blank page (#9475)

* fix: swagger-ui - if token missing in localstorage redirect to signin page

* fix: import statement correction

---------

Co-authored-by: Pranav C <pranavxc@gmail.com>
pull/9476/head
Mert E. 2 months ago committed by GitHub
parent
commit
df1d43999a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      packages/nc-gui/plugins/redirect.ts
  2. 29
      packages/nocodb/src/controllers/api-docs/api-docs.controller.ts
  3. 11
      packages/nocodb/src/controllers/api-docs/template/redocHtml.ts
  4. 10
      packages/nocodb/src/controllers/api-docs/template/swaggerHtml.ts

12
packages/nc-gui/plugins/redirect.ts

@ -1,3 +1,7 @@
const isFullUrl = (url: string) => {
return /^(https?:)?\/\//.test(url)
}
// this plugin is used to redirect user to the page they were trying to access before they were redirected to the login page // this plugin is used to redirect user to the page they were trying to access before they were redirected to the login page
export default defineNuxtPlugin(function (nuxtApp) { export default defineNuxtPlugin(function (nuxtApp) {
const router = useRouter() const router = useRouter()
@ -27,11 +31,15 @@ export default defineNuxtPlugin(function (nuxtApp) {
if (newToken && newToken !== oldToken) { if (newToken && newToken !== oldToken) {
try { try {
if (route.value.query?.continueAfterSignIn) { if (route.value.query?.continueAfterSignIn) {
await navigateTo(route.value.query.continueAfterSignIn as string) await navigateTo(route.value.query.continueAfterSignIn as string, {
external: isFullUrl(route.value.query.continueAfterSignIn as string),
})
} else { } else {
const continueAfterSignIn = localStorage.getItem('continueAfterSignIn') const continueAfterSignIn = localStorage.getItem('continueAfterSignIn')
if (continueAfterSignIn) { if (continueAfterSignIn) {
await navigateTo(continueAfterSignIn) await navigateTo(continueAfterSignIn, {
external: isFullUrl(continueAfterSignIn),
})
} }
} }
} finally { } finally {

29
packages/nocodb/src/controllers/api-docs/api-docs.controller.ts

@ -15,6 +15,7 @@ import { PublicApiLimiterGuard } from '~/guards/public-api-limiter.guard';
import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard'; import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard';
import { TenantContext } from '~/decorators/tenant-context.decorator'; import { TenantContext } from '~/decorators/tenant-context.decorator';
import { NcContext } from '~/interface/config'; import { NcContext } from '~/interface/config';
import Noco from '~/Noco';
@Controller() @Controller()
export class ApiDocsController { export class ApiDocsController {
@ -55,24 +56,44 @@ export class ApiDocsController {
@Get(['/api/v1/db/meta/projects/:baseId/swagger']) @Get(['/api/v1/db/meta/projects/:baseId/swagger'])
@UseGuards(PublicApiLimiterGuard) @UseGuards(PublicApiLimiterGuard)
swaggerHtml(@Param('baseId') baseId: string, @Response() res) { swaggerHtml(@Param('baseId') baseId: string, @Response() res) {
res.send(getSwaggerHtml({ ncSiteUrl: process.env.NC_PUBLIC_URL || '' })); res.send(
getSwaggerHtml({
ncSiteUrl: process.env.NC_PUBLIC_URL || '',
dashboardPath: Noco.getConfig().dashboardPath || '',
}),
);
} }
@UseGuards(PublicApiLimiterGuard) @UseGuards(PublicApiLimiterGuard)
@Get(['/api/v1/db/meta/projects/:baseId/redoc']) @Get(['/api/v1/db/meta/projects/:baseId/redoc'])
redocHtml(@Param('baseId') baseId: string, @Response() res) { redocHtml(@Param('baseId') baseId: string, @Response() res) {
res.send(getRedocHtml({ ncSiteUrl: process.env.NC_PUBLIC_URL || '' })); res.send(
getRedocHtml({
ncSiteUrl: process.env.NC_PUBLIC_URL || '',
dashboardPath: Noco.getConfig().dashboardPath || '',
}),
);
} }
@Get(['/api/v2/meta/bases/:baseId/swagger']) @Get(['/api/v2/meta/bases/:baseId/swagger'])
@UseGuards(PublicApiLimiterGuard) @UseGuards(PublicApiLimiterGuard)
swaggerHtmlV2(@Param('baseId') baseId: string, @Response() res) { swaggerHtmlV2(@Param('baseId') baseId: string, @Response() res) {
res.send(getSwaggerHtml({ ncSiteUrl: process.env.NC_PUBLIC_URL || '' })); res.send(
getSwaggerHtml({
ncSiteUrl: process.env.NC_PUBLIC_URL || '',
dashboardPath: Noco.getConfig().dashboardPath || '',
}),
);
} }
@UseGuards(PublicApiLimiterGuard) @UseGuards(PublicApiLimiterGuard)
@Get(['/api/v2/meta/bases/:baseId/redoc']) @Get(['/api/v2/meta/bases/:baseId/redoc'])
redocHtmlV2(@Param('baseId') baseId: string, @Response() res) { redocHtmlV2(@Param('baseId') baseId: string, @Response() res) {
res.send(getRedocHtml({ ncSiteUrl: process.env.NC_PUBLIC_URL || '' })); res.send(
getRedocHtml({
ncSiteUrl: process.env.NC_PUBLIC_URL || '',
dashboardPath: Noco.getConfig().dashboardPath || '',
}),
);
} }
} }

11
packages/nocodb/src/controllers/api-docs/template/redocHtml.ts vendored

@ -1,7 +1,9 @@
export default ({ export default ({
ncSiteUrl, ncSiteUrl,
dashboardPath,
}: { }: {
ncSiteUrl: string; ncSiteUrl: string;
dashboardPath: string;
}): string => `<!DOCTYPE html> }): string => `<!DOCTYPE html>
<html> <html>
<head> <head>
@ -39,6 +41,15 @@ export default ({
xhttp.setRequestHeader("xc-auth", initialLocalStorage && initialLocalStorage.token); xhttp.setRequestHeader("xc-auth", initialLocalStorage && initialLocalStorage.token);
xhttp.onload = function () { xhttp.onload = function () {
// if invalid token then redirect to signin page
if (xmlhttp.status === 401) {
window.location.href = ${JSON.stringify(ncSiteUrl)} + ${JSON.stringify(
dashboardPath,
)} + '#/signin?continueAfterSignIn=' + encodeURIComponent(window.location.href);
return;
}
const swaggerJson = this.responseText; const swaggerJson = this.responseText;
const swagger = JSON.parse(swaggerJson); const swagger = JSON.parse(swaggerJson);
Redoc.init(swagger, { Redoc.init(swagger, {

10
packages/nocodb/src/controllers/api-docs/template/swaggerHtml.ts vendored

@ -1,7 +1,9 @@
export default ({ export default ({
ncSiteUrl, ncSiteUrl,
dashboardPath,
}: { }: {
ncSiteUrl: string; ncSiteUrl: string;
dashboardPath: string;
}): string => `<!DOCTYPE html> }): string => `<!DOCTYPE html>
<html> <html>
<head> <head>
@ -28,6 +30,14 @@ xmlhttp.open("GET", "./swagger.json");
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xmlhttp.setRequestHeader("xc-auth", initialLocalStorage && initialLocalStorage.token); xmlhttp.setRequestHeader("xc-auth", initialLocalStorage && initialLocalStorage.token);
xmlhttp.onload = function () { xmlhttp.onload = function () {
// if invalid token then redirect to signin page
if (xmlhttp.status === 401) {
window.location.href = ${JSON.stringify(ncSiteUrl)} + ${JSON.stringify(
dashboardPath,
)} + '#/signin?continueAfterSignIn=' + encodeURIComponent(window.location.href);
return;
}
const ui = SwaggerUIBundle({ const ui = SwaggerUIBundle({
// url: , // url: ,

Loading…
Cancel
Save