@redocly/redoc 0.137.0-next.4 → 0.137.0-next.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/api-schemas/otel-traces.d.ts +1359 -0
  3. package/dist/api-schemas/otel-traces.js +1 -0
  4. package/dist/cli/stats/collectors/asyncapi/index.d.ts +3 -0
  5. package/dist/cli/stats/collectors/asyncapi/index.js +1 -0
  6. package/dist/cli/stats/collectors/extension-sampling.d.ts +44 -0
  7. package/dist/cli/stats/collectors/extension-sampling.js +1 -0
  8. package/dist/cli/stats/collectors/openapi/index.js +1 -1
  9. package/dist/cli/stats/collectors/prepare-stats-walk.d.ts +10 -0
  10. package/dist/cli/stats/collectors/prepare-stats-walk.js +1 -0
  11. package/dist/cli/stats/collectors/run-stats-collector.d.ts +24 -0
  12. package/dist/cli/stats/collectors/run-stats-collector.js +1 -0
  13. package/dist/cli/stats/index.js +1 -1
  14. package/dist/client/app/hooks/useMcpData.d.ts +1 -0
  15. package/dist/client/app/hooks/useMcpData.js +1 -1
  16. package/dist/client/app/markdoc/custom-components/openapi/json-schema.js +1 -1
  17. package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -1
  18. package/dist/client/app/markdoc/custom-components/openapi/openapi-example.js +1 -1
  19. package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -1
  20. package/dist/client/app/markdoc/custom-components/openapi/use-markdown-adapter.d.ts +45 -0
  21. package/dist/client/app/markdoc/custom-components/openapi/use-markdown-adapter.js +1 -0
  22. package/dist/client/providers/hooks.js +1 -1
  23. package/dist/client/providers/post-message/PostMessageProvider.js +1 -1
  24. package/dist/constants/l10n/langs/ar.js +1 -1
  25. package/dist/constants/l10n/langs/de.js +1 -1
  26. package/dist/constants/l10n/langs/en.js +1 -1
  27. package/dist/constants/l10n/langs/es.js +1 -1
  28. package/dist/constants/l10n/langs/fr.js +1 -1
  29. package/dist/constants/l10n/langs/hi.js +1 -1
  30. package/dist/constants/l10n/langs/it.js +1 -1
  31. package/dist/constants/l10n/langs/ja.js +1 -1
  32. package/dist/constants/l10n/langs/ko.js +1 -1
  33. package/dist/constants/l10n/langs/pl.js +1 -1
  34. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  35. package/dist/constants/l10n/langs/pt.js +1 -1
  36. package/dist/constants/l10n/langs/ru.js +1 -1
  37. package/dist/constants/l10n/langs/uk.js +1 -1
  38. package/dist/constants/l10n/langs/zh.js +1 -1
  39. package/dist/server/config/env-config.d.ts +2 -0
  40. package/dist/server/config/env-schema.d.ts +5 -0
  41. package/dist/server/config/env-schemas/search.d.ts +3 -0
  42. package/dist/server/config/env-schemas/search.js +1 -1
  43. package/dist/server/constants/mcp.d.ts +5 -0
  44. package/dist/server/constants/mcp.js +1 -0
  45. package/dist/server/constants/plugins/search.d.ts +0 -2
  46. package/dist/server/constants/plugins/search.js +1 -1
  47. package/dist/server/constants/rbac.d.ts +3 -0
  48. package/dist/server/constants/rbac.js +1 -0
  49. package/dist/server/plugins/api-docs/search/get-ai-search-documents.js +9 -9
  50. package/dist/server/plugins/api-docs/search/search-indexer.js +1 -1
  51. package/dist/server/plugins/markdown/utils/sanitize-malformed-md-content.js +2 -2
  52. package/dist/server/plugins/mcp/auth/auth-handlers.d.ts +1 -2
  53. package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
  54. package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +1 -1
  55. package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +1 -1
  56. package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -1
  57. package/dist/server/plugins/mcp/codemode/tools/manage-credentials.js +2 -2
  58. package/dist/server/plugins/mcp/constants.d.ts +0 -1
  59. package/dist/server/plugins/mcp/constants.js +1 -1
  60. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  61. package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +3 -2
  62. package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +5 -4
  63. package/dist/server/plugins/mcp/gateway-mcp/eligibility.js +1 -1
  64. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-audit.d.ts +2 -1
  65. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-audit.js +1 -1
  66. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
  67. package/dist/server/plugins/mcp/gateway-mcp/fetch/upstream-detail.d.ts +7 -0
  68. package/dist/server/plugins/mcp/gateway-mcp/fetch/upstream-detail.js +1 -0
  69. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.d.ts +6 -0
  70. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.js +1 -1
  71. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  72. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
  73. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +1 -1
  74. package/dist/server/plugins/mcp/handlers/mcp-credentials-page.d.ts +6 -0
  75. package/dist/server/plugins/mcp/handlers/mcp-credentials-page.js +50 -42
  76. package/dist/server/plugins/mcp/index.d.ts +0 -2
  77. package/dist/server/plugins/mcp/index.js +1 -1
  78. package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
  79. package/dist/server/plugins/mcp/servers/mcp-server.js +3 -3
  80. package/dist/server/plugins/mcp/types.d.ts +1 -0
  81. package/dist/server/plugins/mcp/utils/tool-registration.d.ts +17 -0
  82. package/dist/server/plugins/mcp/utils/tool-registration.js +1 -0
  83. package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +5 -5
  84. package/dist/server/plugins/search/engines/typesense/index.js +1 -1
  85. package/dist/server/plugins/search/index.js +1 -1
  86. package/dist/server/plugins/search/utils.d.ts +2 -1
  87. package/dist/server/plugins/search/utils.js +2 -2
  88. package/dist/server/types/plugins/common.d.ts +1 -0
  89. package/dist/server/utils/rbac/can-anonymous-access-mcp-feature.d.ts +3 -0
  90. package/dist/server/utils/rbac/can-anonymous-access-mcp-feature.js +1 -0
  91. package/dist/server/utils/rbac/should-handle-mcp-auth.d.ts +2 -0
  92. package/dist/server/utils/rbac/should-handle-mcp-auth.js +1 -0
  93. package/dist/server/utils/rbac.js +1 -1
  94. package/dist/server/web-server/auth.js +3 -3
  95. package/dist/server/web-server/handle-api-route-request.js +1 -1
  96. package/dist/server/web-server/routes/error.js +1 -1
  97. package/dist/server/web-server/routes/helpers/resolve-ui-locales-for-idp-login.js +1 -1
  98. package/dist/server/web-server/routes/index.js +1 -1
  99. package/dist/server/web-server/routes/mcp-routes/agent-card.js +1 -1
  100. package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -1
  101. package/dist/server/web-server/routes/otel/otel.js +1 -1
  102. package/dist/server/web-server/routes/page-data.js +1 -1
  103. package/dist/server/web-server/utils/prepare-list-response.d.ts +0 -4
  104. package/dist/server/web-server/utils/prepare-list-response.js +1 -1
  105. package/dist/server/web-server/utils.d.ts +1 -1
  106. package/dist/server/web-server/utils.js +1 -1
  107. package/dist/types/global-data.d.ts +1 -0
  108. package/package.json +9 -9
@@ -1,7 +1,8 @@
1
- import type { RedoclyConfig } from '@redocly/config';
1
+ import type { RedoclyConfig, SearchEngineType } from '@redocly/config';
2
2
  export declare function isAiSearchEnabled(config: RedoclyConfig): boolean;
3
3
  export declare function isDocsMcpEnabled(config: RedoclyConfig): boolean;
4
4
  export declare function shouldGenerateEmbeddings(config: RedoclyConfig): boolean;
5
+ export declare function shouldIndexSearchDocuments(engine: SearchEngineType): boolean;
5
6
  export declare function getSearchDocumentGroup(documentFacets?: Record<string, string>): string | undefined;
6
7
  export declare function formatDocumentMetadata(metadata?: Record<string, unknown>): string;
7
8
  //# sourceMappingURL=utils.d.ts.map
@@ -1,2 +1,2 @@
1
- import{SEARCH_GROUP_FACET_FIELD as o}from"../../../constants/common.js";import{DEFAULT_AI_SEARCH_ENABLED as s}from"../../constants/plugins/search.js";import{isPrimitive as c}from"../../../utils/guards/is-primitive.js";import{envConfig as i}from"../../config/env-config.js";import{EntitlementsProvider as n}from"../../entitlements/entitlements-provider.js";function a(e){if(i.isDevelopMode)return i.SEARCH_DEV_DEBUG;if(!n.instance().canAccessFeature("aiSearchLimit"))return!1;const t=e.aiAssistant;return typeof t?.hide=="boolean"?!t?.hide:s}function m(e){return n.instance().canAccessFeature("mcp")?!e.mcp?.hide&&!e.mcp?.docs?.hide:!1}function h(e){const r=a(e),t=m(e);return r||t}function l(e){let r;return e&&Object.keys(e).forEach(t=>{t===o&&(r=e[t])}),r}function S(e){return Object.entries(e||{}).map(([r,t])=>` - ${r}: ${c(t)?t:JSON.stringify(t)}`).join(`
2
- `)}export{S as formatDocumentMetadata,l as getSearchDocumentGroup,a as isAiSearchEnabled,m as isDocsMcpEnabled,h as shouldGenerateEmbeddings};
1
+ import{SEARCH_GROUP_FACET_FIELD as o}from"../../../constants/common.js";import{DEFAULT_AI_SEARCH_ENABLED as s}from"../../constants/plugins/search.js";import{isPrimitive as c}from"../../../utils/guards/is-primitive.js";import{envConfig as n}from"../../config/env-config.js";import{EntitlementsProvider as i}from"../../entitlements/entitlements-provider.js";function a(e){if(n.isDevelopMode)return n.SEARCH_DEV_DEBUG;if(!i.instance().canAccessFeature("aiSearchLimit"))return!1;const t=e.aiAssistant;return typeof t?.hide=="boolean"?!t?.hide:s}function u(e){return i.instance().canAccessFeature("mcp")?!e.mcp?.hide&&!e.mcp?.docs?.hide:!1}function S(e){const r=a(e),t=u(e);return(r||t)&&n.isProductionEnv}function l(e){return e==="typesense"?!n.REDOCLY_SKIP_TYPESENSE_INDEXING:!0}function A(e){let r;return e&&Object.keys(e).forEach(t=>{t===o&&(r=e[t])}),r}function D(e){return Object.entries(e||{}).map(([r,t])=>` - ${r}: ${c(t)?t:JSON.stringify(t)}`).join(`
2
+ `)}export{D as formatDocumentMetadata,A as getSearchDocumentGroup,a as isAiSearchEnabled,u as isDocsMcpEnabled,S as shouldGenerateEmbeddings,l as shouldIndexSearchDocuments};
@@ -123,6 +123,7 @@ export type ApiRoute = RouteDetails & {
123
123
  };
124
124
  export type McpToolSchema = {
125
125
  name: string;
126
+ title?: string;
126
127
  description: string;
127
128
  schema: Record<string, unknown>;
128
129
  outputSchema?: Record<string, unknown>;
@@ -0,0 +1,3 @@
1
+ import type { RbacConfig } from '@redocly/config';
2
+ export declare function canAnonymousAccessMcpFeature(rbacConfig: RbacConfig, requiresLogin: boolean): boolean;
3
+ //# sourceMappingURL=can-anonymous-access-mcp-feature.d.ts.map
@@ -0,0 +1 @@
1
+ import{RbacFeatures as o}from"../../../constants/common.js";import{ANONYMOUS_AUTH_DETAILS as c}from"../../constants/rbac.js";import{canAccessFeature as t}from"../rbac.js";function s(r,e){return t(o.MCP,c,r,e)}export{s as canAnonymousAccessMcpFeature};
@@ -0,0 +1,2 @@
1
+ export declare function shouldHandleMcpAuth(requiresLogin: boolean, rbacConfig?: Record<string, unknown>): boolean;
2
+ //# sourceMappingURL=should-handle-mcp-auth.d.ts.map
@@ -0,0 +1 @@
1
+ import{DEFAULT_ANONYMOUS_VISITOR_TEAM as s,RBAC_ALL_OTHER_TEAMS as u,RbacFeatures as a}from"../../../constants/common.js";function r(e){return!e||typeof e!="object"||Object.keys(e).length===0?!1:!(e[s]&&e[s]!=="none"||e[u]&&e[u]!=="none")}function c(e,t){if(!t||Object.keys(t).length===0)return e;const n=t.content;if(n&&Object.keys(n).length>0&&Object.values(n).some(r))return!0;const o=t.teamFoldersBaseRoles;if(r(o))return!0;const f=t.features;return r(f?.[a.MCP])?!0:e}export{c as shouldHandleMcpAuth};
@@ -1 +1 @@
1
- import y from"path";import P from"picomatch";import"../node-crypto-polyfill.js";import{REDOCLY_TEAMS_RBAC as _,REDOCLY_ROUTE_RBAC as A}from"@redocly/config";import{ServerRoutes as k}from"../../constants/api.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as x,PUBLIC_RBAC_SCOPE_ITEM as R,RBAC_ALL_OTHER_TEAMS as l,DEFAULT_RBAC_SCOPE as L}from"../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as j,PUBLIC_API_DEFINITIONS_FOLDER as I,PUBLIC_ASSETS_FOLDER as w}from"../constants/common.js";import{removeTrailingSlash as B}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as b}from"../../utils/url/remove-leading-slash.js";import{parsePathVersions as M}from"../../utils/path/parse-path-versions.js";import{reporter as U}from"../tools/notifiers/reporter.js";import{bold as W}from"../tools/notifiers/helpers/colors.js";import{shaDirPathShort as $}from"../utils/crypto/sha-dir-path-short.js";import{isTruthy as v}from"../../utils/guards/is-truthy.js";import{canExpandConfig as Y,expandRbacConfig as z,getTeamFolderDefaults as K,parseTeamFoldersTemplate as H,parseTeamNameTemplate as G}from"./rbac-expand.js";import{getUserParamsFromCookies as V}from"../web-server/auth.js";import{getDeeperGlobPattern as J}from"./globs.js";import{EntitlementsProvider as Q}from"../entitlements/entitlements-provider.js";const C=["NONE","READ","TRIAGE","WRITE","MAINTAIN","ADMIN"],X=new Set(["x-parsed-md-description","x-parsed-md-summary"]);function Pt(t,e){const r=C.indexOf(t.toUpperCase()),n=C.indexOf(e.toUpperCase());return r>n?t:e}const E={};function T(t,e){if(!t?.content)return R;const r=t.content,{slug:n,fsPath:s}=e;if(!n&&!s)return R;const o=a=>{const d=`slug:${a}`,p=E[d]??P(a);E[d]=p;const g=`fsPath:${a}`,S=E[g]??P(b(a));return E[g]=S,!!(n&&p(n))||!!(s&&S(s))};if(tt(n||s||"")&&Object.keys(r).filter(p=>o(p)).length===0)return r[L]||R;const f=Object.keys(r).filter(a=>o(a));if(f.length==0)return R;const u=f.map(a=>P.scan(a,{tokens:!0,parts:!0}));let h=u[0];for(let a=1;a<u.length;a++)h=J(h,u[a]);return r[h.input]}function F(t,e,r){const n=r?[...e,r]:e,s=[];for(const o of n)t[o]?s.push(t[o]):t[l]&&o!==r&&s.push(t[l]);return s.some(o=>o.toLowerCase()!=="none")}function xt(t,e,r={},n=!1){if(n&&Object.keys(r).length===0)return e.isAuthenticated;const s=r.features?.[t];return s?F(s,e.teams):!0}function Dt(t,e){return O(t,{isAuthenticated:!1,teams:[x]},e.access?.rbac||{},e.access?.requiresLogin||!1)}function O(t,e={},r={},n=!1){if(t.slug&&typeof t.slug=="string"&&Object.values(k).some(c=>{const i=c.split(":")[0].replace(/\/$/,"");return t.slug===i||t.slug?.startsWith(c)})||t.slug==="/mcp"&&Q.instance().canAccessFeature("mcp"))return!0;if(n&&Object.keys(r).length===0)return!!e.isAuthenticated;const s=z(r,e.teams||[]),o=t[_]||T(s,t[A]||{});return Object.keys(o||{}).length===0?!1:Object.keys(o).length===1&&o[l]&&o[l].toLowerCase()!=="none"?!0:F(o,e?.teams||[],e?.email)}function gt(t,e,r,n){if(!t.startsWith(I)&&!t.startsWith(j))return!0;const s=t.replace(new RegExp(`^${I}/`),"").replace(new RegExp(`^${j}/`),""),c=s==="."?"":s,i={[A]:{slug:t,fsPath:c},slug:t};return O(i,n,e,r)}function St(t,e,r,n,s){if(!t.startsWith(w))return!0;const o=t.match(/.*\..{64}\.([A-Fa-f0-9]{8})\.[^\.]+$/)?.[1];if(!o)return!0;const c=n[o];if(!c)return!0;const{base:i,ext:f}=y.parse(t),u=i.split(".")[0],h=f.split(".").join(""),d=c==="."?"":c,p={[A]:{slug:t,fsPath:y.posix.join(d,`${u}.${h}`)},slug:t};return O(p,s,e,r)}async function _t(t,e){const{isAuthenticated:r=!1,idpAccessToken:n,federatedAccessToken:s,federatedIdToken:o,...c}=await V(t,e),{teams:i=[]}=c;let f;return r?f=i.filter(u=>u!==x):f=[x],{isAuthenticated:r,idpAccessToken:n,teams:f,claims:c}}function N(t,e,r={},n=!1){if(!t)return t;if(Array.isArray(t)){const s=[];for(const o of t){const c=N(o,e,r,n);c!==void 0&&s.push(c)}return s}if(typeof t=="object"){if(!O(t,e,r,n))return;let s=!1;const o={};for(const c in t){if(c===_||c===A)continue;if(X.has(c)){o[c]=t[c];continue}const i=N(t[c],e,r,n);if(c==="items"&&Array.isArray(i)&&i.length===0&&t[c].length!==0){s=!0;continue}i!==void 0&&(o[c]=i),c==="paths"&&Z(i)&&q(i)}return s?void 0:o}return t}function Lt(t){return typeof t=="string"?t.split(" ").filter(Boolean):Array.isArray(t)?t.map(e=>e.toString()):[]}function jt(t,e){if(!e)return;const r=e.content;if(!r)return e;const n=Object.entries(r).flatMap(([o,c])=>o===L?[[o,c]]:[[o,c],...t.localeFolders.map(i=>[o.startsWith("/")?`/${i.toLocaleLowerCase()}${o}`:y.posix.join(t.localizationFolder,i,o),c])]),s=Object.fromEntries(n);return{...e,content:s}}async function It(t,e){if(!e)return{};const r={},n=new Set((await t.scan()).flatMap(({relativePath:s})=>{const{versionFolderPath:o}=M(s)||{},c=y.dirname(s);return o?[o,c]:c}));for(const s of n)r[$(s)]=s;return r}const m=t=>typeof t=="object"&&t!==null&&!Array.isArray(t);function Z(t){return m(t)&&Object.keys(t).length>0}function q(t){for(const e of Object.keys(t)){const r=t[e];m(r)&&Object.keys(r).length===0&&delete t[e]}}function tt(t){return t?t.split("/").filter(Boolean).some(r=>r.startsWith(".")):!1}const et=t=>{if(t&&m(t)&&("content"in t&&m(t.content)||"reunite"in t&&m(t.reunite)||"features"in t&&m(t.features)||t.teamFolders&&t.teamNamePatterns)){const e=Object.values(t.content||{});if(e.length===0)return!0;if(e.every(m))return e.every(r=>Object.values(r).every(n=>typeof n=="string"))}return!1},Ct=async t=>{if(t){if(Object.keys(t).length===0)return{};if(et(t))return rt(t);await U.panicOnContentError(`You are using an incorrect format of ${W("rbac:")} configuration. See: https://redocly.com/docs/realm/access`)}},rt=t=>{const e={...t};if(e.content){const r={};for(const n in e.content)if(e.content[n]!==void 0){const s=B(n);r[s]=e.content[n]}e.content=r}return e};function Ft(t,e){const r=t.fsPath,n=t.slug,s=[];if(Y(e)&&(r||n)){const o=[r,n].filter(v),c=H(e,o);if(c){const i=e?.teamNamePatterns?.map(u=>u.replace("{teamPathSegment}",c.teamPathSegment).replace("{projectRole}","read"))??[];s.push(...i);const f=T({content:{...K(e),...e.content}},t);s.push(...D(f))}else{const i=T(e,t);s.push(...D(i))}}else{const o=T(e,t);s.push(...D(o))}return nt(e,s)}function D(t){if(!t)return[];const e=[],r=l in t?{authenticated:t[l],anonymous:t[l]}:{};for(const[n,s]of Object.entries({...r,...t}))s.toLowerCase()!=="none"&&n!==l&&e.push(n);return e}function nt(t,e){return e.map(n=>G(t,n)??{teamName:n}).map(n=>n.projectRole&&n.projectRole!=="READ"?n.teamName?.toLowerCase().replace(n.projectRole?.toLowerCase?.()??"","read")??"":n.teamName?.toLowerCase()??"")}export{C as PROJECT_ROLES_ORDERED_BY_ACCESS_LEVEL,jt as applyL10nToRbacConfig,St as canAccessAsset,xt as canAccessFeature,O as canAccessResource,gt as canDownloadApiDefinition,nt as expandTeamsForRead,D as extractTeamsFromScopeItems,N as filterDataByAccessDeep,_t as getAuthDetailsFromCookies,Pt as getHigherRole,Ft as getRbacTeamsListForResource,T as getScopeItemsForResource,F as hasScopeAccess,et as isRbacConfigValid,Dt as isResourcePubliclyAccessible,rt as normalizeRbacConfig,Ct as parseRbacConfig,Lt as parseTeamClaimToArray,It as resolveDirectoryHashes};
1
+ import R from"path";import P from"picomatch";import"../node-crypto-polyfill.js";import{REDOCLY_TEAMS_RBAC as g,REDOCLY_ROUTE_RBAC as A}from"@redocly/config";import{MCP_ROUTE as k,PUBLIC_MCP_ROUTE as w}from"@redocly/theme/core/constants/mcp";import{ServerRoutes as B}from"../../constants/api.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as S,PUBLIC_RBAC_SCOPE_ITEM as y,RBAC_ALL_OTHER_TEAMS as l,DEFAULT_RBAC_SCOPE as L}from"../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as C,PUBLIC_API_DEFINITIONS_FOLDER as j,PUBLIC_ASSETS_FOLDER as M}from"../constants/common.js";import{MCP_CREDENTIALS_ROUTE as U}from"../constants/mcp.js";import{ANONYMOUS_AUTH_DETAILS as b}from"../constants/rbac.js";import{removeTrailingSlash as W}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as $}from"../../utils/url/remove-leading-slash.js";import{parsePathVersions as v}from"../../utils/path/parse-path-versions.js";import{reporter as Y}from"../tools/notifiers/reporter.js";import{bold as z}from"../tools/notifiers/helpers/colors.js";import{shaDirPathShort as H}from"../utils/crypto/sha-dir-path-short.js";import{isTruthy as K}from"../../utils/guards/is-truthy.js";import{canExpandConfig as G,expandRbacConfig as V,getTeamFolderDefaults as J,parseTeamFoldersTemplate as Q,parseTeamNameTemplate as X}from"./rbac-expand.js";import{getUserParamsFromCookies as Z}from"../web-server/auth.js";import{getDeeperGlobPattern as q}from"./globs.js";import{EntitlementsProvider as tt}from"../entitlements/entitlements-provider.js";const I=["NONE","READ","TRIAGE","WRITE","MAINTAIN","ADMIN"],et=new Set(["x-parsed-md-description","x-parsed-md-summary"]);function Ct(t,e){const r=I.indexOf(t.toUpperCase()),n=I.indexOf(e.toUpperCase());return r>n?t:e}const E={};function T(t,e){if(!t?.content)return y;const r=t.content,{slug:n,fsPath:o}=e;if(!n&&!o)return y;const s=a=>{const d=`slug:${a}`,p=E[d]??P(a);E[d]=p;const _=`fsPath:${a}`,D=E[_]??P($(a));return E[_]=D,!!(n&&p(n))||!!(o&&D(o))};if(ot(n||o||"")&&Object.keys(r).filter(p=>s(p)).length===0)return r[L]||y;const f=Object.keys(r).filter(a=>s(a));if(f.length==0)return y;const u=f.map(a=>P.scan(a,{tokens:!0,parts:!0}));let h=u[0];for(let a=1;a<u.length;a++)h=q(h,u[a]);return r[h.input]}function F(t,e,r){const n=r?[...e,r]:e,o=[];for(const s of n)t[s]?o.push(t[s]):t[l]&&s!==r&&o.push(t[l]);return o.some(s=>s.toLowerCase()!=="none")}function jt(t,e,r={},n=!1){if(n&&Object.keys(r).length===0)return e.isAuthenticated;const o=r.features?.[t];return o?F(o,e.teams):!0}function It(t,e){return O(t,b,e.access?.rbac||{},e.access?.requiresLogin||!1)}function O(t,e={},r={},n=!1){if(t.slug&&typeof t.slug=="string"&&Object.values(B).some(c=>{const i=c.split(":")[0].replace(/\/$/,"");return t.slug===i||t.slug?.startsWith(c)})||(t.slug===k||t.slug===w||t.slug===U)&&tt.instance().canAccessFeature("mcp"))return!0;if(n&&Object.keys(r).length===0)return!!e.isAuthenticated;const o=V(r,e.teams||[]),s=t[g]||T(o,t[A]||{});return Object.keys(s||{}).length===0?!1:Object.keys(s).length===1&&s[l]&&s[l].toLowerCase()!=="none"?!0:F(s,e?.teams||[],e?.email)}function Ft(t,e,r,n){if(!t.startsWith(j)&&!t.startsWith(C))return!0;const o=t.replace(new RegExp(`^${j}/`),"").replace(new RegExp(`^${C}/`),""),c=o==="."?"":o,i={[A]:{slug:t,fsPath:c},slug:t};return O(i,n,e,r)}function Nt(t,e,r,n,o){if(!t.startsWith(M))return!0;const s=t.match(/.*\..{64}\.([A-Fa-f0-9]{8})\.[^\.]+$/)?.[1];if(!s)return!0;const c=n[s];if(!c)return!0;const{base:i,ext:f}=R.parse(t),u=i.split(".")[0],h=f.split(".").join(""),d=c==="."?"":c,p={[A]:{slug:t,fsPath:R.posix.join(d,`${u}.${h}`)},slug:t};return O(p,o,e,r)}async function kt(t,e){const{isAuthenticated:r=!1,idpAccessToken:n,federatedAccessToken:o,federatedIdToken:s,...c}=await Z(t,e),{teams:i=[]}=c;let f;return r?f=i.filter(u=>u!==S):f=[S],{isAuthenticated:r,idpAccessToken:n,teams:f,claims:c}}function N(t,e,r={},n=!1){if(!t)return t;if(Array.isArray(t)){const o=[];for(const s of t){const c=N(s,e,r,n);c!==void 0&&o.push(c)}return o}if(typeof t=="object"){if(!O(t,e,r,n))return;let o=!1;const s={};for(const c in t){if(c===g||c===A)continue;if(et.has(c)){s[c]=t[c];continue}const i=N(t[c],e,r,n);if(c==="items"&&Array.isArray(i)&&i.length===0&&t[c].length!==0){o=!0;continue}i!==void 0&&(s[c]=i),c==="paths"&&rt(i)&&nt(i)}return o?void 0:s}return t}function wt(t){return typeof t=="string"?t.split(" ").filter(Boolean):Array.isArray(t)?t.map(e=>e.toString()):[]}function Bt(t,e){if(!e)return;const r=e.content;if(!r)return e;const n=Object.entries(r).flatMap(([s,c])=>s===L?[[s,c]]:[[s,c],...t.localeFolders.map(i=>[s.startsWith("/")?`/${i.toLocaleLowerCase()}${s}`:R.posix.join(t.localizationFolder,i,s),c])]),o=Object.fromEntries(n);return{...e,content:o}}async function Mt(t,e){if(!e)return{};const r={},n=new Set((await t.scan()).flatMap(({relativePath:o})=>{const{versionFolderPath:s}=v(o)||{},c=R.dirname(o);return s?[s,c]:c}));for(const o of n)r[H(o)]=o;return r}const m=t=>typeof t=="object"&&t!==null&&!Array.isArray(t);function rt(t){return m(t)&&Object.keys(t).length>0}function nt(t){for(const e of Object.keys(t)){const r=t[e];m(r)&&Object.keys(r).length===0&&delete t[e]}}function ot(t){return t?t.split("/").filter(Boolean).some(r=>r.startsWith(".")):!1}const st=t=>{if(t&&m(t)&&("content"in t&&m(t.content)||"reunite"in t&&m(t.reunite)||"features"in t&&m(t.features)||t.teamFolders&&t.teamNamePatterns)){const e=Object.values(t.content||{});if(e.length===0)return!0;if(e.every(m))return e.every(r=>Object.values(r).every(n=>typeof n=="string"))}return!1},Ut=async t=>{if(t){if(Object.keys(t).length===0)return{};if(st(t))return ct(t);await Y.panicOnContentError(`You are using an incorrect format of ${z("rbac:")} configuration. See: https://redocly.com/docs/realm/access`)}},ct=t=>{const e={...t};if(e.content){const r={};for(const n in e.content)if(e.content[n]!==void 0){const o=W(n);r[o]=e.content[n]}e.content=r}return e};function bt(t,e){const r=t.fsPath,n=t.slug,o=[];if(G(e)&&(r||n)){const s=[r,n].filter(K),c=Q(e,s);if(c){const i=e?.teamNamePatterns?.map(u=>u.replace("{teamPathSegment}",c.teamPathSegment).replace("{projectRole}","read"))??[];o.push(...i);const f=T({content:{...J(e),...e.content}},t);o.push(...x(f))}else{const i=T(e,t);o.push(...x(i))}}else{const s=T(e,t);o.push(...x(s))}return it(e,o)}function x(t){if(!t)return[];const e=[],r=l in t?{authenticated:t[l],anonymous:t[l]}:{};for(const[n,o]of Object.entries({...r,...t}))o.toLowerCase()!=="none"&&n!==l&&e.push(n);return e}function it(t,e){return e.map(n=>X(t,n)??{teamName:n}).map(n=>n.projectRole&&n.projectRole!=="READ"?n.teamName?.toLowerCase().replace(n.projectRole?.toLowerCase?.()??"","read")??"":n.teamName?.toLowerCase()??"")}export{I as PROJECT_ROLES_ORDERED_BY_ACCESS_LEVEL,Bt as applyL10nToRbacConfig,Nt as canAccessAsset,jt as canAccessFeature,O as canAccessResource,Ft as canDownloadApiDefinition,it as expandTeamsForRead,x as extractTeamsFromScopeItems,N as filterDataByAccessDeep,kt as getAuthDetailsFromCookies,Ct as getHigherRole,bt as getRbacTeamsListForResource,T as getScopeItemsForResource,F as hasScopeAccess,st as isRbacConfigValid,It as isResourcePubliclyAccessible,ct as normalizeRbacConfig,Ut as parseRbacConfig,wt as parseTeamClaimToArray,Mt as resolveDirectoryHashes};
@@ -1,12 +1,12 @@
1
- import"../node-crypto-polyfill.js";import{DOMParser as M}from"@xmldom/xmldom";import{SignedXml as Y}from"xml-crypto";import G from"xpath";import{deflateSync as Q,inflateSync as X}from"fflate";import{createHash as Z}from"crypto";import{ulid as ee}from"ulid";import{AuthProviderType as u,DEFAULT_TEAM_CLAIM_NAME as P}from"@redocly/config";import{AUTH_URL as te,JWT_SECRET_KEY as y}from"../constants/common.js";import{envConfig as ne}from"../config/env-config.js";import{decryptClaimValue as re}from"../utils/crypto/decrypt-claim-value.js";import{getPathPrefix as oe,withPathPrefix as se}from"@redocly/theme/core/utils";import{ServerRoutes as b}from"../../constants/api.js";import{AuthCookieNames as A,DEFAULT_AUTHENTICATED_TEAM as ae,REQUIRED_OIDC_SCOPES as v}from"../../constants/common.js";import{appendQueryParams as ie}from"../../utils/url/append-query-params.js";import{parsePreviewUrl as N}from"../../utils/url/parse-preview-url.js";import{logger as ce}from"../tools/notifiers/logger.js";import{randomString as ue}from"../utils/crypto/random-string.js";import{randomUUID as U}from"../utils/crypto/random-uuid.js";import{AlgorithmTypes as h,JwtTokenExpired as de}from"./jwt/types.js";import*as d from"./jwt/jwt.js";import{parseTeamClaimToArray as le}from"../utils/index.js";import{arrayBufferToBase64 as me,decodeBase64 as j,encodeBase64URL as pe,urlSafeBase64 as V}from"./jwt/encode.js";import{formatSamlCertificate as fe}from"./utils/format-saml-certificate.js";function $(e){return e?.type===u.OIDC}function he(e){return e?.type===u.SAML2}async function rt(e,t){if($(t))return ye(e,t);if(he(t))return we(e,t)}async function ye(e,t){const n=await q(e,t),r=new Set((t.scopes||[]).concat(v)),o=t.authorizationRequestCustomParams||{};return{type:u.OIDC,idpId:e,name:"OAuth provider",authorizationEndpoint:n.authorization_endpoint,clientId:t.clientId,responseType:"code",scope:Array.from(r).join(" "),extraParams:o,pkce:t.pkce}}function we(e,t){return{type:u.SAML2,idpId:e,name:"SAML2 provider",ssoUrl:t.ssoUrl,issuerId:t.issuerId,entityId:t.entityId||t.issuerId}}function B(e){return Array.from(new Set((e.scopes||[]).concat(v))).join(" ")}async function H(e,t,n){return await fetch(e,{method:"POST",body:new URLSearchParams({client_id:t.clientId,...t.clientSecret?{client_secret:t.clientSecret}:{},...n}).toString(),headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"}}).then(r=>r.json())}async function ot(e,t,n,r,o={}){return await H(e,r,{scope:B(r),code:t,redirect_uri:F(n),grant_type:"authorization_code",...o})}async function st(e,t,n){return await H(e,n,{scope:B(n),grant_type:"refresh_token",refresh_token:t})}function Se(e,{authorizationEndpoint:t,clientId:n,responseType:r,scope:o,extraParams:s,idpId:a,pkce:l},p,x,f){if(!t||!n||!r||!o)return{loginUrl:void 0};const i=new URL(t),w=f?.redirectUriOverride??`${e}${se(b.OIDC_CALLBACK)}`,g={state:U(),idpId:a,redirectUri:w,redirectTo:p,branch:f?.branchOverride??_e(e),inviteCode:x,source:f?.sourceOverride??"portal",uiLocales:f?.uiLocales},S={};if(l){const m=V(ue(50)),k=V(Z("sha256").update(m).digest("base64")),I="S256";i.searchParams.append("code_challenge",k),i.searchParams.append("code_challenge_method",I),S.code_verifier={value:m,options:{secure:!0,httpOnly:!0,expires:new Date(Date.now()+1e3*60*10),path:oe()||"/"}}}i.searchParams.append("client_id",n),i.searchParams.append("scope",o),i.searchParams.append("response_type",r),i.searchParams.append("redirect_uri",F(w)),i.searchParams.append("state",pe(JSON.stringify(g))),f?.uiLocales&&i.searchParams.append("ui_locales",f.uiLocales);for(const m in s)s[m]!==void 0&&i.searchParams.append(m,s[m]);return{loginUrl:i.toString(),cookies:S}}function at(e,t,n,r){const o=new URL(e);return o.searchParams.append("post_logout_redirect_uri",t),r&&o.searchParams.append("state",r),o.searchParams.append("id_token_hint",n),o.toString()}async function it(e){const t=Math.floor(Date.now()/1e3),n=t+(e.ttlSec??600);return d.sign({type:"mcp_auth_code",client_id:e.clientId,redirect_uri:e.redirectUri,id_token:e.idToken,...e.idpId?{idp_id:e.idpId}:{},...e.idpAccessTokenEnc?{idp_access_token_enc:e.idpAccessTokenEnc}:{},...e.idpRefreshTokenEnc?{idp_refresh_token_enc:e.idpRefreshTokenEnc}:{},...e.codeChallenge?{code_challenge:e.codeChallenge}:{},...e.codeChallengeMethod?{code_challenge_method:e.codeChallengeMethod}:{},iat:t,exp:n},y,h.HS256)}async function ct(e){await d.verify(e,y,h.HS256);const{payload:t}=d.decode(e);if(t.type!=="mcp_auth_code")throw new Error("Invalid authorization code type");if(!t.client_id||!t.redirect_uri)throw new Error("Authorization code missing required claims");if(typeof t.exp=="number"&&Date.now()>=t.exp*1e3)throw new Error("Authorization code expired");return t}async function ut(e){const t=Math.floor(Date.now()/1e3);return d.sign({type:"mcp_refresh_token",client_id:e.clientId,...e.idpId?{idp_id:e.idpId}:{},claims:e.claims,...e.idpAccessTokenEnc?{idp_access_token_enc:e.idpAccessTokenEnc}:{},...e.idpRefreshTokenEnc?{idp_refresh_token_enc:e.idpRefreshTokenEnc}:{},session_exp:e.sessionExp,iat:t,exp:e.sessionExp},y,h.HS256)}async function dt(e){await d.verify(e,y,h.HS256);const{payload:t}=d.decode(e);if(t.type!=="mcp_refresh_token")throw new Error("Invalid refresh token type");if(!t.client_id||typeof t.claims!="object"||t.claims===null)throw new Error("Refresh token missing required claims");if(typeof t.session_exp!="number")throw new Error("Refresh token missing session expiry");return t}function lt(e){const t=e||ee(),n=t.startsWith("mcp_")?t:`mcp_${t}`;return{id:n,object:"mcpSession",uri:`urn:redocly:realm:mcp:session:${n}`}}function F(e){const t=N(e);if(!t)return e;const n=Ae(t.hostname);if(n)return t.hostname=`previewauth--${n.previewBranch}${n.after}`,z(e,t);const r=W(t.hostname);return r?(t.hostname=`${r.projectSlug}.previewauth.${r.after}`,z(e,t)):e}function _e(e){const t=N(e);if(t)return W(t.hostname)?.previewBranch}function z(e,t){return e.replace(/^https?:\/\/[^/?#]+/i,`${t.protocol}//${t.host}`)}function W(e){const t=e.split(".preview.",2);if(t.length<2)return null;const[n,r]=t,o=n.indexOf("--");if(o===-1)return null;const s=n.slice(0,o),a=n.slice(o+2);return!s||!a||a.includes(".")?null:{projectSlug:s,previewBranch:a,after:r}}function Ae(e){const t=e.indexOf("."),n=t===-1?e:e.slice(0,t);if(!n.startsWith("preview-"))return null;const r=n.indexOf("--");if(r===-1)return null;const o=n.slice(r+2);if(!o)return null;const s=t===-1?"":e.slice(t);return{previewBranch:o,after:s}}function xe(e){return e.type===u.OIDC}function ge(e){return e.type===u.SAML2}function mt(e,t,n,r,o){return xe(e)?Se(t,e,n,r,{uiLocales:o}):ge(e)?ke(t,e,n,r,o):{}}function ke(e,t,n,r,o){const a=`<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
1
+ import"../node-crypto-polyfill.js";import{DOMParser as M}from"@xmldom/xmldom";import{SignedXml as Y}from"xml-crypto";import G from"xpath";import{deflateSync as Q,inflateSync as X}from"fflate";import{createHash as Z}from"crypto";import{ulid as ee}from"ulid";import{AuthProviderType as u,DEFAULT_TEAM_CLAIM_NAME as P}from"@redocly/config";import{AUTH_URL as te,JWT_SECRET_KEY as y}from"../constants/common.js";import{envConfig as ne}from"../config/env-config.js";import{decryptClaimValue as re}from"../utils/crypto/decrypt-claim-value.js";import{getPathPrefix as oe,withPathPrefix as se}from"@redocly/theme/core/utils";import{ServerRoutes as v}from"../../constants/api.js";import{AuthCookieNames as A,DEFAULT_AUTHENTICATED_TEAM as ae,REQUIRED_OIDC_SCOPES as N}from"../../constants/common.js";import{appendQueryParams as ie}from"../../utils/url/append-query-params.js";import{parsePreviewUrl as b}from"../../utils/url/parse-preview-url.js";import{logger as ce}from"../tools/notifiers/logger.js";import{randomString as ue}from"../utils/crypto/random-string.js";import{randomUUID as U}from"../utils/crypto/random-uuid.js";import{AlgorithmTypes as h,JwtTokenExpired as de}from"./jwt/types.js";import*as d from"./jwt/jwt.js";import{parseTeamClaimToArray as le}from"../utils/index.js";import{arrayBufferToBase64 as me,decodeBase64 as j,encodeBase64URL as pe,urlSafeBase64 as V}from"./jwt/encode.js";import{formatSamlCertificate as fe}from"./utils/format-saml-certificate.js";function $(e){return e?.type===u.OIDC}function he(e){return e?.type===u.SAML2}async function rt(e,t){if($(t))return ye(e,t);if(he(t))return we(e,t)}async function ye(e,t){const n=await q(e,t),r=new Set((t.scopes||[]).concat(N)),o=t.authorizationRequestCustomParams||{};return{type:u.OIDC,idpId:e,name:"OAuth provider",authorizationEndpoint:n.authorization_endpoint,clientId:t.clientId,responseType:"code",scope:Array.from(r).join(" "),extraParams:o,pkce:t.pkce}}function we(e,t){return{type:u.SAML2,idpId:e,name:"SAML2 provider",ssoUrl:t.ssoUrl,issuerId:t.issuerId,entityId:t.entityId||t.issuerId}}function B(e){return Array.from(new Set((e.scopes||[]).concat(N))).join(" ")}async function H(e,t,n){return await fetch(e,{method:"POST",body:new URLSearchParams({client_id:t.clientId,...t.clientSecret?{client_secret:t.clientSecret}:{},...n}).toString(),headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"}}).then(r=>r.json())}async function ot(e,t,n,r,o={}){return await H(e,r,{scope:B(r),code:t,redirect_uri:F(n),grant_type:"authorization_code",...o})}async function st(e,t,n){return await H(e,n,{scope:B(n),grant_type:"refresh_token",refresh_token:t})}function Se(e,{authorizationEndpoint:t,clientId:n,responseType:r,scope:o,extraParams:s,idpId:a,pkce:l},p,x,f){if(!t||!n||!r||!o)return{loginUrl:void 0};const i=new URL(t),w=f?.redirectUriOverride??`${e}${se(v.OIDC_CALLBACK)}`,g={state:U(),idpId:a,redirectUri:w,redirectTo:p,branch:f?.branchOverride??_e(e),inviteCode:x,source:f?.sourceOverride??"portal",uiLocales:f?.uiLocales},S={};if(l){const m=V(ue(50)),k=V(Z("sha256").update(m).digest("base64")),I="S256";i.searchParams.append("code_challenge",k),i.searchParams.append("code_challenge_method",I),S.code_verifier={value:m,options:{secure:!0,httpOnly:!0,expires:new Date(Date.now()+1e3*60*10),path:oe()||"/"}}}i.searchParams.append("client_id",n),i.searchParams.append("scope",o),i.searchParams.append("response_type",r),i.searchParams.append("redirect_uri",F(w)),i.searchParams.append("state",pe(JSON.stringify(g))),f?.uiLocales&&i.searchParams.append("ui_locales",f.uiLocales);for(const m in s)s[m]!==void 0&&i.searchParams.append(m,s[m]);return{loginUrl:i.toString(),cookies:S}}function at(e,t,n,r){const o=new URL(e);return o.searchParams.append("post_logout_redirect_uri",t),r&&o.searchParams.append("state",r),o.searchParams.append("id_token_hint",n),o.toString()}async function it(e){const t=Math.floor(Date.now()/1e3),n=t+(e.ttlSec??600);return d.sign({type:"mcp_auth_code",client_id:e.clientId,redirect_uri:e.redirectUri,id_token:e.idToken,...e.idpId?{idp_id:e.idpId}:{},...e.idpAccessTokenEnc?{idp_access_token_enc:e.idpAccessTokenEnc}:{},...e.idpRefreshTokenEnc?{idp_refresh_token_enc:e.idpRefreshTokenEnc}:{},...e.codeChallenge?{code_challenge:e.codeChallenge}:{},...e.codeChallengeMethod?{code_challenge_method:e.codeChallengeMethod}:{},iat:t,exp:n},y,h.HS256)}async function ct(e){await d.verify(e,y,h.HS256);const{payload:t}=d.decode(e);if(t.type!=="mcp_auth_code")throw new Error("Invalid authorization code type");if(!t.client_id||!t.redirect_uri)throw new Error("Authorization code missing required claims");if(typeof t.exp=="number"&&Date.now()>=t.exp*1e3)throw new Error("Authorization code expired");return t}async function ut(e){const t=Math.floor(Date.now()/1e3);return d.sign({type:"mcp_refresh_token",client_id:e.clientId,...e.idpId?{idp_id:e.idpId}:{},claims:e.claims,...e.idpAccessTokenEnc?{idp_access_token_enc:e.idpAccessTokenEnc}:{},...e.idpRefreshTokenEnc?{idp_refresh_token_enc:e.idpRefreshTokenEnc}:{},session_exp:e.sessionExp,iat:t,exp:e.sessionExp},y,h.HS256)}async function dt(e){await d.verify(e,y,h.HS256);const{payload:t}=d.decode(e);if(t.type!=="mcp_refresh_token")throw new Error("Invalid refresh token type");if(!t.client_id||typeof t.claims!="object"||t.claims===null)throw new Error("Refresh token missing required claims");if(typeof t.session_exp!="number")throw new Error("Refresh token missing session expiry");return t}function lt(e){const t=e||ee(),n=t.startsWith("mcp_")?t:`mcp_${t}`;return{id:n,object:"mcpSession",uri:`urn:redocly:realm:mcp:session:${n}`}}function F(e){const t=b(e);if(!t)return e;const n=Ae(t.hostname);if(n)return t.hostname=`previewauth--${n.previewBranch}${n.after}`,z(e,t);const r=W(t.hostname);return r?(t.hostname=`${r.projectSlug}.previewauth.${r.after}`,z(e,t)):e}function _e(e){const t=b(e);if(t)return W(t.hostname)?.previewBranch}function z(e,t){return e.replace(/^https?:\/\/[^/?#]+/i,`${t.protocol}//${t.host}`)}function W(e){const t=e.split(".preview.",2);if(t.length<2)return null;const[n,r]=t,o=n.indexOf("--");if(o===-1)return null;const s=n.slice(0,o),a=n.slice(o+2);return!s||!a||a.includes(".")?null:{projectSlug:s,previewBranch:a,after:r}}function Ae(e){const t=e.indexOf("."),n=t===-1?e:e.slice(0,t);if(!n.startsWith("preview-"))return null;const r=n.indexOf("--");if(r===-1)return null;const o=n.slice(r+2);if(!o)return null;const s=t===-1?"":e.slice(t);return{previewBranch:o,after:s}}function xe(e){return e.type===u.OIDC}function ge(e){return e.type===u.SAML2}function mt(e,t,n,r,o){return xe(e)?Se(t,e,n,r,{uiLocales:o}):ge(e)?ke(t,e,n,r,o):{}}function ke(e,t,n,r,o){const a=`<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
2
2
  xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
3
3
  Version="2.0"
4
4
  ID="_${U()}"
5
5
  IssueInstant="${new Date().toISOString()}"
6
- AssertionConsumerServiceURL="${e}${b.SAML_CALLBACK}"
6
+ AssertionConsumerServiceURL="${e}${v.SAML_CALLBACK}"
7
7
  AttributeConsumingServiceIndex="0">
8
8
  <saml:Issuer>${t.entityId}</saml:Issuer>
9
9
  <samlp:NameIDPolicy
10
10
  AllowCreate="true"
11
11
  Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
12
- </samlp:AuthnRequest>`,l=Ie(a);return{loginUrl:ie(t.ssoUrl,{SAMLRequest:l,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:n,inviteCode:r,source:"portal",uiLocales:o})})}}function Ie(e){return me(Q(new TextEncoder().encode(e)).buffer)}function pt(e){const t=j(e);if(t.startsWith("<samlp:Response")||t.indexOf("<saml2p:Response")>-1)return t;const n=X(new Uint8Array(atob(e).split("").map(r=>r.charCodeAt(0))));return new TextDecoder().decode(n)}function ft(e){try{return JSON.parse(j(e||""))}catch{throw new Error("Invalid OAuth2 state")}}function ht(e){const t=new M().parseFromString(e,"application/xml"),r=c(t,"//*[local-name(.)='StatusCode']/@Value")[0]?.nodeValue?.endsWith("Success")||!1,s=c(t,"//*[local-name(.)='Response']/@Destination")[0]?.nodeValue||"",a=c(t,"//*[local-name(.)='Assertion']//*[local-name(.)='Issuer']/text()")[0],l=a&&a.nodeValue||void 0,p=c(t,"//*[local-name(.)='Audience']/text()")[0],x=p&&p.nodeValue||void 0,i=c(t,"//*[local-name(.)='Assertion']//*[local-name(.)='X509Certificate']/text()")[0]?.nodeValue||"",w=c(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/text()")[0],g=w&&w.nodeValue||"",S=c(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/@Format")[0],m=S&&S.nodeValue||"",k=c(t,"//*[local-name(.)='Conditions']/@NotOnOrAfter")[0],I=Te(k),C={},R=c(t,"//*[local-name(.)='AttributeStatement']//*[local-name(.)='Attribute']");if(R.length)for(const L of R){const O=c(L,"./@Name")[0];if(O.nodeValue){const D=c(L,"./*[local-name(.)='AttributeValue']/text()")[0];D?.nodeValue&&(C[O.nodeValue]=D.nodeValue)}}return{uid:g,success:r,expiresAt:I,issuerId:l,entityId:x,attrs:C,cert:i,nameFormat:m,destination:s}}function Te(e){const t=typeof e?.nodeValue=="string"&&T(Date.parse(e.nodeValue)),n=T(Date.now()),r=T(Date.now()+720*60*1e3);return t?t>n&&t<r?r:t:n}function T(e){return Math.floor(e/1e3)}const E={},_={jwks:{}};async function q(e,t){if(!E[e]){const n=t.configurationUrl?await J(t.configurationUrl):t.configuration;E[e]=Ee()?Re(n):n}return E[e]}function Ee(){const e=ne.REDOCLY_ENFORCE_RESIDENCY;return!!e&&e.includes("host.docker.internal")}const Ce=["authorization_endpoint","end_session_endpoint"];function Re(e){if(typeof e!="object"||e===null)return e;const t={...e};for(const n of Object.keys(t)){if(Ce.includes(String(n)))continue;const r=t[n];typeof r=="string"&&r.includes("://localhost")&&(t[n]=r.replace("://localhost","://host.docker.internal"))}return t}async function Le(e){for(const t of Object.keys(e)){const n=e[t];if(!$(n))continue;const r=await q(t,n);if(r.jwks_uri){const o=await J(r.jwks_uri);for(const s of o.keys)_.jwks[s.kid]={...s,idpId:t}}}}async function J(e){return fetch(e,{headers:{Accept:"application/json"}}).then(t=>t.json())}async function yt(e){return fetch(`${te}/oidc/userinfo`,{headers:{Accept:"application/json",Authorization:`Bearer ${e}`}}).then(t=>t.status===200?t.json():void 0).catch(()=>{})}function wt(e){if(!e.configurationUrl)return!1;const t=new URL(e.configurationUrl);return["localhost","127.0.0.1","blueharvest.cloud","bhstage.cloud","cloud.redocly.com","beta.redocly.com","cloud.eu.redocly.com","beta.eu.redocly.com","cba.au.redocly.com"].some(r=>Oe(t.hostname,r))}function Oe(e,t){return e===t||e.endsWith(`.${t}`)}async function St(e,t){const n=new M().parseFromString(e,"application/xml"),r=c(n,"//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0];if(!r)throw new Error("Cannot find Signature in the SAML response");const o=fe(t),s=new Y({publicCert:o});s.loadSignature(r);try{return s.checkSignature(e)}catch{return!1}}function _t(e,t,n,r){t==="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"&&(e=n["http://schemas.microsoft.com/identity/claims/objectidentifier"]);let o;(t==="urn:oasis:names:tc:SAML:2.0:nameid-format:email"||t==="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")&&(o=e),t==="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"&&e?.match(/.+@.+/)&&(o=e);const s=n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],a=s?.match(/.+@.+/);return o=o||n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]||(a?s:void 0),o=o?.toLowerCase(),{sub:e,given_name:n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"],family_name:n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"],name:n["http://schemas.microsoft.com/identity/claims/displayname"]||s,email:o,email_verified:!0,teams:r?le(n[r]):[]}}function K(e,t={}){return e.map(n=>t[n]||n)}async function At(e,t){if(!t)return{};const n=t[A.AUTHORIZATION];if(!n)return{};try{const r=d.decode(n);if(r.header.alg===h.RS256){_.jwks[r.header.kid]===void 0&&await Le(e);const p=_.jwks[r.header.kid];if(!p)return _.jwks[r.header.kid]=null,{};await d.verify(n,p,h.RS256)}else await d.verify(n,y,h.HS256);const o=r.payload.idpId||_.jwks[r.header.kid]?.idpId,s=e[o]||{},a=Pe(s),l=Me(s);return{...r.payload,email:r.payload.email?.toLowerCase(),idpId:o,teams:Array.from(new Set([...K(r.payload.teams||[],l),..."defaultTeams"in s&&s.defaultTeams||[],...K("teamsClaimName"in s&&r.payload[a||""]||[],l),ae])),name:De(r.payload),isAuthenticated:!0,idpAccessToken:re(r.payload.idp_access_token,y)||t[A.IDP_ACCESS_TOKEN],federatedAccessToken:t[A.FEDERATED_ACCESS_TOKEN],federatedIdToken:t[A.FEDERATED_ID_TOKEN],authCookie:n}}catch(r){r instanceof de||ce.error("Malformed JWT token: %s",r.message)}return{}}function De(e){return(e.firstName&&e.lastName?`${e.firstName} ${e.lastName}`:e.name||e.given_name||e.firstName||e.lastName)||e.email}function Me(e){switch(e.type){case u.SAML2:return e.teamsAttributeMap;case u.OIDC:return e.teamsClaimMap;default:return}}function Pe(e){switch(e.type){case u.SAML2:return e.teamsAttributeName??P;case u.OIDC:return e.teamsClaimName;default:return P}}function c(e,t){return G.select(t,e)||[]}export{mt as buildLoginUrl,Se as buildOidcLoginUrl,at as buildOidcLogoutUrl,ke as buildSAML2LoginUrl,it as createMcpAuthorizationCode,ut as createMcpRefreshToken,lt as createMcpSessionResource,pt as decodeSamlResponse,Le as discoverJwks,Ie as encodeSAML2,_t as extractUserClaims,rt as getAuthProviderLoginParams,ye as getOidcLoginParams,q as getOidcMetadata,yt as getRedoclyTokenPayload,we as getSaml2LoginParams,At as getUserParamsFromCookies,De as getUsernameFromPayload,$ as isOidcProviderConfig,wt as isRedoclySso,he as isSaml2ProviderConfig,ot as oidcExchangeCodeForToken,_ as oidcJwksCache,E as oidcMetadataCache,st as oidcRefreshTokenGrant,ft as parseOidcState,_e as parsePreviewBranch,ht as parseSamlResponse,F as rewritePreviewAuthRedirectUri,ct as verifyMcpAuthorizationCode,dt as verifyMcpRefreshToken,St as verifySAMLResponse};
12
+ </samlp:AuthnRequest>`,l=Ie(a);return{loginUrl:ie(t.ssoUrl,{SAMLRequest:l,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:n,inviteCode:r,source:"portal",uiLocales:o})})}}function Ie(e){return me(Q(new TextEncoder().encode(e)).buffer)}function pt(e){const t=j(e);if(t.startsWith("<samlp:Response")||t.indexOf("<saml2p:Response")>-1)return t;const n=X(new Uint8Array(atob(e).split("").map(r=>r.charCodeAt(0))));return new TextDecoder().decode(n)}function ft(e){try{return JSON.parse(j(e||""))}catch{throw new Error("Invalid OAuth2 state")}}function ht(e){const t=new M().parseFromString(e,"application/xml"),r=c(t,"//*[local-name(.)='StatusCode']/@Value")[0]?.nodeValue?.endsWith("Success")||!1,s=c(t,"//*[local-name(.)='Response']/@Destination")[0]?.nodeValue||"",a=c(t,"//*[local-name(.)='Assertion']//*[local-name(.)='Issuer']/text()")[0],l=a&&a.nodeValue||void 0,p=c(t,"//*[local-name(.)='Audience']/text()")[0],x=p&&p.nodeValue||void 0,i=c(t,"//*[local-name(.)='Assertion']//*[local-name(.)='X509Certificate']/text()")[0]?.nodeValue||"",w=c(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/text()")[0],g=w&&w.nodeValue||"",S=c(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/@Format")[0],m=S&&S.nodeValue||"",k=c(t,"//*[local-name(.)='Conditions']/@NotOnOrAfter")[0],I=Te(k),C={},R=c(t,"//*[local-name(.)='AttributeStatement']//*[local-name(.)='Attribute']");if(R.length)for(const L of R){const O=c(L,"./@Name")[0];if(O.nodeValue){const D=c(L,"./*[local-name(.)='AttributeValue']/text()")[0];D?.nodeValue&&(C[O.nodeValue]=D.nodeValue)}}return{uid:g,success:r,expiresAt:I,issuerId:l,entityId:x,attrs:C,cert:i,nameFormat:m,destination:s}}function Te(e){const t=typeof e?.nodeValue=="string"&&T(Date.parse(e.nodeValue)),n=T(Date.now()),r=T(Date.now()+720*60*1e3);return t?t>n&&t<r?r:t:n}function T(e){return Math.floor(e/1e3)}const E={},_={jwks:{}};async function q(e,t){if(!E[e]){const n=t.configurationUrl?await J(t.configurationUrl):t.configuration;E[e]=Ee()?Re(n):n}return E[e]}function Ee(){const e=ne.REDOCLY_ENFORCE_RESIDENCY;return!!e&&e.includes("host.docker.internal")}const Ce=["authorization_endpoint","end_session_endpoint"];function Re(e){if(typeof e!="object"||e===null)return e;const t={...e};for(const n of Object.keys(t)){if(Ce.includes(String(n)))continue;const r=t[n];typeof r=="string"&&r.includes("://localhost")&&(t[n]=r.replace("://localhost","://host.docker.internal"))}return t}async function Le(e){for(const t of Object.keys(e)){const n=e[t];if(!$(n))continue;const r=await q(t,n);if(r.jwks_uri){const o=await J(r.jwks_uri);for(const s of o.keys)_.jwks[s.kid]={...s,idpId:t}}}}async function J(e){return fetch(e,{headers:{Accept:"application/json"}}).then(t=>t.json())}async function yt(e){return fetch(`${te}/oidc/userinfo`,{headers:{Accept:"application/json",Authorization:`Bearer ${e}`}}).then(t=>t.status===200?t.json():void 0).catch(()=>{})}function wt(e){if(!e.configurationUrl)return!1;const t=new URL(e.configurationUrl);return["localhost","127.0.0.1","blueharvest.cloud","bhstage.cloud","cloud.redocly.com","beta.redocly.com","cloud.eu.redocly.com","beta.eu.redocly.com"].some(r=>Oe(t.hostname,r))}function Oe(e,t){return e===t||e.endsWith(`.${t}`)}async function St(e,t){const n=new M().parseFromString(e,"application/xml"),r=c(n,"//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0];if(!r)throw new Error("Cannot find Signature in the SAML response");const o=fe(t),s=new Y({publicCert:o});s.loadSignature(r);try{return s.checkSignature(e)}catch{return!1}}function _t(e,t,n,r){t==="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"&&(e=n["http://schemas.microsoft.com/identity/claims/objectidentifier"]);let o;(t==="urn:oasis:names:tc:SAML:2.0:nameid-format:email"||t==="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")&&(o=e),t==="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"&&e?.match(/.+@.+/)&&(o=e);const s=n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],a=s?.match(/.+@.+/);return o=o||n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]||(a?s:void 0),o=o?.toLowerCase(),{sub:e,given_name:n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"],family_name:n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"],name:n["http://schemas.microsoft.com/identity/claims/displayname"]||s,email:o,email_verified:!0,teams:r?le(n[r]):[]}}function K(e,t={}){return e.map(n=>t[n]||n)}async function At(e,t){if(!t)return{};const n=t[A.AUTHORIZATION];if(!n)return{};try{const r=d.decode(n);if(r.header.alg===h.RS256){_.jwks[r.header.kid]===void 0&&await Le(e);const p=_.jwks[r.header.kid];if(!p)return _.jwks[r.header.kid]=null,{};await d.verify(n,p,h.RS256)}else await d.verify(n,y,h.HS256);const o=r.payload.idpId||_.jwks[r.header.kid]?.idpId,s=e[o]||{},a=Pe(s),l=Me(s);return{...r.payload,email:r.payload.email?.toLowerCase(),idpId:o,teams:Array.from(new Set([...K(r.payload.teams||[],l),..."defaultTeams"in s&&s.defaultTeams||[],...K("teamsClaimName"in s&&r.payload[a||""]||[],l),ae])),name:De(r.payload),isAuthenticated:!0,idpAccessToken:re(r.payload.idp_access_token,y)||t[A.IDP_ACCESS_TOKEN],federatedAccessToken:t[A.FEDERATED_ACCESS_TOKEN],federatedIdToken:t[A.FEDERATED_ID_TOKEN],authCookie:n}}catch(r){r instanceof de||ce.error("Malformed JWT token: %s",r.message)}return{}}function De(e){return(e.firstName&&e.lastName?`${e.firstName} ${e.lastName}`:e.name||e.given_name||e.firstName||e.lastName)||e.email}function Me(e){switch(e.type){case u.SAML2:return e.teamsAttributeMap;case u.OIDC:return e.teamsClaimMap;default:return}}function Pe(e){switch(e.type){case u.SAML2:return e.teamsAttributeName??P;case u.OIDC:return e.teamsClaimName;default:return P}}function c(e,t){return G.select(t,e)||[]}export{mt as buildLoginUrl,Se as buildOidcLoginUrl,at as buildOidcLogoutUrl,ke as buildSAML2LoginUrl,it as createMcpAuthorizationCode,ut as createMcpRefreshToken,lt as createMcpSessionResource,pt as decodeSamlResponse,Le as discoverJwks,Ie as encodeSAML2,_t as extractUserClaims,rt as getAuthProviderLoginParams,ye as getOidcLoginParams,q as getOidcMetadata,yt as getRedoclyTokenPayload,we as getSaml2LoginParams,At as getUserParamsFromCookies,De as getUsernameFromPayload,$ as isOidcProviderConfig,wt as isRedoclySso,he as isSaml2ProviderConfig,ot as oidcExchangeCodeForToken,_ as oidcJwksCache,E as oidcMetadataCache,st as oidcRefreshTokenGrant,ft as parseOidcState,_e as parsePreviewBranch,ht as parseSamlResponse,F as rewritePreviewAuthRedirectUri,ct as verifyMcpAuthorizationCode,dt as verifyMcpRefreshToken,St as verifySAMLResponse};
@@ -1 +1 @@
1
- import{logger as n}from"../tools/notifiers/logger.js";import{envConfig as o}from"../config/env-config.js";import{runApiRoutesWorker as m}from"../api-routes/run-api-routes-worker.js";import{MCP_CREDENTIALS_HANDLER_ID as i,MCP_DOCS_SERVER_HANDLER_ID as u}from"../plugins/mcp/index.js";import{handleMcpRequest as d}from"../plugins/mcp/handlers/handle-mcp-request.js";async function l(r,s,a){try{const e=n.startTiming(),t=r.requestHandlerId===u||r.requestHandlerId===i?await d(r,s,a):await m(r,s,a);return n.infoTime(e,`API request handled "${new URL(s.req.url).pathname}" with status "${t.status}" and content type "${t.headers?.get("content-type")}"`),t.headers.set("X-Source","REALM_API_FUNCTION"),t}catch(e){return n.error(`[${r.requestHandlerId}] ${e.stack}`),e.name==="RequestBodySizeLimitError"?s.json({message:e.message},{status:413}):e.name==="ResponseSizeLimitError"?s.json({message:e.message},{status:500}):e.name==="MemoryUsageLimitError"?s.json({message:e.message},{status:502}):e.name==="TimeoutExceededError"?s.json({message:e.message},{status:504}):o.isDevelopMode?s.json({message:e.message},{status:500}):s.json({message:"Internal server error"},{status:500})}}export{l as handleApiRouteRequest};
1
+ import{logger as n}from"../tools/notifiers/logger.js";import{envConfig as o}from"../config/env-config.js";import{runApiRoutesWorker as m}from"../api-routes/run-api-routes-worker.js";import{MCP_CREDENTIALS_HANDLER_ID as i,MCP_DOCS_SERVER_HANDLER_ID as u}from"../constants/mcp.js";import{handleMcpRequest as d}from"../plugins/mcp/handlers/handle-mcp-request.js";async function l(r,s,a){try{const e=n.startTiming(),t=r.requestHandlerId===u||r.requestHandlerId===i?await d(r,s,a):await m(r,s,a);return n.infoTime(e,`API request handled "${new URL(s.req.url).pathname}" with status "${t.status}" and content type "${t.headers?.get("content-type")}"`),t.headers.set("X-Source","REALM_API_FUNCTION"),t}catch(e){return n.error(`[${r.requestHandlerId}] ${e.stack}`),e.name==="RequestBodySizeLimitError"?s.json({message:e.message},{status:413}):e.name==="ResponseSizeLimitError"?s.json({message:e.message},{status:500}):e.name==="MemoryUsageLimitError"?s.json({message:e.message},{status:502}):e.name==="TimeoutExceededError"?s.json({message:e.message},{status:504}):o.isDevelopMode?s.json({message:e.message},{status:500}):s.json({message:"Internal server error"},{status:500})}}export{l as handleApiRouteRequest};
@@ -1 +1 @@
1
- import{context as s,SpanStatusCode as n,trace as a}from"@opentelemetry/api";import{envConfig as o}from"../../config/env-config.js";const c=t=>{const e=a?.getSpan(s.active());return t instanceof Error&&"name"in t&&t.name==="URIError"?(e&&(e.setStatus({code:n.OK}),e.end()),new Response("Malformed URL",{status:400})):t instanceof SyntaxError?(e&&(e.setStatus({code:n.OK}),e.end()),new Response("Invalid JSON",{status:400})):(e&&(e.setStatus({code:n.ERROR,message:t.message}),e.recordException(t),e.end()),o.isDevelopMode&&t?.name==="PageMissingDefaultExportError"?new Response(t.message,{status:200}):new Response("Internal Server Error",{status:500}))};export{c as errorHandler};
1
+ import{context as s,SpanStatusCode as n,trace as a}from"@opentelemetry/api";import{HTTPException as o}from"hono/http-exception";import{envConfig as i}from"../../config/env-config.js";const u=t=>{const e=a?.getSpan(s.active());return t instanceof Error&&"name"in t&&t.name==="URIError"?(e&&(e.setStatus({code:n.OK}),e.end()),new Response("Malformed URL",{status:400})):t instanceof SyntaxError?(e&&(e.setStatus({code:n.OK}),e.end()),new Response("Invalid JSON",{status:400})):t instanceof o&&t.status<500?(e&&(e.setStatus({code:n.OK}),e.end()),t.getResponse()):(e&&(e.setStatus({code:n.ERROR,message:t.message}),e.recordException(t),e.end()),i.isDevelopMode&&t?.name==="PageMissingDefaultExportError"?new Response(t.message,{status:200}):new Response("Internal Server Error",{status:500}))};export{u as errorHandler};
@@ -1 +1 @@
1
- function i(o,n){if(!o?.trim()||!n?.length)return;const e=o.split("/").filter(Boolean)[0];return e?n.find(t=>t.code.toLowerCase()===e.toLowerCase())?.code:void 0}function a(o){const{localePrefixParam:n,l10n:e}=o;return(e?i(n,e.locales):void 0)??e?.defaultLocale}export{a as resolveUiLocalesForIdpLogin};
1
+ import{DEFAULT_LOCALE_PLACEHOLDER as i}from"../../../../constants/common.js";function c(o,n){if(!o?.trim()||!n?.length)return;const e=o.split("/").filter(Boolean)[0];return e?n.find(r=>r.code.toLowerCase()===e.toLowerCase())?.code:void 0}function l(o){const{localePrefixParam:n,l10n:e}=o,r=(e?c(n,e.locales):void 0)??e?.defaultLocale;return r===i?void 0:r}export{l as resolveUiLocalesForIdpLogin};
@@ -1 +1 @@
1
- import{serveStatic as R}from"hono/serve-static";import{withPathPrefix as i,withoutPathPrefix as H}from"@redocly/theme/core/utils";import{ServerRoutes as l}from"../../../constants/api.js";import{PUBLIC_STATIC_FOLDER as c}from"../../constants/common.js";import{envConfig as L}from"../../config/env-config.js";import{authMiddleware as C}from"../middleware/authMiddleware.js";import{ensureSearchData as I}from"../middleware/ensureSearchData.js";import{dynamicMiddleware as g}from"../middleware/dynamic-middleware/dynamic-middleware.js";import{installRoutes as D}from"../../plugins/dev-onboarding/api/routes/index.js";import{installSkillsRoutes as h}from"./skills/skills-routes.js";import{authorizeHandler as P,oidcCallbackHandler as N,logoutHandler as s,postLogoutHandler as w,idpLoginHandler as M,redoclyLoginCallbackHandler as B,samlCallbackHandler as v,redoclyTokenLoginHandler as F,inviteHandler as G}from"./auth.js";import{appDataHandler as U}from"./app-data.js";import{searchFacetsHandler as Y,searchHandler as y}from"./search.js";import{dynamicRouteHandler as K}from"./dynamic-route.js";import{pageDataHandler as k,sharedPageDataHandler as b}from"./page-data.js";import{pathPrefixRedirectHandler as x}from"./path-prefix-redirect.js";import{getRoutesByLineHandler as T,resolvePathHandler as E,resolvePathsHandler as V,resolveSlugHandler as _}from"./resolve-route.js";import{feedbackHandler as q}from"./feedback.js";import{loggerMiddleware as X}from"../middleware/loggerMiddleware.js";import{responseHeadersMiddleware as $}from"../middleware/responseHeadersMiddleware.js";import{idleTimeoutMiddleware as j}from"../middleware/idleTimeoutMiddleware.js";import{otelTracesHandler as z}from"./otel/otel.js";import{healthCheckHandler as W}from"./health.js";import{askAiHandler as Z,aiAssistantEscalationsHandler as u,aiAssistantFeedbackHandler as J,AI_ASSISTANT_IDENTITY_STATUS_HEADER as Q}from"./ask-ai.js";import{semanticSearchHandler as aa}from"./semantic-search.js";import{replayOauth2RedirectCallbackHandler as ea}from"./replay-oauth2-redirect.js";import{corsProxyHandler as S}from"./cors-proxy.js";import{corsMiddleware as t}from"../middleware/corsMiddleware.js";import{installApiRoutes as ia}from"./api-routes/api-routes.js";import{cookieMiddleware as la}from"../middleware/cookieMiddleware.js";import{staticContentHandler as ta}from"../routes/static-content.js";import{infoHandler as f}from"./info.js";import{catalogHandler as ma}from"./catalog/catalog.js";import{catalogRelationsHandler as da}from"./catalog/catalog-relations.js";import{bffCatalogHandler as Aa}from"./catalog/bff-catalog.js";import{bffCatalogRevisionsHandler as oa}from"./catalog/bff-catalog-revisions.js";import{bffCatalogRelatedEntitiesHandler as na}from"./catalog/bff-catalog-related-entities.js";import{catalogAuthMiddleware as m}from"../middleware/catalogAuthMiddleware.js";import{telemetryMiddleware as pa}from"../middleware/telemetry-middleware.js";import{errorHandler as sa}from"./error.js";import{installMcpRoutes as Ta}from"./mcp-routes/mcp-routes.js";import{jsonValidatorMiddleware as O}from"../middleware/jsonValidatorMiddleware.js";import{searchFacetsRequestSchema as Ea}from"../../../api-schemas/search-facets.js";import{searchRequestSchema as _a}from"../../../api-schemas/search.js";function de(a,e,d){const{resolveRouteData:o,readStaticAsset:n}=d;a.use("*",j()),a.use("*",la()),a.use("*",g(e)),a.use("*",C(e)),a.use("*",X()),a.use("*",$(e)),a.use("*",pa()),a.use(i("*"),R({root:`./${c}`,getContent:(A,r)=>ta(A,r,e,n),rewriteRequestPath:A=>H(A)})),a.use(i(l.FEEDBACK),t({allowMethods:["POST"]})),a.use(i(l.ASK_AI),t({allowMethods:["POST"],exposeHeaders:[Q]})),a.use(i(l.AI_ASSISTANT_ESCALATIONS),t({allowMethods:["POST"]})),a.use(i(l.AI_ASSISTANT_FEEDBACK),t({allowMethods:["POST"]})),a.use(i(l.SEMANTIC_SEARCH),t({allowMethods:["POST"]})),a.use("*",Sa(e));const p=I(e);a.use(i(l.INFO),f()),L.NEW_CATALOG_ENABLED&&(a.use(i(l.CATALOG_ENTITIES),m({serverOutDir:e.serverOutDir}),ma(e)),a.use(i(l.CATALOG_ENTITIES_RELATIONS),m({serverOutDir:e.serverOutDir}),da(e)),a.get(i(l.BFF_CATALOG_ENTITIES),m({serverOutDir:e.serverOutDir,protectReadMethods:!1}),Aa(e)),a.get(i(l.BFF_CATALOG_RELATED_ENTITIES),m({serverOutDir:e.serverOutDir,protectReadMethods:!1}),na(e)),a.get(i(l.BFF_CATALOG_REVISIONS),m({serverOutDir:e.serverOutDir,protectReadMethods:!1}),oa(e))),a.get(i(l.SHARED_PAGE_DATA),b(e)),a.get(i(l.PAGE_DATA),k(e,o)),a.get(i(l.APP_DATA),U(e)),a.post(i(l.SEARCH),p,O(_a),y(e)),a.post(i(l.SEARCH_FACETS),p,O(Ea),Y(e)),a.post(i(l.AUTHORIZATION),P),a.post(i(l.LOGOUT),s(e)),a.get(i(l.LOGOUT),s(e)),a.get(i(l.POST_LOGOUT),w(e)),a.get(i(l.OIDC_CALLBACK),N(e)),a.get(i(l.REDOCLY_TOKEN_LOGIN),F(e)),a.get(i(l.REDOCLY_LOGIN_CALLBACK),B()),a.get(i(l.IDP_LOGIN),M(e)),a.post(i(l.SAML_CALLBACK),v(e)),a.get(i(l.INVITE),G(e)),a.get(i(l.HEALTH),W),Ta(a,e),D(a,e),h(a,e),a.all(i(l.CORS_PROXY),S(e)),a.all(i(`${l.CORS_PROXY}/*`),S(e)),ia(a,e),a.post(i(l.FEEDBACK),q(e)),a.post(i(l.RESOLVE_ROUTE_BY_PATH),E(e)),a.post(i(l.RESOLVE_ROUTES_BY_PATHS),V(e)),a.post(i(l.RESOLVE_ROUTE_BY_SLUG),_(e)),a.post(i(l.ASK_AI),Z(e)),a.post(i(l.AI_ASSISTANT_ESCALATIONS),u(e)),a.post(i(l.AI_ASSISTANT_FEEDBACK),J(e)),a.post(i(l.SEMANTIC_SEARCH),aa(e)),a.get(i(l.GET_ROUTES_BY_LINE),T(e)),a.post(i(l.OTEL_TRACES),z),a.get(i(l.REPLAY_OAUTH2_CALLBACK),ea),a.all(i("/*"),K(e,o,n)),a.get("*",x),a.onError(sa)}function Sa(a){return async(e,d)=>{await a.waitForPluginsLifecycle(),await d()}}function Ae(a,e){a.get(i(l.INFO),f()),a.post(i(l.RESOLVE_ROUTE_BY_PATH),E(e)),a.post(i(l.RESOLVE_ROUTE_BY_SLUG),_(e)),a.get(i(l.GET_ROUTES_BY_LINE),T(e))}export{Ae as installDevRoutes,de as installProdRoutes,Sa as waitForPluginsLifecycle};
1
+ import{serveStatic as R}from"hono/serve-static";import{withPathPrefix as i,withoutPathPrefix as c}from"@redocly/theme/core/utils";import{ServerRoutes as l}from"../../../constants/api.js";import{PUBLIC_STATIC_FOLDER as H}from"../../constants/common.js";import{envConfig as L}from"../../config/env-config.js";import{authMiddleware as C}from"../middleware/authMiddleware.js";import{ensureSearchData as I}from"../middleware/ensureSearchData.js";import{dynamicMiddleware as g}from"../middleware/dynamic-middleware/dynamic-middleware.js";import{installRoutes as h}from"../../plugins/dev-onboarding/api/routes/index.js";import{installSkillsRoutes as D}from"./skills/skills-routes.js";import{authorizeHandler as P,oidcCallbackHandler as N,logoutHandler as T,postLogoutHandler as w,idpLoginHandler as M,redoclyLoginCallbackHandler as B,samlCallbackHandler as v,redoclyTokenLoginHandler as F,inviteHandler as G}from"./auth.js";import{appDataHandler as U}from"./app-data.js";import{searchFacetsHandler as Y,searchHandler as y}from"./search.js";import{dynamicRouteHandler as K}from"./dynamic-route.js";import{pageDataHandler as k,sharedPageDataHandler as b}from"./page-data.js";import{pathPrefixRedirectHandler as x}from"./path-prefix-redirect.js";import{getRoutesByLineHandler as E,resolvePathHandler as S,resolvePathsHandler as V,resolveSlugHandler as _}from"./resolve-route.js";import{feedbackHandler as q}from"./feedback.js";import{loggerMiddleware as X}from"../middleware/loggerMiddleware.js";import{responseHeadersMiddleware as $}from"../middleware/responseHeadersMiddleware.js";import{idleTimeoutMiddleware as j}from"../middleware/idleTimeoutMiddleware.js";import{otelTracesHandler as u}from"./otel/otel.js";import{healthCheckHandler as z}from"./health.js";import{askAiHandler as W,aiAssistantEscalationsHandler as Z,aiAssistantFeedbackHandler as J,AI_ASSISTANT_IDENTITY_STATUS_HEADER as Q}from"./ask-ai.js";import{semanticSearchHandler as aa}from"./semantic-search.js";import{replayOauth2RedirectCallbackHandler as ea}from"./replay-oauth2-redirect.js";import{corsProxyHandler as f}from"./cors-proxy.js";import{corsMiddleware as t}from"../middleware/corsMiddleware.js";import{installApiRoutes as ia}from"./api-routes/api-routes.js";import{cookieMiddleware as la}from"../middleware/cookieMiddleware.js";import{staticContentHandler as ta}from"../routes/static-content.js";import{infoHandler as r}from"./info.js";import{catalogHandler as ma}from"./catalog/catalog.js";import{catalogRelationsHandler as oa}from"./catalog/catalog-relations.js";import{bffCatalogHandler as da}from"./catalog/bff-catalog.js";import{bffCatalogRevisionsHandler as Aa}from"./catalog/bff-catalog-revisions.js";import{bffCatalogRelatedEntitiesHandler as na}from"./catalog/bff-catalog-related-entities.js";import{catalogAuthMiddleware as m}from"../middleware/catalogAuthMiddleware.js";import{telemetryMiddleware as sa}from"../middleware/telemetry-middleware.js";import{errorHandler as pa}from"./error.js";import{installMcpRoutes as Ta}from"./mcp-routes/mcp-routes.js";import{jsonValidatorMiddleware as A}from"../middleware/jsonValidatorMiddleware.js";import{otelTracesRequestSchema as Ea}from"../../../api-schemas/otel-traces.js";import{searchFacetsRequestSchema as Sa}from"../../../api-schemas/search-facets.js";import{searchRequestSchema as _a}from"../../../api-schemas/search.js";function Ae(a,e,o){const{resolveRouteData:n,readStaticAsset:s}=o;a.use("*",j()),a.use("*",la()),a.use("*",g(e)),a.use("*",C(e)),a.use("*",X()),a.use("*",$(e)),a.use("*",sa()),a.use(i("*"),R({root:`./${H}`,getContent:(d,O)=>ta(d,O,e,s),rewriteRequestPath:d=>c(d)})),a.use(i(l.FEEDBACK),t({allowMethods:["POST"]})),a.use(i(l.ASK_AI),t({allowMethods:["POST"],exposeHeaders:[Q]})),a.use(i(l.AI_ASSISTANT_ESCALATIONS),t({allowMethods:["POST"]})),a.use(i(l.AI_ASSISTANT_FEEDBACK),t({allowMethods:["POST"]})),a.use(i(l.SEMANTIC_SEARCH),t({allowMethods:["POST"]})),a.use("*",fa(e));const p=I(e);a.use(i(l.INFO),r()),L.NEW_CATALOG_ENABLED&&(a.use(i(l.CATALOG_ENTITIES),m({serverOutDir:e.serverOutDir}),ma(e)),a.use(i(l.CATALOG_ENTITIES_RELATIONS),m({serverOutDir:e.serverOutDir}),oa(e)),a.get(i(l.BFF_CATALOG_ENTITIES),m({serverOutDir:e.serverOutDir,protectReadMethods:!1}),da(e)),a.get(i(l.BFF_CATALOG_RELATED_ENTITIES),m({serverOutDir:e.serverOutDir,protectReadMethods:!1}),na(e)),a.get(i(l.BFF_CATALOG_REVISIONS),m({serverOutDir:e.serverOutDir,protectReadMethods:!1}),Aa(e))),a.get(i(l.SHARED_PAGE_DATA),b(e)),a.get(i(l.PAGE_DATA),k(e,n)),a.get(i(l.APP_DATA),U(e)),a.post(i(l.SEARCH),p,A(_a),y(e)),a.post(i(l.SEARCH_FACETS),p,A(Sa),Y(e)),a.post(i(l.AUTHORIZATION),P),a.post(i(l.LOGOUT),T(e)),a.get(i(l.LOGOUT),T(e)),a.get(i(l.POST_LOGOUT),w(e)),a.get(i(l.OIDC_CALLBACK),N(e)),a.get(i(l.REDOCLY_TOKEN_LOGIN),F(e)),a.get(i(l.REDOCLY_LOGIN_CALLBACK),B()),a.get(i(l.IDP_LOGIN),M(e)),a.post(i(l.SAML_CALLBACK),v(e)),a.get(i(l.INVITE),G(e)),a.get(i(l.HEALTH),z),Ta(a,e),h(a,e),D(a,e),a.all(i(l.CORS_PROXY),f(e)),a.all(i(`${l.CORS_PROXY}/*`),f(e)),ia(a,e),a.post(i(l.FEEDBACK),q(e)),a.post(i(l.RESOLVE_ROUTE_BY_PATH),S(e)),a.post(i(l.RESOLVE_ROUTES_BY_PATHS),V(e)),a.post(i(l.RESOLVE_ROUTE_BY_SLUG),_(e)),a.post(i(l.ASK_AI),W(e)),a.post(i(l.AI_ASSISTANT_ESCALATIONS),Z(e)),a.post(i(l.AI_ASSISTANT_FEEDBACK),J(e)),a.post(i(l.SEMANTIC_SEARCH),aa(e)),a.get(i(l.GET_ROUTES_BY_LINE),E(e)),a.post(i(l.OTEL_TRACES),A(Ea),u),a.get(i(l.REPLAY_OAUTH2_CALLBACK),ea),a.all(i("/*"),K(e,n,s)),a.get("*",x),a.onError(pa)}function fa(a){return async(e,o)=>{await a.waitForPluginsLifecycle(),await o()}}function ne(a,e){a.get(i(l.INFO),r()),a.post(i(l.RESOLVE_ROUTE_BY_PATH),S(e)),a.post(i(l.RESOLVE_ROUTE_BY_SLUG),_(e)),a.get(i(l.GET_ROUTES_BY_LINE),E(e))}export{ne as installDevRoutes,Ae as installProdRoutes,fa as waitForPluginsLifecycle};
@@ -1 +1 @@
1
- import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as c}from"../../../constants/common.js";import{telemetryTraceStep as d}from"../../../telemetry/helpers/trace-step.js";import{getAccessibleSkills as g}from"../../../utils/skills/get-accessible-skills.js";import{resolvePublicBaseUrl as m}from"../../../web-server/utils/resolve-public-base-url.js";import{shouldHandleMcpAuth as A}from"../../../plugins/mcp/auth/auth-handlers.js";import{buildAgentCard as C}from"./utils/build-agent-card.js";function y(e){return async r=>await d("com.redocly.agentCard.served",async t=>{if(t?.setAttribute("id","agentCardId"),t?.setAttribute("object","agentCard"),t?.setAttribute("uri","urn:redocly:realm:api:agentCard:agentCardId"),e.config.skills?.hide===!0)return r.newResponse(null,404);const{isAuthenticated:l,teams:a,claims:{email:u}}=r.get("auth"),i=e.config.access?.rbac||{},n=!!e.config.access?.requiresLogin,s=g(e.getSkills(),{isAuthenticated:l,teams:a,email:u},i,n),o=A(n,i);return t?.setAttribute("skillsCount",s.length),t?.setAttribute("mcpAuthRequired",o),r.json(C({seo:e.getGlobalConfig("seo"),baseUrl:m(e,r),skills:s,mcpAuthRequired:o}),200,{"Cache-Control":c,"Access-Control-Allow-Origin":"*"})})}export{y as agentCardHandler};
1
+ import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as c}from"../../../constants/common.js";import{telemetryTraceStep as d}from"../../../telemetry/helpers/trace-step.js";import{getAccessibleSkills as g}from"../../../utils/skills/get-accessible-skills.js";import{resolvePublicBaseUrl as m}from"../../../web-server/utils/resolve-public-base-url.js";import{shouldHandleMcpAuth as A}from"../../../utils/rbac/should-handle-mcp-auth.js";import{buildAgentCard as C}from"./utils/build-agent-card.js";function y(e){return async r=>await d("com.redocly.agentCard.served",async t=>{if(t?.setAttribute("id","agentCardId"),t?.setAttribute("object","agentCard"),t?.setAttribute("uri","urn:redocly:realm:api:agentCard:agentCardId"),e.config.skills?.hide===!0)return r.newResponse(null,404);const{isAuthenticated:l,teams:a,claims:{email:u}}=r.get("auth"),i=e.config.access?.rbac||{},n=!!e.config.access?.requiresLogin,s=g(e.getSkills(),{isAuthenticated:l,teams:a,email:u},i,n),o=A(n,i);return t?.setAttribute("skillsCount",s.length),t?.setAttribute("mcpAuthRequired",o),r.json(C({seo:e.getGlobalConfig("seo"),baseUrl:m(e,r),skills:s,mcpAuthRequired:o}),200,{"Cache-Control":c,"Access-Control-Allow-Origin":"*"})})}export{y as agentCardHandler};
@@ -1 +1 @@
1
- import{withPathPrefix as S}from"@redocly/theme/core/utils";import{DEFAULT_DOCS_MCP_SERVER_NAME as f,MCP_PROTOCOL_VERSION as A}from"../../../plugins/mcp/constants.js";import{RESERVED_ROUTES as O}from"../../../plugins/get-reserved-routes.js";import{isMcpCodeModeEnabled as T}from"../../../plugins/mcp/utils/mode.js";import{CODE_MODE_TOOL_NAMES as b,DESCRIBE_TOOLS_TOOL_NAME as M,FETCH_TOOL_NAME as R}from"../../../plugins/mcp/codemode/constants.js";import{EXECUTE_TOOL_SCHEMA as g}from"../../../plugins/mcp/codemode/tools/execute-schema.js";import{describeToolsSchema as v}from"../../../plugins/mcp/codemode/tools/describe-tools.js";import{buildCodeModeInstructions as L,buildExecuteDescription as I,DESCRIBE_TOOLS_DESCRIPTION as D}from"../../../plugins/mcp/codemode/prompts.js";import{toToolListEntries as P}from"../../../plugins/mcp/codemode/build-tool-list.js";import{composeExecuteAnnotations as y}from"../../../plugins/mcp/codemode/capabilities/index.js";import{ALL_CAPABILITIES as V}from"../../../plugins/mcp/codemode/capabilities/registry.js";import{isGatewayCapabilityEnabled as H}from"../../../plugins/mcp/gateway-mcp/eligibility.js";import{shouldHandleMcpAuth as N}from"../../../plugins/mcp/auth/auth-handlers.js";import{resolvePublicBaseUrl as U}from"../../../web-server/utils/resolve-public-base-url.js";import{telemetryTraceStep as x}from"../../../telemetry/helpers/trace-step.js";import{MCP_AUTH_SCHEMES as w}from"./constants.js";const B="https://static.modelcontextprotocol.io/schemas/mcp-server-card/v1.json",j="1.0";function ie(r){const s=T(),E=new Date().toISOString().slice(0,10);return async m=>await x("com.redocly.mcpServerCard.served",async e=>{e?.setAttribute("id","mcpServerCardId"),e?.setAttribute("object","mcpServerCard"),e?.setAttribute("uri","urn:redocly:realm:api:mcpServerCard:mcpServerCardId");const o=r.getConfig(),a=o.mcp?.docs?.name||f,n=r.getMcpTools().filter(t=>!b.has(t.name)&&!t.hasAvailabilityGate),i=H(o.mcp)?[...V]:[],l=i.some(t=>t.id===R),d=P(n,i),c=(s?[{...g,description:I(l,d),annotations:y(i)},{name:M,description:D,schema:v(n,i)}]:n).map(({name:t,description:_,schema:h,annotations:u})=>({name:t,description:_,inputSchema:h,...u?{annotations:u}:{}})),C=o.skills?.hide===!0?[]:r.getSkills(),p={$schema:B,version:j,protocolVersion:A,serverInfo:{name:a,title:a,version:E},description:o.seo?.description,documentationUrl:U(r,m),transport:{type:"streamable-http",endpoint:S(O.mcp)},capabilities:{logging:{},tools:{listChanged:!0},...C.length>0?{resources:{listChanged:!0},completions:{}}:{}},authentication:N(!!o.access?.requiresLogin,o.access?.rbac)?{required:!0,schemes:w}:void 0,instructions:s?L(l,d):void 0,tools:c.length>0?c:["dynamic"]};return e?.setAttribute("mode",s?"code":"tools"),e?.setAttribute("toolsCount",c.length),e?.setAttribute("authRequired",p.authentication!==void 0),m.json(p,200,{"Access-Control-Allow-Origin":"*","Cache-Control":"public, max-age=3600"})})}export{ie as mcpServerCardHandler};
1
+ import{withPathPrefix as A}from"@redocly/theme/core/utils";import{DEFAULT_DOCS_MCP_SERVER_NAME as b,MCP_PROTOCOL_VERSION as S}from"../../../plugins/mcp/constants.js";import{RESERVED_ROUTES as T}from"../../../plugins/get-reserved-routes.js";import{isMcpCodeModeEnabled as g}from"../../../plugins/mcp/utils/mode.js";import{CODE_MODE_TOOL_NAMES as v,FETCH_TOOL_NAME as M}from"../../../plugins/mcp/codemode/constants.js";import{EXECUTE_TOOL_SCHEMA as O}from"../../../plugins/mcp/codemode/tools/execute-schema.js";import{describeToolsSchema as R}from"../../../plugins/mcp/codemode/tools/describe-tools.js";import{normalizeToolDisplayName as L}from"../../../plugins/mcp/utils/tool-registration.js";import{buildCodeModeInstructions as y,buildExecuteDescription as D}from"../../../plugins/mcp/codemode/prompts.js";import{toToolListEntries as I}from"../../../plugins/mcp/codemode/build-tool-list.js";import{composeExecuteAnnotations as P}from"../../../plugins/mcp/codemode/capabilities/index.js";import{ALL_CAPABILITIES as V}from"../../../plugins/mcp/codemode/capabilities/registry.js";import{isGatewayCapabilityEnabled as H}from"../../../plugins/mcp/gateway-mcp/eligibility.js";import{shouldHandleMcpAuth as U}from"../../../utils/rbac/should-handle-mcp-auth.js";import{resolvePublicBaseUrl as x}from"../../../web-server/utils/resolve-public-base-url.js";import{telemetryTraceStep as N}from"../../../telemetry/helpers/trace-step.js";import{MCP_AUTH_SCHEMES as w}from"./constants.js";const j="https://static.modelcontextprotocol.io/schemas/mcp-server-card/v1.json",k="1.0";function se(r){const s=g(),u=new Date().toISOString().slice(0,10);return async a=>await N("com.redocly.mcpServerCard.served",async e=>{e?.setAttribute("id","mcpServerCardId"),e?.setAttribute("object","mcpServerCard"),e?.setAttribute("uri","urn:redocly:realm:api:mcpServerCard:mcpServerCardId");const o=r.getConfig(),m=o.mcp?.docs?.name||b,n=r.getMcpTools().filter(t=>!v.has(t.name)&&!t.hasAvailabilityGate),i=H(o.mcp)?[...V]:[],l=i.some(t=>t.id===M),d=I(n,i),c=(s?[{...O,description:D(l,d),annotations:P(i)},R(n,i)]:n).map(L).map(({name:t,title:E,description:f,schema:h,annotations:_})=>({name:t,title:E,description:f,inputSchema:h,annotations:_})),C=o.skills?.hide===!0?[]:r.getSkills(),p={$schema:j,version:k,protocolVersion:S,serverInfo:{name:m,title:m,version:u},description:o.seo?.description,documentationUrl:x(r,a),transport:{type:"streamable-http",endpoint:A(T.mcp)},capabilities:{logging:{},tools:{listChanged:!0},...C.length>0?{resources:{listChanged:!0},completions:{}}:{}},authentication:U(!!o.access?.requiresLogin,o.access?.rbac)?{required:!0,schemes:w}:void 0,instructions:s?y(l,d):void 0,tools:c.length>0?c:["dynamic"]};return e?.setAttribute("mode",s?"code":"tools"),e?.setAttribute("toolsCount",c.length),e?.setAttribute("authRequired",p.authentication!==void 0),a.json(p,200,{"Access-Control-Allow-Origin":"*","Cache-Control":"public, max-age=3600"})})}export{se as mcpServerCardHandler};
@@ -1 +1 @@
1
- import{AsyncApiRealmAPI as y}from"@redocly/realm-asyncapi-sdk";import{envConfig as o}from"../../../config/env-config.js";import{getClientIp as R}from"../../utils/get-client-ip.js";import{getAttributesStringValue as I,mergeAttributes as h,toAttribute as O}from"./otlp.js";const C=o.OTEL_TRACES_URL||"https://otel.cloud.redocly.com/v1/traces",A="cloudevents.event_session_id";class w extends y.OtelClient{initTracer(){}}let d=null;function E(){return d||(d=new w,d.init({collectorTraceUrl:void 0,serviceName:"realm-ui",serviceVersion:"1.0",isProd:o.isProductionEnv,version:"1.0",tracerName:"attribute-processor"})),d}async function $(e){const t=await e.req.json();return t.resourceSpans?.length&&(N(t,j(e)),await fetch(C,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})),e.newResponse(null,200)}function N(e,t){for(const s of e.resourceSpans){const r=s.resource.attributes.find(u=>u.key==="session_id");if(!r)continue;const i=I(r);if(!i)continue;const l=L(t.userId,i),_=new Date,v={organizationId:o.ORGANIZATION_ID||"",organizationSlug:o.ORGANIZATION_SLUG||"",projectId:o.PROJECT_ID||"",projectSlug:o.PROJECT_SLUG||"",env:o.REDOCLY_ENV||"",source:"urn:redocly:realm:ui",actor:{id:l.id,object:l.object,uri:l.uri},clientIp:t.clientIp,userAgent:t.userAgent},c=(u,n)=>{const a=u.attributes.find(f=>f.key===n);return a?I(a):""};for(const u of s.scopeSpans)for(const n of u.spans){if(!n.name.startsWith("event.")||n.name==="event.undefined")continue;const a=c(n,"cloudevents.event_spec_version"),f=c(n,"cloudevents.event_object"),g=c(n,"cloudevents.event_data_content_type"),b=c(n,"cloudevents.event_origin"),p=c(n,"cloudevents.event_time"),m=p?new Date(p):_,S={...v,id:c(n,"cloudevents.event_id"),specversion:a,type:n.name.slice(6),object:f,datacontenttype:g,time:m,origin:b},T=E().processAttributes(S,m);h(n,T,{overwrite:!0}),P(n,t.sessionId)}}}function P(e,t){const s=e.attributes.findIndex(i=>i.key===A),r=O(A,t);r?s===-1?e.attributes.push(r):e.attributes[s]=r:s!==-1&&e.attributes.splice(s,1)}function j(e){const t=e.get("auth")?.claims?.id||e.get("auth")?.claims?.sub,s=e.get("auth")?.claims?.sessionId,r=R(e.req.raw)||e.req.raw.context?.remoteAddr?.hostname,i=e.req.raw.headers.get("user-agent");return{userId:t,sessionId:s||void 0,clientIp:r??void 0,userAgent:i??void 0}}function L(e,t){if(e)return{id:e,object:"user",uri:`${o.MAIN_API_URL}/users/${e}`};const s=t.replace("ses_","ann_");return{id:s,object:"anonymous",uri:`${o.MAIN_API_URL}/anonymous/${s}`}}export{$ as otelTracesHandler,L as toActor};
1
+ import{AsyncApiRealmAPI as N}from"@redocly/realm-asyncapi-sdk";import{envConfig as o}from"../../../config/env-config.js";import{getClientIp as R}from"../../utils/get-client-ip.js";import{getAttributesStringValue as _,mergeAttributes as h,toAttribute as O}from"./otlp.js";const C=o.OTEL_TRACES_URL||"https://otel.cloud.redocly.com/v1/traces",v="cloudevents.event_session_id";class w extends N.OtelClient{initTracer(){}}let d=null;function E(){return d||(d=new w,d.init({collectorTraceUrl:void 0,serviceName:"realm-ui",serviceVersion:"1.0",isProd:o.isProductionEnv,version:"1.0",tracerName:"attribute-processor"})),d}async function k(e){const t=await e.req.json();return t.resourceSpans?.length&&(P(t,L(e)),await fetch(C,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})),e.newResponse(null,200)}function P(e,t){for(const s of e.resourceSpans){const r=s.resource.attributes.find(u=>u.key==="session_id");if(!r)continue;const i=_(r);if(!i)continue;const l=U(t.userId,i),p=new Date,g={organizationId:o.ORGANIZATION_ID||"",organizationSlug:o.ORGANIZATION_SLUG||"",projectId:o.PROJECT_ID||"",projectSlug:o.PROJECT_SLUG||"",env:o.REDOCLY_ENV||"",source:"urn:redocly:realm:ui",actor:{id:l.id,object:l.object,uri:l.uri},clientIp:t.clientIp,userAgent:t.userAgent},c=(u,n)=>{const a=u.attributes.find(f=>f.key===n);return a?_(a):""};for(const u of s.scopeSpans)for(const n of u.spans){if(!n.name.startsWith("event.")||n.name==="event.undefined")continue;const a=c(n,"cloudevents.event_spec_version"),f=c(n,"cloudevents.event_object"),b=c(n,"cloudevents.event_data_content_type"),S=c(n,"cloudevents.event_origin"),m=c(n,"cloudevents.event_time"),I=m?new Date(m):p,A=Number.isNaN(I.getTime())?p:I,T={...g,id:c(n,"cloudevents.event_id"),specversion:a,type:n.name.slice(6),object:f,datacontenttype:b,time:A,origin:S},y=E().processAttributes(T,A);h(n,y,{overwrite:!0}),j(n,t.sessionId)}}}function j(e,t){const s=e.attributes.findIndex(i=>i.key===v),r=O(v,t);r?s===-1?e.attributes.push(r):e.attributes[s]=r:s!==-1&&e.attributes.splice(s,1)}function L(e){const t=e.get("auth")?.claims?.id||e.get("auth")?.claims?.sub,s=e.get("auth")?.claims?.sessionId,r=R(e.req.raw)||e.req.raw.context?.remoteAddr?.hostname,i=e.req.raw.headers.get("user-agent");return{userId:t,sessionId:s||void 0,clientIp:r??void 0,userAgent:i??void 0}}function U(e,t){if(e)return{id:e,object:"user",uri:`${o.MAIN_API_URL}/users/${e}`};const s=t.replace("ses_","ann_");return{id:s,object:"anonymous",uri:`${o.MAIN_API_URL}/anonymous/${s}`}}export{k as otelTracesHandler,U as toActor};
@@ -1 +1 @@
1
- import{ServerRoutes as $}from"../../../constants/api.js";import{DEV_LOGIN_SLUG as w}from"../../../constants/common.js";import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as a,DEFAULT_TITLE as U}from"../../constants/common.js";import{findInIterable as F}from"../../../utils/collection/find-in-iterable.js";import{removeTrailingSlash as N}from"../../../utils/url/remove-trailing-slash.js";import{envConfig as b}from"../../config/env-config.js";import{canAccessResource as q,filterDataByAccessDeep as T,isResourcePubliclyAccessible as B}from"../../utils/rbac.js";import{getServerProps as H}from"../../ssr/index.js";import{readSharedData as M}from"../../utils/index.js";import{getRedirectLoginUrl as G}from"../utils/get-redirect-login-url.js";import{processRedirects as V}from"./helpers/process-redirects.js";import{removeErrorDetails as W}from"../utils/remove-error-details.js";import{telemetry as k}from"../../telemetry/index.js";import{MCP_NOT_ALLOWED_TEMPLATE_ID as K}from"../../plugins/mcp/constants.js";function ie(e,n){return async(t,g)=>{const m=t.get("logger"),{req:p}=t,{pathname:d}=new URL(p.url),{seo:f,ssoDirect:h}=e.getConfig(),i=f?.title||U;if(e?.compilationErrors?.length&&b.isDevelopMode)return t.json({templateId:"compilation-error",props:{compilationErrors:e?.compilationErrors},sharedDataIds:{}},500,{"Cache-Control":a});const u=d.match(/page-data(.*)data.json$/);if(!u)return g();const c=decodeURI(u[1]),r=c==="/index/"?"/":N(c),o=e.getRouteBySlug(r,{followRedirect:!1})||F(e.routesBySlug.values(),s=>s.hasClientRoutes&&c.startsWith(s.slug+"/"));if(c===$.OIDC_CALLBACK+"/")return t.json({templateId:"403OIDC",sharedDataIds:{},props:{seo:{title:`${i} - Forbidden`}}},200,{"Cache-Control":a});const{isAuthenticated:C,teams:D,claims:{name:j,picture:A,email:I}}=t.get("auth"),R={isAuthenticated:C,email:I,teams:D},l={isAuthenticated:C,name:j,picture:A,email:I,teams:D};if(r==="/mcp"&&e.globalData.mcpData?.docs?.enabled)return t.json({templateId:K,sharedDataIds:{},props:{},userData:l},405,{"Cache-Control":a});const L=e.getRedirect(r);if(L){const s=V({redirect:L}).location;return k.sendRedirectMessage([{id:r,object:"redirect",uri:`urn:redocly:realm:api:redirect:${r}`,from:r,templateId:"404"}]),t.json({templateId:"404",redirectTo:s,sharedDataIds:{},props:{}},301,{"Cache-Control":a})}if(!o){const s=e.getRouteBySlug(r,{followRedirect:!0});return m.error(`Page not found: ${d}`),t.json({templateId:"404",redirectTo:s?.slug,sharedDataIds:{},props:{seo:{title:`${i} - Not Found`}},userData:l},404,{"Cache-Control":a})}if(m.verbose(`Page viewed: ${o.slug}`),!q(o,R,e.config.access?.rbac,e.config.access?.requiresLogin)&&o.slug!==w){if(C)return t.json({templateId:"403",sharedDataIds:{},props:{seo:{title:`${i} - Forbidden`}},userData:l},403,{"Cache-Control":a});const s=Object.keys(h||{}).length>0;return t.json({templateId:"404",sharedDataIds:{},props:{seo:{title:`${i} - Not Found`}},userData:l,...s?{redirectTo:G(e,o.slug)}:{}},s?401:404,{"Cache-Control":a})}const S=T(o.versions,R,e.config.access?.rbac,e.config.access?.requiresLogin),_=e.routesSharedData.get(o.slug)||{},v=await n(o),P=await H(o,t,v,e),{sharedDataIds:y,...E}=P,O={templateId:o.templateId,versions:S,sharedDataIds:{..._,...y||{}},props:b.isProductionEnv?W(E):E,slug:o.slug,userData:l,isPublic:B(o,e.config)};return t.json(O,200,{"Cache-Control":a})}}function ce(e){return async(n,t)=>{const g=n.get("logger"),{req:m}=n,{pathname:p}=new URL(m.url),d=p.match(/\/page-data\/shared\/(.*)\.json/);if(!d)return t();const f=decodeURIComponent(d[1]),h=await M(f,e.outdir),{isAuthenticated:i,teams:u,claims:{email:c}}=n.get("auth"),r=T(h,{isAuthenticated:i,email:c,teams:u},e.config.access?.rbac,e.config.access?.requiresLogin);return r?n.json(r,200,{"Cache-Control":a}):(g.error(`Shared data not found: ${p}`),n.text("Not Found",404,{"Cache-Control":a}))}}export{ie as pageDataHandler,ce as sharedPageDataHandler};
1
+ import{MCP_ROUTE as y,PUBLIC_MCP_ROUTE as $}from"@redocly/theme/core/constants/mcp";import{ServerRoutes as w}from"../../../constants/api.js";import{DEV_LOGIN_SLUG as M}from"../../../constants/common.js";import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as a,DEFAULT_TITLE as F}from"../../constants/common.js";import{findInIterable as N}from"../../../utils/collection/find-in-iterable.js";import{removeTrailingSlash as B}from"../../../utils/url/remove-trailing-slash.js";import{envConfig as b}from"../../config/env-config.js";import{canAccessResource as q,filterDataByAccessDeep as T,isResourcePubliclyAccessible as H}from"../../utils/rbac.js";import{getServerProps as G}from"../../ssr/index.js";import{readSharedData as V}from"../../utils/index.js";import{getRedirectLoginUrl as W}from"../utils/get-redirect-login-url.js";import{processRedirects as k}from"./helpers/process-redirects.js";import{removeErrorDetails as K}from"../utils/remove-error-details.js";import{telemetry as z}from"../../telemetry/index.js";import{MCP_NOT_ALLOWED_TEMPLATE_ID as J}from"../../constants/mcp.js";function pe(e,n){return async(t,g)=>{const p=t.get("logger"),{req:m}=t,{pathname:d}=new URL(m.url),{seo:f,ssoDirect:h}=e.getConfig(),i=f?.title||F;if(e?.compilationErrors?.length&&b.isDevelopMode)return t.json({templateId:"compilation-error",props:{compilationErrors:e?.compilationErrors},sharedDataIds:{}},500,{"Cache-Control":a});const u=d.match(/page-data(.*)data.json$/);if(!u)return g();const c=decodeURI(u[1]),r=c==="/index/"?"/":B(c),o=e.getRouteBySlug(r,{followRedirect:!1})||N(e.routesBySlug.values(),s=>s.hasClientRoutes&&c.startsWith(s.slug+"/"));if(c===w.OIDC_CALLBACK+"/")return t.json({templateId:"403OIDC",sharedDataIds:{},props:{seo:{title:`${i} - Forbidden`}}},200,{"Cache-Control":a});const{isAuthenticated:C,teams:D,claims:{name:_,picture:P,email:I}}=t.get("auth"),R={isAuthenticated:C,email:I,teams:D},l={isAuthenticated:C,name:_,picture:P,email:I,teams:D};if((r===y||r===$&&!!e.globalData.mcpData?.docs?.publicEndpoint)&&e.globalData.mcpData?.docs?.enabled)return t.json({templateId:J,sharedDataIds:{},props:{},userData:l},405,{"Cache-Control":a});const E=e.getRedirect(r);if(E){const s=k({redirect:E}).location;return z.sendRedirectMessage([{id:r,object:"redirect",uri:`urn:redocly:realm:api:redirect:${r}`,from:r,templateId:"404"}]),t.json({templateId:"404",redirectTo:s,sharedDataIds:{},props:{}},301,{"Cache-Control":a})}if(!o){const s=e.getRouteBySlug(r,{followRedirect:!0});return p.error(`Page not found: ${d}`),t.json({templateId:"404",redirectTo:s?.slug,sharedDataIds:{},props:{seo:{title:`${i} - Not Found`}},userData:l},404,{"Cache-Control":a})}if(p.verbose(`Page viewed: ${o.slug}`),!q(o,R,e.config.access?.rbac,e.config.access?.requiresLogin)&&o.slug!==M){if(C)return t.json({templateId:"403",sharedDataIds:{},props:{seo:{title:`${i} - Forbidden`}},userData:l},403,{"Cache-Control":a});const s=Object.keys(h||{}).length>0;return t.json({templateId:"404",sharedDataIds:{},props:{seo:{title:`${i} - Not Found`}},userData:l,...s?{redirectTo:W(e,o.slug)}:{}},s?401:404,{"Cache-Control":a})}const j=T(o.versions,R,e.config.access?.rbac,e.config.access?.requiresLogin),A=e.routesSharedData.get(o.slug)||{},S=await n(o),v=await G(o,t,S,e),{sharedDataIds:O,...L}=v,U={templateId:o.templateId,versions:j,sharedDataIds:{...A,...O||{}},props:b.isProductionEnv?K(L):L,slug:o.slug,userData:l,isPublic:H(o,e.config)};return t.json(U,200,{"Cache-Control":a})}}function me(e){return async(n,t)=>{const g=n.get("logger"),{req:p}=n,{pathname:m}=new URL(p.url),d=m.match(/\/page-data\/shared\/(.*)\.json/);if(!d)return t();const f=decodeURIComponent(d[1]),h=await V(f,e.outdir),{isAuthenticated:i,teams:u,claims:{email:c}}=n.get("auth"),r=T(h,{isAuthenticated:i,email:c,teams:u},e.config.access?.rbac,e.config.access?.requiresLogin);return r?n.json(r,200,{"Cache-Control":a}):(g.error(`Shared data not found: ${m}`),n.text("Not Found",404,{"Cache-Control":a}))}}export{pe as pageDataHandler,me as sharedPageDataHandler};
@@ -7,10 +7,6 @@ export type ListResponseResult<T extends {
7
7
  page: {
8
8
  total: number;
9
9
  limit: number;
10
- hasNextPage: boolean;
11
- hasPrevPage: boolean;
12
- startCursor: string | null;
13
- endCursor: string | null;
14
10
  nextPage: string | null;
15
11
  previousPage: string | null;
16
12
  };
@@ -1 +1 @@
1
- import{createCursor as c}from"../../providers/database/pagination/utils/create-cursor.js";import{DEFAULT_LIMIT as o}from"../../providers/database/pagination/limit.js";function h(e){return!!(e.after||e.before)}function b(e,i,n){const r=h(i),t=i.limit??o;if(r){if(i.before)return!0;if(i.after)return e.length===t}return n!==void 0&&i.skip!==void 0?i.skip+t<n:n!==void 0?t<n:e.length===t}function d(e){return!!(e.after||e.before||e.skip!==void 0&&e.skip>0)}function x({data:e,params:i,totalCount:n,nameTransformationsFromDatabase:r={},hasMore:t}){if(!e.length)return{object:"list",items:[],page:{total:0,limit:i.limit??o,hasNextPage:!1,hasPrevPage:!1,startCursor:null,endCursor:null,nextPage:null,previousPage:null}};const l=i.sort?.length?i.sort:[{field:"id",order:"ASC"}],u=t??b(e,i,n),g=d(i),P=!!(i.after||i.before&&t||i.skip!==void 0&&i.skip>0),f=c(e[0],l,r),s=c(e[e.length-1],l,r);return{object:"list",items:e,page:{total:n??0,limit:i.limit??o,hasNextPage:u,hasPrevPage:g,startCursor:f,endCursor:s,nextPage:u?s:null,previousPage:P?f:null}}}export{x as prepareListResponse};
1
+ import{createCursor as u}from"../../providers/database/pagination/utils/create-cursor.js";import{DEFAULT_LIMIT as l}from"../../providers/database/pagination/limit.js";function P(i){return!!(i.after||i.before)}function b(i,e,t){const r=P(e),n=e.limit??l;if(r){if(e.before)return!0;if(e.after)return i.length===n}return t!==void 0&&e.skip!==void 0?e.skip+n<t:t!==void 0?n<t:i.length===n}function v({data:i,params:e,totalCount:t,nameTransformationsFromDatabase:r={},hasMore:n}){if(!i.length)return{object:"list",items:[],page:{total:0,limit:e.limit??l,nextPage:null,previousPage:null}};const o=e.sort?.length?e.sort:[{field:"id",order:"ASC"}],f=n??b(i,e,t),s=!!(e.after||e.before&&n||e.skip!==void 0&&e.skip>0),c=u(i[0],o,r),g=u(i[i.length-1],o,r);return{object:"list",items:i,page:{total:t??0,limit:e.limit??l,nextPage:f?g:null,previousPage:s?c:null}}}export{v as prepareListResponse};
@@ -12,7 +12,7 @@ export declare function handleErrorPageRender(ctx: Context, store: Store, option
12
12
  };
13
13
  }, statusCode: ClientErrorStatusCode, templateId?: string): Promise<Response>;
14
14
  export declare function getLoginUrlWithRedirect(redirectTo: string): string;
15
- export declare function handleUnauthorizedAsset(ctx: Context): Promise<Response & import("hono").TypedResponse<"Forbidden", -1 | 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511, "text">>;
15
+ export declare function handleUnauthorizedAsset(ctx: Context): Promise<Response & import("hono").TypedResponse<string, -1 | 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511, "text">>;
16
16
  export declare function handleUnauthorizedApiRequest(ctx: Context): Response & import("hono").TypedResponse<{
17
17
  message: string;
18
18
  }, -1 | 100 | 102 | 103 | 200 | 201 | 202 | 203 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511, "json">;
@@ -1 +1 @@
1
- import{setCookie as b}from"hono/cookie";import{withPathPrefix as l}from"@redocly/theme/core/utils";import{DEV_LOGIN_SLUG as A}from"../../constants/common.js";import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as C}from"../constants/common.js";import{hasPostLogoutCookie as y}from"../utils/cookie.js";import{getAuthProviderLoginParams as _,buildLoginUrl as O}from"./auth.js";import{renderPage as R}from"../ssr/index.js";import{telemetry as v}from"../../cli/telemetry/index.js";async function k(t,r,e,n){const{isAuthenticated:a}=t.get("auth"),i=t.req.raw.headers.get("x-forwarded-host"),o=t.req.raw.headers.get("x-forwarded-proto"),w=i?`${o==="http"||o==="https"?o:"https"}://${i}`:new URL(t.req.url).origin,g=r.getConfig().ssoDirect,p=Object.keys(g||{}),d=n||p[0],m=g?.[d];if(a)return z(t,r,{slug:e},403);const s=d&&m?await _(d,m):void 0,f=s&&y(t)?{...s,extraParams:{...s.extraParams,prompt:"login",post_logout:"1"}}:s,{loginUrl:E,cookies:h={}}=f&&O(f,w,l(e))||{},L=r.globalData.auth?.devLogin||p.length>1?D(e):E;return Object.keys(h).forEach(c=>{b(t,c,h[c].value,h[c].options)}),L?t.newResponse(null,302,{Location:L}):t.text("Unauthorized",401)}const P={};async function z(t,r,e,n,a){const i=a||String(n);let o=P[i];if(!o){const u={templateId:String(a||n),fsPath:"/",...e,baseSlug:e.slug};o=(await R(u,{},t,r,v)).html,P[i]=o}return t.html(o,n,{"Cache-Control":C})}function D(t){const r=new URLSearchParams({redirectTo:l(t)});return`${l(A)}?${r}`}async function G(t){return t.text("Forbidden",U(t))}function V(t){return t.json({message:"Forbidden"},U(t))}function U(t){const{isAuthenticated:r}=t.get("auth");return r?403:401}function K(t){const r=t?.match(/(?:^|:)(\d{1,3}(?:\.\d{1,3}){3})$/);return r?r[1]:t}export{D as getLoginUrlWithRedirect,z as handleErrorPageRender,k as handleUnauthorized,V as handleUnauthorizedApiRequest,G as handleUnauthorizedAsset,K as normalizeIpAddress};
1
+ import{setCookie as A}from"hono/cookie";import{withPathPrefix as c}from"@redocly/theme/core/utils";import{DEV_LOGIN_SLUG as b}from"../../constants/common.js";import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as y}from"../constants/common.js";import{hasPostLogoutCookie as C}from"../utils/cookie.js";import{getAuthProviderLoginParams as _,buildLoginUrl as z}from"./auth.js";import{renderPage as O}from"../ssr/index.js";import{telemetry as R}from"../../cli/telemetry/index.js";async function F(t,r,o,n){const{isAuthenticated:a}=t.get("auth"),i=t.req.raw.headers.get("x-forwarded-host"),e=t.req.raw.headers.get("x-forwarded-proto"),w=i?`${e==="http"||e==="https"?e:"https"}://${i}`:new URL(t.req.url).origin,l=r.getConfig().ssoDirect,m=Object.keys(l||{}),d=n||m[0],p=l?.[d];if(a)return $(t,r,{slug:o},403);const s=d&&p?await _(d,p):void 0,f=s&&C(t)?{...s,extraParams:{...s.extraParams,prompt:"login",post_logout:"1"}}:s,{loginUrl:E,cookies:h={}}=f&&z(f,w,c(o))||{},L=r.globalData.auth?.devLogin||m.length>1?v(o):E;return Object.keys(h).forEach(u=>{A(t,u,h[u].value,h[u].options)}),L?t.newResponse(null,302,{Location:L}):t.text("Unauthorized",401)}const P={};async function $(t,r,o,n,a){const i=a?`${a}:${o.slug}`:String(n);let e=P[i];if(!e){const g={templateId:String(a||n),fsPath:"/",...o,baseSlug:o.slug};e=(await O(g,{},t,r,R)).html,P[i]=e}return t.html(e,n,{"Cache-Control":y})}function v(t){const r=new URLSearchParams({redirectTo:c(t)});return`${c(b)}?${r}`}async function G(t){const{status:r,reason:o}=U(t);return t.text(o,r)}function V(t){const{status:r,reason:o}=U(t);return t.json({message:o},r)}function U(t){const{isAuthenticated:r}=t.get("auth");return r?{status:403,reason:"Forbidden"}:{status:401,reason:"Unauthorized"}}function K(t){const r=t?.match(/(?:^|:)(\d{1,3}(?:\.\d{1,3}){3})$/);return r?r[1]:t}export{v as getLoginUrlWithRedirect,$ as handleErrorPageRender,F as handleUnauthorized,V as handleUnauthorizedApiRequest,G as handleUnauthorizedAsset,K as normalizeIpAddress};
@@ -32,6 +32,7 @@ export type GlobalData = UiAccessibleConfig & {
32
32
  docs?: {
33
33
  enabled: boolean;
34
34
  name?: string;
35
+ publicEndpoint?: boolean;
35
36
  };
36
37
  };
37
38
  searchFeatures?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/redoc",
3
- "version": "0.137.0-next.4",
3
+ "version": "0.137.0-next.6",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -93,15 +93,15 @@
93
93
  "xpath": "0.0.34",
94
94
  "yaml-ast-parser": "0.0.43",
95
95
  "zod": "^3.25.76",
96
- "@redocly/api-docs": "0.2.0-next.4",
97
- "@redocly/asyncapi-docs": "1.14.0-next.4",
98
- "@redocly/config": "0.53.1",
99
- "@redocly/graphql-docs": "1.14.0-next.4",
100
- "@redocly/openapi-docs": "3.25.0-next.4",
96
+ "@redocly/api-docs": "0.2.0-next.6",
97
+ "@redocly/asyncapi-docs": "1.14.0-next.6",
98
+ "@redocly/config": "0.54.0",
99
+ "@redocly/graphql-docs": "1.14.0-next.6",
100
+ "@redocly/openapi-docs": "3.25.0-next.6",
101
101
  "@redocly/portal-legacy-ui": "0.19.0",
102
- "@redocly/portal-plugin-mock-server": "0.22.0-next.4",
103
- "@redocly/realm-asyncapi-sdk": "0.15.0-next.2",
104
- "@redocly/theme": "0.69.0-next.4"
102
+ "@redocly/portal-plugin-mock-server": "0.22.0-next.6",
103
+ "@redocly/realm-asyncapi-sdk": "0.15.0-next.3",
104
+ "@redocly/theme": "0.69.0-next.6"
105
105
  },
106
106
  "peerDependencies": {
107
107
  "react": "^19.2.7",