diff --git a/packages/nc-gui/plugins/redirect.ts b/packages/nc-gui/plugins/redirect.ts index ed598240a3..1bf5369f08 100644 --- a/packages/nc-gui/plugins/redirect.ts +++ b/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 export default defineNuxtPlugin(function (nuxtApp) { const router = useRouter() @@ -27,11 +31,15 @@ export default defineNuxtPlugin(function (nuxtApp) { if (newToken && newToken !== oldToken) { try { 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 { const continueAfterSignIn = localStorage.getItem('continueAfterSignIn') if (continueAfterSignIn) { - await navigateTo(continueAfterSignIn) + await navigateTo(continueAfterSignIn, { + external: isFullUrl(continueAfterSignIn), + }) } } } finally { diff --git a/packages/nocodb/src/controllers/api-docs/api-docs.controller.ts b/packages/nocodb/src/controllers/api-docs/api-docs.controller.ts index 4c9ab3c437..53ec485313 100644 --- a/packages/nocodb/src/controllers/api-docs/api-docs.controller.ts +++ b/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 { TenantContext } from '~/decorators/tenant-context.decorator'; import { NcContext } from '~/interface/config'; +import Noco from '~/Noco'; @Controller() export class ApiDocsController { @@ -55,24 +56,44 @@ export class ApiDocsController { @Get(['/api/v1/db/meta/projects/:baseId/swagger']) @UseGuards(PublicApiLimiterGuard) 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) @Get(['/api/v1/db/meta/projects/:baseId/redoc']) 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']) @UseGuards(PublicApiLimiterGuard) 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) @Get(['/api/v2/meta/bases/:baseId/redoc']) 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 || '', + }), + ); } } diff --git a/packages/nocodb/src/controllers/api-docs/template/redocHtml.ts b/packages/nocodb/src/controllers/api-docs/template/redocHtml.ts index cc2682fdac..beb6ec9681 100644 --- a/packages/nocodb/src/controllers/api-docs/template/redocHtml.ts +++ b/packages/nocodb/src/controllers/api-docs/template/redocHtml.ts @@ -1,7 +1,9 @@ export default ({ ncSiteUrl, + dashboardPath, }: { ncSiteUrl: string; + dashboardPath: string; }): string => ` @@ -39,6 +41,15 @@ export default ({ xhttp.setRequestHeader("xc-auth", initialLocalStorage && initialLocalStorage.token); 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 swagger = JSON.parse(swaggerJson); Redoc.init(swagger, { diff --git a/packages/nocodb/src/controllers/api-docs/template/swaggerHtml.ts b/packages/nocodb/src/controllers/api-docs/template/swaggerHtml.ts index 27f6bef73d..8338bcd94a 100644 --- a/packages/nocodb/src/controllers/api-docs/template/swaggerHtml.ts +++ b/packages/nocodb/src/controllers/api-docs/template/swaggerHtml.ts @@ -1,7 +1,9 @@ export default ({ ncSiteUrl, + dashboardPath, }: { ncSiteUrl: string; + dashboardPath: string; }): string => ` @@ -28,6 +30,14 @@ xmlhttp.open("GET", "./swagger.json"); xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); xmlhttp.setRequestHeader("xc-auth", initialLocalStorage && initialLocalStorage.token); 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({ // url: ,