cc upt
This commit is contained in:
+26
-28
@@ -581,11 +581,23 @@ function openApiDocument(basePath = "") {
|
||||
};
|
||||
}
|
||||
|
||||
function swaggerOptions(basePath = "") {
|
||||
function resolveBasePath(req: Request): string {
|
||||
// Behind the AppFactory reverse proxy the public prefix is /apps/<app-id>, but the
|
||||
// handle_path route strips it before the request reaches this container, so it cannot be
|
||||
// read from the request path. ROOT_PATH is the sanctioned source; X-Forwarded-Prefix is a
|
||||
// fallback for proxies that forward it. Empty when running without a proxy.
|
||||
const forwardedPrefix = getHeader(req, "x-forwarded-prefix");
|
||||
return (rootPath || forwardedPrefix || "").replace(/\/+$/, "");
|
||||
}
|
||||
|
||||
function swaggerUiOptions() {
|
||||
return {
|
||||
customSiteTitle: "SAP Business One connector API",
|
||||
swaggerOptions: {
|
||||
url: `${basePath}/openapi.json`.replace("//", "/"),
|
||||
// Relative endpoint (same approach as the sibling idoklad service): the browser resolves
|
||||
// it against the docs page, i.e. {prefix}/docs/openapi.json, so the spec loads locally and
|
||||
// behind the AppFactory proxy without hardcoding the /apps/<app-id> prefix.
|
||||
url: "openapi.json",
|
||||
displayRequestDuration: true,
|
||||
persistAuthorization: true,
|
||||
tryItOutEnabled: true,
|
||||
@@ -604,36 +616,22 @@ app.get("/health", (_req, res) => {
|
||||
res.json({ status: "ok" });
|
||||
});
|
||||
|
||||
app.get("/openapi.json", (_req, res) => {
|
||||
res.json(openApiDocument(rootPath));
|
||||
// OpenAPI document served under the same /docs prefix as the UI so the relative UI endpoint
|
||||
// resolves correctly locally and behind the reverse-proxy prefix. servers[0].url advertises the
|
||||
// public prefix (ROOT_PATH) so Swagger UI "Try it out" targets {prefix}/api/..., not the host root.
|
||||
app.get("/docs/openapi.json", (req, res) => {
|
||||
res.json(openApiDocument(resolveBasePath(req)));
|
||||
});
|
||||
|
||||
// Documented root alias for direct access to the OpenAPI document.
|
||||
app.get("/openapi.json", (req, res) => {
|
||||
res.json(openApiDocument(resolveBasePath(req)));
|
||||
});
|
||||
|
||||
app.use("/docs", swaggerUi.serve, swaggerUi.setup(undefined, swaggerUiOptions()));
|
||||
|
||||
addResourceEndpoints();
|
||||
|
||||
// Behind the AppFactory reverse proxy the container is reached via /apps/<app-id> and
|
||||
// the prefix is stripped (handle_path) before requests arrive here. The Swagger UI page is
|
||||
// therefore served at the public /apps/<app-id>/docs, so the OpenAPI document URL and the
|
||||
// "Try it out" base path must carry ROOT_PATH; otherwise the browser would resolve them
|
||||
// against the bare origin and bypass the app.
|
||||
app.use("/docs", swaggerUi.serveFiles(undefined, swaggerOptions(rootPath)), swaggerUi.setup(undefined, swaggerOptions(rootPath)));
|
||||
|
||||
if (rootPath) {
|
||||
app.get(rootPath, (_req, res) => {
|
||||
res.json(serviceMetadata());
|
||||
});
|
||||
|
||||
app.get(rootPath + "/health", (_req, res) => {
|
||||
res.json({ status: "ok" });
|
||||
});
|
||||
|
||||
app.get(rootPath + "/openapi.json", (_req, res) => {
|
||||
res.json(openApiDocument(rootPath));
|
||||
});
|
||||
|
||||
addResourceEndpoints(rootPath);
|
||||
app.use(rootPath + "/docs", swaggerUi.serveFiles(undefined, swaggerOptions(rootPath)), swaggerUi.setup(undefined, swaggerOptions(rootPath)));
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
app.listen(port, "0.0.0.0", () => {
|
||||
console.log(serviceId + " listening on port " + port);
|
||||
|
||||
Reference in New Issue
Block a user