@redocly/reef 0.133.0-next.5 → 0.133.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @redocly/reef
2
2
 
3
+ ## 0.133.0-next.6
4
+
5
+ ### Patch Changes
6
+
7
+ - eeb767e9b48: Fixed an issue where preview login redirects failed when the branch hostname contained double hyphens.
8
+ - 7cd2d9f19e6: Fixed an issue in Realm Markdown image handling where inline `data:` image URLs were incorrectly treated as broken local routes.
9
+ - c9c36d6ac34: Fixed an issue where Typesense search didn't resolve types for curation fields.
10
+ - 7447d307450: Fixed security vulnerabilities `CVE-2026-44455`, `CVE-2026-44456`, `CVE-2026-44457`, `CVE-2026-44458` and `CVE-2026-44459` by upgrading `hono` to `4.12.18`.
11
+ - 46f103f0c48: Updated `@redocly/openapi-core` to version `2.30.5`.
12
+ - Updated dependencies [5e5d990eacb]
13
+ - Updated dependencies [46f103f0c48]
14
+ - @redocly/realm-asyncapi-sdk@0.11.0-next.4
15
+ - @redocly/openapi-docs@3.21.0-next.6
16
+ - @redocly/theme@0.65.0-next.5
17
+ - @redocly/portal-plugin-mock-server@0.18.0-next.6
18
+ - @redocly/asyncapi-docs@1.10.0-next.6
19
+ - @redocly/graphql-docs@1.10.0-next.6
20
+
3
21
  ## 0.133.0-next.5
4
22
 
5
23
  ### Minor Changes
@@ -1 +1 @@
1
- import{appendFile as E}from"node:fs/promises";import{existsSync as $}from"node:fs";import m from"node:path";import{Client as R}from"typesense";import{SEARCH_GROUP_FACET_FIELD as A,SEARCH_PRODUCT_FIELD as T,SEARCH_RBAC_FIELD as b,SEARCH_VERSION_FIELD as f}from"../../../../../constants/common.js";import{BASE_SEARCH_DOCUMENT as O,DISABLE_DEEP_LINK_IF_FIELDS_EXIST as P,HIGHLIGHTED_TEXT_MAX_LENGTH as F,SEARCH_DATA_EXPORT_FOLDER as S,SEARCH_DOCUMENT_METADATA_KEY as N,SEARCH_GROUP_LIMIT as C,SEARCH_MAX_FACET_VALUES as D,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as v}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as I}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as p}from"../../../../config/env-config.js";import{ensureDir as d}from"../../../../utils/index.js";class Y{#e=null;#r="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:T,type:"string",facet:!0,optional:!0},{name:f,type:"object",facet:!0,optional:!0},{name:b,type:"string[]",facet:!0},{name:"metadata_curated",type:"auto",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"auto",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"auto",facet:!1,optional:!0,queryable:!1}];#s=new Map;#n={ORGANIZATION_ID:p.ORGANIZATION_ID??"",PROJECT_ID:p.PROJECT_ID??"",TYPESENSE_API_URL:p.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:p.TYPESENSE_API_KEY??""};constructor(){if(!p.isBuildMode){for(const[e,t]of Object.entries(this.#n))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#r=`${this.#n.ORGANIZATION_ID}_${this.#n.PROJECT_ID}_`,this.#e=new R({nodes:[{url:this.#n.TYPESENSE_API_URL}],apiKey:this.#n.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#p(e)}async addDocuments(e,t){e.push(O);const{locale:o,outDir:n}=t,s=e.map(a=>{const r={...a},c=a[N];return c&&(c.curated&&(r.metadata_curated=c.curated),c.excludes&&(r.metadata_keywords_excludes=c.excludes),c.includes&&(r.metadata_keywords_includes=c.includes)),r}),i=this.#s.get(o)??[];this.#s.set(o,i.concat(s)),i.length+e.length>=v&&await this.exportDocuments(n)}async search(e){return await I("search",async t=>{const{query:o,locale:n,filter:s,loadMore:i,auth:a}=e,r=this.#c(n),c={collection:r,q:o||"*",query_by:this.#l(),max_facet_values:D};if(t?.setAttribute("collectionName",r),t?.setAttribute("locale",n),this.#e)if(i){const{groupKey:l,offset:u}=i,h={offset:u,filter_by:this.#o(a,s),facet_by:"*"};return t?.setAttribute("isLoadMore",!0),t?.setAttribute("filter",h.filter_by),this.#u(await this.#e.collections(r).documents().search({...c,...h}),l)}else{const l={group_by:this.#m(),group_limit:C,filter_by:this.#o(a,s)};t?.setAttribute("groups",l.group_by),t?.setAttribute("filter",l.filter_by);const u=[l,...this.#y(a,s)];return this.#f(await this.#e?.multiSearch.perform({searches:u},c),s)}else return{facets:{},documents:{}}})}#u(e,t){const o={facets:{},documents:{[t]:[]}};if(e.hits&&e.hits.length)for(const n of e.hits)o.documents[t].push({document:this.#a(n),highlight:this.#i(n)});return o}#f(e,t){const o={facets:{},documents:{}};for(const n of this.#_(t))o.documents[n]=[];if("results"in e)for(const n of e.results){if(n.facet_counts&&n.facet_counts.length)for(const s of n.facet_counts)o.facets[s.field_name]=s.counts.map(i=>({value:i.value,count:i.count}));if(n.grouped_hits&&n.grouped_hits.length)for(const s of n.grouped_hits){const i=s.group_key[0],a=[];for(const r of s.hits)a.push({document:this.#a(r),highlight:this.#i(r)});o.documents[i]=a}}return o}#a(e){return this.#h(e)}#i(e){const t={},o=[];for(const[n,s]of Object.entries(e.highlight??{}))if(Array.isArray(s)){if(n==="path"){const i=s,a=[];for(const r of i)a.push(r.snippet);t.path=a}else if(n==="parameters"){const i=s;for(const a of i){let r=!1;for(const[c,l]of Object.entries(a))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(r=!0);else l.matched_tokens?.length&&(r=!0);if(r){const c={name:a.name?.snippet||"",description:a.description?.snippet||"",place:a.place?.snippet||"",path:a.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[n]=s.snippet,o.push(n);for(const[n,s]of Object.entries(e.document))!o.includes(n)&&typeof s=="string"&&(t[n]=s.length>F?`${s.substring(0,F)}...`:s);return t.parameters||(t.parameters=[]),t}#h(e){let t;const o=Object.keys(e.highlight);for(const s of P)if(o.some(i=>i===s))return e.document;const n=e.highlight.parameters;if(n){for(const s of n)for(const[i,a]of Object.entries(s))if(i!=="deepLink"){if(Array.isArray(a)){for(const r of a)if(r.matched_tokens?.length){t=s.deepLink.snippet;break}}else if(a.matched_tokens?.length){t=s.deepLink.snippet;break}}}if(t){const s=t.split("#")[1];return{...e.document,url:`${e.document.url}#${s}`}}return e.document}async exportDocuments(e){const t='{"documents":[',o=d(m.join(e,S));for(const[n,s]of this.#s){if(s.length===0)continue;const i=d(m.join(o,`${n}.json`)),a=!$(i),r=JSON.stringify(s).substring(1).slice(0,-1),c=a?t+r:","+r;await E(i,c,{encoding:"utf8"}),this.#s.set(n,[])}}async exportIndexes(e){const t=d(m.join(e,S));for(const o of this.#s.keys()){const n=d(m.join(t,`${o}.json`)),s=`],"schemaFields":${JSON.stringify(this.#t)}}`;await E(n,s,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await I("search.facets",async o=>{const{locale:n,query:s,facetQuery:i,filter:a,field:r,auth:c}=e,l=this.#c(n),u={q:s||"*",query_by:this.#l(),facet_by:"*",facet_query:this.#d(i,r),filter_by:this.#o(c,a,r),max_facet_values:D};if(o?.setAttribute("collectionName",l),o?.setAttribute("query",u.q),o?.setAttribute("facetQuery",u.facet_query),o?.setAttribute("filter",u.filter_by),this.#e){const h={},_=await this.#e.collections(l).documents().search(u);if(_.facet_counts&&_.facet_counts.length)for(const y of _.facet_counts)h[y.field_name]=y.counts.map(g=>({value:g.value,count:g.count,isCounterVisible:!!s||(a?.length||0)>0}));return h}else return{}})}#c(e){return`${this.#r}${e}`}#p(e){for(const[t,{queryable:o}]of e)this.#t.find(n=>n.name===t)||this.#t.push({queryable:o,name:t,type:"string",facet:!0,optional:!0})}#l(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#m(){return this.#t.filter(e=>e.facet&&e.name===A).map(e=>e.name).join(",")}#o(e,t,o){const n=`${b}:[${e.teams.map(i=>`'${i}'`).join(", ")}]`;let s=`${f}.isDefault:true`;if(t&&t.length){const i=t.filter(r=>r.field!==o&&r.field!==f).map(r=>{const c=r.values.map(l=>`'${l}'`);return c.length?`${r.field}:[${c.join(", ")}]`:""}).join(" && "),a=t.find(r=>r.field===f);if(a&&a.values.length&&a.values.length===2){const r=a.values[0],c=a.values[1],l=`(${f}.folderId:! ${r} && ${f}.isDefault:true)`,u=`(${f}.folderId:${r} && ${f}.version:${c})`;s=`(${l} || ${u})`}return i?`${n} && ${i} && ${s}`:`${n} && ${s}`}else return`${n} && ${s}`}#d(e,t){return e&&t?`${t}:${e}`:""}#_(e){const t=[];if(e&&e.length)for(const o of e)o.field===A&&t.push(...o.values);return t}#y(e,t){const o=[],n=this.#t.filter(s=>s.facet);for(const s of n){const i={facet_by:s.name,filter_by:this.#o(e,t,s.name)};o.push(i)}return o}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(o=>{o.values=[]}),e.setSearchFacets(t)}}export{Y as Typesense};
1
+ import{appendFile as E}from"node:fs/promises";import{existsSync as $}from"node:fs";import m from"node:path";import{Client as R}from"typesense";import{SEARCH_GROUP_FACET_FIELD as A,SEARCH_PRODUCT_FIELD as T,SEARCH_RBAC_FIELD as b,SEARCH_VERSION_FIELD as f}from"../../../../../constants/common.js";import{BASE_SEARCH_DOCUMENT as O,DISABLE_DEEP_LINK_IF_FIELDS_EXIST as P,HIGHLIGHTED_TEXT_MAX_LENGTH as F,SEARCH_DATA_EXPORT_FOLDER as S,SEARCH_DOCUMENT_METADATA_KEY as N,SEARCH_GROUP_LIMIT as C,SEARCH_MAX_FACET_VALUES as D,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as v}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as I}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as p}from"../../../../config/env-config.js";import{ensureDir as d}from"../../../../utils/index.js";class Y{#e=null;#o="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:T,type:"string",facet:!0,optional:!0},{name:f,type:"object",facet:!0,optional:!0},{name:b,type:"string[]",facet:!0},{name:"metadata_curated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"string[]",facet:!1,optional:!0,queryable:!1}];#s=new Map;#n={ORGANIZATION_ID:p.ORGANIZATION_ID??"",PROJECT_ID:p.PROJECT_ID??"",TYPESENSE_API_URL:p.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:p.TYPESENSE_API_KEY??""};constructor(){if(!p.isBuildMode){for(const[e,t]of Object.entries(this.#n))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#o=`${this.#n.ORGANIZATION_ID}_${this.#n.PROJECT_ID}_`,this.#e=new R({nodes:[{url:this.#n.TYPESENSE_API_URL}],apiKey:this.#n.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#p(e)}async addDocuments(e,t){e.push(O);const{locale:r,outDir:n}=t,s=e.map(a=>{const o={...a},c=a[N];return c&&(c.curated&&(o.metadata_curated=c.curated),c.excludes&&(o.metadata_keywords_excludes=c.excludes),c.includes&&(o.metadata_keywords_includes=c.includes)),o}),i=this.#s.get(r)??[];this.#s.set(r,i.concat(s)),i.length+e.length>=v&&await this.exportDocuments(n)}async search(e){return await I("search",async t=>{const{query:r,locale:n,filter:s,loadMore:i,auth:a}=e,o=this.#c(n),c={collection:o,q:r||"*",query_by:this.#l(),max_facet_values:D};if(t?.setAttribute("collectionName",o),t?.setAttribute("locale",n),this.#e)if(i){const{groupKey:l,offset:u}=i,h={offset:u,filter_by:this.#r(a,s),facet_by:"*"};return t?.setAttribute("isLoadMore",!0),t?.setAttribute("filter",h.filter_by),this.#u(await this.#e.collections(o).documents().search({...c,...h}),l)}else{const l={group_by:this.#m(),group_limit:C,filter_by:this.#r(a,s)};t?.setAttribute("groups",l.group_by),t?.setAttribute("filter",l.filter_by);const u=[l,...this.#y(a,s)];return this.#f(await this.#e?.multiSearch.perform({searches:u},c),s)}else return{facets:{},documents:{}}})}#u(e,t){const r={facets:{},documents:{[t]:[]}};if(e.hits&&e.hits.length)for(const n of e.hits)r.documents[t].push({document:this.#a(n),highlight:this.#i(n)});return r}#f(e,t){const r={facets:{},documents:{}};for(const n of this.#_(t))r.documents[n]=[];if("results"in e)for(const n of e.results){if(n.facet_counts&&n.facet_counts.length)for(const s of n.facet_counts)r.facets[s.field_name]=s.counts.map(i=>({value:i.value,count:i.count}));if(n.grouped_hits&&n.grouped_hits.length)for(const s of n.grouped_hits){const i=s.group_key[0],a=[];for(const o of s.hits)a.push({document:this.#a(o),highlight:this.#i(o)});r.documents[i]=a}}return r}#a(e){return this.#h(e)}#i(e){const t={},r=[];for(const[n,s]of Object.entries(e.highlight??{}))if(Array.isArray(s)){if(n==="path"){const i=s,a=[];for(const o of i)a.push(o.snippet);t.path=a}else if(n==="parameters"){const i=s;for(const a of i){let o=!1;for(const[c,l]of Object.entries(a))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(o=!0);else l.matched_tokens?.length&&(o=!0);if(o){const c={name:a.name?.snippet||"",description:a.description?.snippet||"",place:a.place?.snippet||"",path:a.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[n]=s.snippet,r.push(n);for(const[n,s]of Object.entries(e.document))!r.includes(n)&&typeof s=="string"&&(t[n]=s.length>F?`${s.substring(0,F)}...`:s);return t.parameters||(t.parameters=[]),t}#h(e){let t;const r=Object.keys(e.highlight);for(const s of P)if(r.some(i=>i===s))return e.document;const n=e.highlight.parameters;if(n){for(const s of n)for(const[i,a]of Object.entries(s))if(i!=="deepLink"){if(Array.isArray(a)){for(const o of a)if(o.matched_tokens?.length){t=s.deepLink.snippet;break}}else if(a.matched_tokens?.length){t=s.deepLink.snippet;break}}}if(t){const s=t.split("#")[1];return{...e.document,url:`${e.document.url}#${s}`}}return e.document}async exportDocuments(e){const t='{"documents":[',r=d(m.join(e,S));for(const[n,s]of this.#s){if(s.length===0)continue;const i=d(m.join(r,`${n}.json`)),a=!$(i),o=JSON.stringify(s).substring(1).slice(0,-1),c=a?t+o:","+o;await E(i,c,{encoding:"utf8"}),this.#s.set(n,[])}}async exportIndexes(e){const t=d(m.join(e,S));for(const r of this.#s.keys()){const n=d(m.join(t,`${r}.json`)),s=`],"schemaFields":${JSON.stringify(this.#t)}}`;await E(n,s,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await I("search.facets",async r=>{const{locale:n,query:s,facetQuery:i,filter:a,field:o,auth:c}=e,l=this.#c(n),u={q:s||"*",query_by:this.#l(),facet_by:"*",facet_query:this.#d(i,o),filter_by:this.#r(c,a,o),max_facet_values:D};if(r?.setAttribute("collectionName",l),r?.setAttribute("query",u.q),r?.setAttribute("facetQuery",u.facet_query),r?.setAttribute("filter",u.filter_by),this.#e){const h={},_=await this.#e.collections(l).documents().search(u);if(_.facet_counts&&_.facet_counts.length)for(const y of _.facet_counts)h[y.field_name]=y.counts.map(g=>({value:g.value,count:g.count,isCounterVisible:!!s||(a?.length||0)>0}));return h}else return{}})}#c(e){return`${this.#o}${e}`}#p(e){for(const[t,{queryable:r}]of e)this.#t.find(n=>n.name===t)||this.#t.push({queryable:r,name:t,type:"string",facet:!0,optional:!0})}#l(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#m(){return this.#t.filter(e=>e.facet&&e.name===A).map(e=>e.name).join(",")}#r(e,t,r){const n=`${b}:[${e.teams.map(i=>`'${i}'`).join(", ")}]`;let s=`${f}.isDefault:true`;if(t&&t.length){const i=t.filter(o=>o.field!==r&&o.field!==f).map(o=>{const c=o.values.map(l=>`'${l}'`);return c.length?`${o.field}:[${c.join(", ")}]`:""}).join(" && "),a=t.find(o=>o.field===f);if(a&&a.values.length&&a.values.length===2){const o=a.values[0],c=a.values[1],l=`(${f}.folderId:! ${o} && ${f}.isDefault:true)`,u=`(${f}.folderId:${o} && ${f}.version:${c})`;s=`(${l} || ${u})`}return i?`${n} && ${i} && ${s}`:`${n} && ${s}`}else return`${n} && ${s}`}#d(e,t){return e&&t?`${t}:${e}`:""}#_(e){const t=[];if(e&&e.length)for(const r of e)r.field===A&&t.push(...r.values);return t}#y(e,t){const r=[],n=this.#t.filter(s=>s.facet);for(const s of n){const i={facet_by:s.name,filter_by:this.#r(e,t,s.name)};r.push(i)}return r}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(r=>{r.values=[]}),e.setSearchFacets(t)}}export{Y as Typesense};
@@ -1,12 +1,12 @@
1
- import"../node-crypto-polyfill.js";import{DOMParser as b}from"@xmldom/xmldom";import{SignedXml as B}from"xml-crypto";import F from"xpath";import{deflateSync as H,inflateSync as J}from"fflate";import{createHash as q}from"crypto";import{ulid as W}from"ulid";import{AuthProviderType as u,DEFAULT_TEAM_CLAIM_NAME as K}from"@redocly/config";import{AUTH_URL as Y,JWT_SECRET_KEY as L}from"../constants/common.js";import{envConfig as Q}from"../config/env-config.js";import{getPathPrefix as X,withPathPrefix as G}from"@redocly/theme/core/utils";import{DEFAULT_AUTHENTICATED_TEAM as Z,REQUIRED_OIDC_SCOPES as R,ServerRoutes as N}from"../../constants/common.js";import{appendQueryParams as ee}from"../../utils/url/append-query-params.js";import{logger as te}from"../tools/notifiers/logger.js";import{randomString as ne}from"../utils/crypto/random-string.js";import{randomUUID as U}from"../utils/crypto/random-uuid.js";import{AlgorithmTypes as w,JwtTokenExpired as oe}from"./jwt/types.js";import*as f from"./jwt/jwt.js";import{parseTeamClaimToArray as re}from"../utils/index.js";import{arrayBufferToBase64 as ae,decodeBase64 as P,encodeBase64URL as se,urlSafeBase64 as v}from"./jwt/encode.js";import{formatSamlCertificate as ce}from"./utils/format-saml-certificate.js";function E(e){return e?.type===u.OIDC}function ie(e){return e?.type===u.SAML2}async function Je(e,t){if(E(t))return ue(e,t);if(ie(t))return de(e,t)}async function ue(e,t){const o=await V(e,t),n=new Set((t.scopes||[]).concat(R)),r=t.authorizationRequestCustomParams||{};return{type:u.OIDC,idpId:e,name:"OAuth provider",authorizationEndpoint:o.authorization_endpoint,clientId:t.clientId,responseType:"code",scope:Array.from(n).join(" "),extraParams:r,pkce:t.pkce}}function de(e,t){return{type:u.SAML2,idpId:e,name:"SAML2 provider",ssoUrl:t.ssoUrl,issuerId:t.issuerId,entityId:t.entityId||t.issuerId}}async function qe(e,t,o,n,r={}){const a=new Set((n.scopes||[]).concat(R));return await fetch(e,{method:"POST",body:new URLSearchParams({client_id:n.clientId,scope:Array.from(a).join(" "),code:t,redirect_uri:j(o),grant_type:"authorization_code",...n.clientSecret?{client_secret:n.clientSecret}:{},...r}).toString(),headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"}}).then(s=>s.json())}function le(e,{authorizationEndpoint:t,clientId:o,responseType:n,scope:r,extraParams:a,idpId:s,pkce:d},m,A,p){if(!t||!o||!n||!r)return{loginUrl:void 0};const c=new URL(t),h=p?.redirectUriOverride??`${e}${G(N.OIDC_CALLBACK)}`,_={state:U(),idpId:s,redirectUri:h,redirectTo:m,branch:p?.branchOverride??me(e),inviteCode:A,source:p?.sourceOverride??"portal",uiLocales:p?.uiLocales},y={};if(d){const l=v(ne(50)),g=v(q("sha256").update(l).digest("base64")),x="S256";c.searchParams.append("code_challenge",g),c.searchParams.append("code_challenge_method",x),y.code_verifier={value:l,options:{secure:!0,httpOnly:!0,expires:new Date(Date.now()+1e3*60*10),path:X()||"/"}}}c.searchParams.append("client_id",o),c.searchParams.append("scope",r),c.searchParams.append("response_type",n),c.searchParams.append("redirect_uri",j(h)),c.searchParams.append("state",se(JSON.stringify(_))),p?.uiLocales&&c.searchParams.append("ui_locales",p.uiLocales);for(const l in a)a[l]!==void 0&&c.searchParams.append(l,a[l]);return{loginUrl:c.toString(),cookies:y}}function We(e,t,o,n){const r=new URL(e);return r.searchParams.append("post_logout_redirect_uri",t),n&&r.searchParams.append("state",n),r.searchParams.append("id_token_hint",o),r.toString()}async function Ke(e){const t=Math.floor(Date.now()/1e3),o=t+(e.ttlSec??600);return f.sign({type:"mcp_auth_code",client_id:e.clientId,redirect_uri:e.redirectUri,id_token:e.idToken,...e.idpAccessToken?{idp_access_token:e.idpAccessToken}:{},...e.codeChallenge?{code_challenge:e.codeChallenge}:{},...e.codeChallengeMethod?{code_challenge_method:e.codeChallengeMethod}:{},iat:t,exp:o},L,w.HS256)}async function Ye(e){await f.verify(e,L,w.HS256);const{payload:t}=f.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}function Qe(e){const t=e||W(),o=t.startsWith("mcp_")?t:`mcp_${t}`;return{id:o,object:"mcp_session",uri:`urn:redocly:realm:mcp:session:${o}`}}function j(e){return e.match(/^https:\/\/preview-[^\.]+--/)?"https://previewauth--"+e.split("--")[1]:e.match(/^(https:\/\/[^\.]+)--[^\.]+\.preview\./)?e.replace(/^(https:\/\/[^\.]+?)--[^\.]+\.preview\./,"$1.previewauth."):e}function me(e){return e.match(/^(https:\/\/[^\.]+)--([^\.]+)\.preview\./)?.[2]||void 0}function pe(e){return e.type===u.OIDC}function fe(e){return e.type===u.SAML2}function Xe(e,t,o,n,r){return pe(e)?le(t,e,o,n,{uiLocales:r}):fe(e)?he(t,e,o,n,r):{}}function he(e,t,o,n,r){const s=`<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
1
+ import"../node-crypto-polyfill.js";import{DOMParser as b}from"@xmldom/xmldom";import{SignedXml as W}from"xml-crypto";import J from"xpath";import{deflateSync as q,inflateSync as K}from"fflate";import{createHash as Y}from"crypto";import{ulid as Q}from"ulid";import{AuthProviderType as u,DEFAULT_TEAM_CLAIM_NAME as X}from"@redocly/config";import{AUTH_URL as G,JWT_SECRET_KEY as L}from"../constants/common.js";import{envConfig as Z}from"../config/env-config.js";import{getPathPrefix as ee,withPathPrefix as te}from"@redocly/theme/core/utils";import{DEFAULT_AUTHENTICATED_TEAM as ne,REQUIRED_OIDC_SCOPES as D,ServerRoutes as v}from"../../constants/common.js";import{appendQueryParams as re}from"../../utils/url/append-query-params.js";import{parseHttpsUrl as R}from"../../utils/url/parse-https-url.js";import{logger as oe}from"../tools/notifiers/logger.js";import{randomString as ae}from"../utils/crypto/random-string.js";import{randomUUID as U}from"../utils/crypto/random-uuid.js";import{AlgorithmTypes as w,JwtTokenExpired as se}from"./jwt/types.js";import*as f from"./jwt/jwt.js";import{parseTeamClaimToArray as ie}from"../utils/index.js";import{arrayBufferToBase64 as ce,decodeBase64 as N,encodeBase64URL as ue,urlSafeBase64 as j}from"./jwt/encode.js";import{formatSamlCertificate as le}from"./utils/format-saml-certificate.js";function E(e){return e?.type===u.OIDC}function de(e){return e?.type===u.SAML2}async function Qe(e,t){if(E(t))return me(e,t);if(de(t))return pe(e,t)}async function me(e,t){const n=await H(e,t),r=new Set((t.scopes||[]).concat(D)),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 pe(e,t){return{type:u.SAML2,idpId:e,name:"SAML2 provider",ssoUrl:t.ssoUrl,issuerId:t.issuerId,entityId:t.entityId||t.issuerId}}async function Xe(e,t,n,r,o={}){const a=new Set((r.scopes||[]).concat(D));return await fetch(e,{method:"POST",body:new URLSearchParams({client_id:r.clientId,scope:Array.from(a).join(" "),code:t,redirect_uri:V(n),grant_type:"authorization_code",...r.clientSecret?{client_secret:r.clientSecret}:{},...o}).toString(),headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"}}).then(s=>s.json())}function fe(e,{authorizationEndpoint:t,clientId:n,responseType:r,scope:o,extraParams:a,idpId:s,pkce:l},m,A,p){if(!t||!n||!r||!o)return{loginUrl:void 0};const i=new URL(t),h=p?.redirectUriOverride??`${e}${te(v.OIDC_CALLBACK)}`,_={state:U(),idpId:s,redirectUri:h,redirectTo:m,branch:p?.branchOverride??he(e),inviteCode:A,source:p?.sourceOverride??"portal",uiLocales:p?.uiLocales},y={};if(l){const d=j(ae(50)),g=j(Y("sha256").update(d).digest("base64")),x="S256";i.searchParams.append("code_challenge",g),i.searchParams.append("code_challenge_method",x),y.code_verifier={value:d,options:{secure:!0,httpOnly:!0,expires:new Date(Date.now()+1e3*60*10),path:ee()||"/"}}}i.searchParams.append("client_id",n),i.searchParams.append("scope",o),i.searchParams.append("response_type",r),i.searchParams.append("redirect_uri",V(h)),i.searchParams.append("state",ue(JSON.stringify(_))),p?.uiLocales&&i.searchParams.append("ui_locales",p.uiLocales);for(const d in a)a[d]!==void 0&&i.searchParams.append(d,a[d]);return{loginUrl:i.toString(),cookies:y}}function Ge(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 Ze(e){const t=Math.floor(Date.now()/1e3),n=t+(e.ttlSec??600);return f.sign({type:"mcp_auth_code",client_id:e.clientId,redirect_uri:e.redirectUri,id_token:e.idToken,...e.idpAccessToken?{idp_access_token:e.idpAccessToken}:{},...e.codeChallenge?{code_challenge:e.codeChallenge}:{},...e.codeChallengeMethod?{code_challenge_method:e.codeChallengeMethod}:{},iat:t,exp:n},L,w.HS256)}async function et(e){await f.verify(e,L,w.HS256);const{payload:t}=f.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}function tt(e){const t=e||Q(),n=t.startsWith("mcp_")?t:`mcp_${t}`;return{id:n,object:"mcp_session",uri:`urn:redocly:realm:mcp:session:${n}`}}function V(e){const t=R(e);if(!t)return e;const n=ye(t.hostname);if(n)return t.hostname=`previewauth--${n.previewBranch}${n.after}`,$(e,t);const r=B(t.hostname);return r?(t.hostname=`${r.projectSlug}.previewauth.${r.after}`,$(e,t)):e}function he(e){const t=R(e);if(t)return B(t.hostname)?.previewBranch}function $(e,t){return e.replace(/^https:\/\/[^/?#]+/i,`https://${t.host}`)}function B(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 a=n.slice(0,o),s=n.slice(o+2);return!a||!s||s.includes(".")?null:{projectSlug:a,previewBranch:s,after:r}}function ye(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 a=t===-1?"":e.slice(t);return{previewBranch:o,after:a}}function we(e){return e.type===u.OIDC}function Se(e){return e.type===u.SAML2}function nt(e,t,n,r,o){return we(e)?fe(t,e,n,r,{uiLocales:o}):Se(e)?Ae(t,e,n,r,o):{}}function Ae(e,t,n,r,o){const s=`<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}${N.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>`,d=ye(s);return{loginUrl:ee(t.ssoUrl,{SAMLRequest:d,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:o,inviteCode:n,source:"portal",uiLocales:r})})}}function ye(e){return ae(H(new TextEncoder().encode(e)).buffer)}function Ge(e){const t=P(e);if(t.startsWith("<samlp:Response")||t.indexOf("<saml2p:Response")>-1)return t;const o=J(new Uint8Array(atob(e).split("").map(n=>n.charCodeAt(0))));return new TextDecoder().decode(o)}function Ze(e){try{return JSON.parse(P(e||""))}catch{throw new Error("Invalid OAuth2 state")}}function et(e){const t=new b().parseFromString(e,"application/xml"),n=i(t,"//*[local-name(.)='StatusCode']/@Value")[0]?.nodeValue?.endsWith("Success")||!1,a=i(t,"//*[local-name(.)='Response']/@Destination")[0]?.nodeValue||"",s=i(t,"//*[local-name(.)='Assertion']//*[local-name(.)='Issuer']/text()")[0],d=s&&s.nodeValue||void 0,m=i(t,"//*[local-name(.)='Audience']/text()")[0],A=m&&m.nodeValue||void 0,c=i(t,"//*[local-name(.)='Assertion']//*[local-name(.)='X509Certificate']/text()")[0]?.nodeValue||"",h=i(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/text()")[0],_=h&&h.nodeValue||"",y=i(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/@Format")[0],l=y&&y.nodeValue||"",g=i(t,"//*[local-name(.)='Conditions']/@NotOnOrAfter")[0],x=we(g),M={},k=i(t,"//*[local-name(.)='AttributeStatement']//*[local-name(.)='Attribute']");if(k.length)for(const T of k){const D=i(T,"./@Name")[0];if(D.nodeValue){const O=i(T,"./*[local-name(.)='AttributeValue']/text()")[0];O?.nodeValue&&(M[D.nodeValue]=O.nodeValue)}}return{uid:_,success:n,expiresAt:x,issuerId:d,entityId:A,attrs:M,cert:c,nameFormat:l,destination:a}}function we(e){const t=typeof e?.nodeValue=="string"&&I(Date.parse(e.nodeValue)),o=I(Date.now()),n=I(Date.now()+720*60*1e3);return t?t>o&&t<n?n:t:o}function I(e){return Math.floor(e/1e3)}const C={},S={jwks:{}};async function V(e,t){if(!C[e]){const o=t.configurationUrl?await $(t.configurationUrl):t.configuration;C[e]=Se()?Ae(o):o}return C[e]}function Se(){const e=Q.REDOCLY_ENFORCE_RESIDENCY;return!!e&&e.includes("host.docker.internal")}function Ae(e){if(typeof e!="object"||e===null)return e;const t={...e};for(const o of Object.keys(t)){const n=t[o];typeof n=="string"&&n.includes("://localhost")&&(t[o]=n.replace("://localhost","://host.docker.internal"))}return t}async function _e(e){for(const t of Object.keys(e)){const o=e[t];if(!E(o))continue;const n=await V(t,o);if(n.jwks_uri){const r=await $(n.jwks_uri);for(const a of r.keys)S.jwks[a.kid]={...a,idpId:t}}}}async function $(e){return fetch(e,{headers:{Accept:"application/json"}}).then(t=>t.json())}async function tt(e){return fetch(`${Y}/oidc/userinfo`,{headers:{Accept:"application/json",Authorization:`Bearer ${e}`}}).then(t=>t.status===200?t.json():void 0).catch(()=>{})}function nt(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(n=>ge(t.hostname,n))}function ge(e,t){return e===t||e.endsWith(`.${t}`)}async function ot(e,t){const o=new b().parseFromString(e,"application/xml"),n=i(o,"//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0];if(!n)throw new Error("Cannot find Signature in the SAML response");const r=ce(t),a=new B({publicCert:r});a.loadSignature(n);try{return a.checkSignature(e)}catch{return!1}}function rt(e,t,o,n){t==="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"&&(e=o["http://schemas.microsoft.com/identity/claims/objectidentifier"]);let r;(t==="urn:oasis:names:tc:SAML:2.0:nameid-format:email"||t==="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")&&(r=e),t==="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"&&e?.match(/.+@.+/)&&(r=e);const a=o["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],s=a?.match(/.+@.+/);return r=r||o["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]||(s?a:void 0),r=r?.toLowerCase(),{sub:e,given_name:o["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"],family_name:o["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"],name:o["http://schemas.microsoft.com/identity/claims/displayname"]||a,email:r,email_verified:!0,teams:n?re(o[n]):[]}}function z(e,t={}){return e.map(o=>t[o]||o)}async function at(e,t){if(!t)return{};const o=t.authorization;if(!o)return{};try{const n=f.decode(o);if(n.header.alg===w.RS256){S.jwks[n.header.kid]===void 0&&await _e(e);const m=S.jwks[n.header.kid];if(!m)return S.jwks[n.header.kid]=null,{};await f.verify(o,m,w.RS256)}else await f.verify(o,L,w.HS256);const r=n.payload.idpId||S.jwks[n.header.kid]?.idpId,a=e[r]||{},s=Ie(a),d=Le(a);return{...n.payload,email:n.payload.email?.toLowerCase(),idpId:r,teams:Array.from(new Set([...z(n.payload.teams||[],d),..."defaultTeams"in a&&a.defaultTeams||[],...z("teamsClaimName"in a&&n.payload[s||""]||[],d),Z])),name:xe(n.payload),isAuthenticated:!0,idpAccessToken:n.payload.idp_access_token||t.idp_access_token,federatedAccessToken:t.federated_access_token,federatedIdToken:t.federated_id_token,authCookie:o}}catch(n){n instanceof oe||te.error("Malformed JWT token: %s",n.message)}return{}}function xe(e){return(e.firstName&&e.lastName?`${e.firstName} ${e.lastName}`:e.name||e.given_name||e.firstName||e.lastName)||e.email}function Le(e){switch(e.type){case u.SAML2:return e.teamsAttributeMap;case u.OIDC:return e.teamsClaimMap;default:return}}function Ie(e){switch(e.type){case u.SAML2:return e.teamsAttributeName;case u.OIDC:return e.teamsClaimName;default:return K}}function i(e,t){return F.select(t,e)||[]}export{Xe as buildLoginUrl,le as buildOidcLoginUrl,We as buildOidcLogoutUrl,he as buildSAML2LoginUrl,Ke as createMcpAuthorizationCode,Qe as createMcpSessionResource,Ge as decodeSamlResponse,ye as encodeSAML2,rt as extractUserClaims,Je as getAuthProviderLoginParams,ue as getOidcLoginParams,V as getOidcMetadata,tt as getRedoclyTokenPayload,de as getSaml2LoginParams,at as getUserParamsFromCookies,xe as getUsernameFromPayload,E as isOidcProviderConfig,nt as isRedoclySso,ie as isSaml2ProviderConfig,qe as oidcExchangeCodeForToken,S as oidcJwksCache,C as oidcMetadataCache,Ze as parseOidcState,me as parsePreviewBranch,et as parseSamlResponse,j as rewritePreviewAuthRedirectUri,Ye as verifyMcpAuthorizationCode,ot as verifySAMLResponse};
12
+ </samlp:AuthnRequest>`,l=_e(s);return{loginUrl:re(t.ssoUrl,{SAMLRequest:l,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:n,inviteCode:r,source:"portal",uiLocales:o})})}}function _e(e){return ce(q(new TextEncoder().encode(e)).buffer)}function rt(e){const t=N(e);if(t.startsWith("<samlp:Response")||t.indexOf("<saml2p:Response")>-1)return t;const n=K(new Uint8Array(atob(e).split("").map(r=>r.charCodeAt(0))));return new TextDecoder().decode(n)}function ot(e){try{return JSON.parse(N(e||""))}catch{throw new Error("Invalid OAuth2 state")}}function at(e){const t=new b().parseFromString(e,"application/xml"),r=c(t,"//*[local-name(.)='StatusCode']/@Value")[0]?.nodeValue?.endsWith("Success")||!1,a=c(t,"//*[local-name(.)='Response']/@Destination")[0]?.nodeValue||"",s=c(t,"//*[local-name(.)='Assertion']//*[local-name(.)='Issuer']/text()")[0],l=s&&s.nodeValue||void 0,m=c(t,"//*[local-name(.)='Audience']/text()")[0],A=m&&m.nodeValue||void 0,i=c(t,"//*[local-name(.)='Assertion']//*[local-name(.)='X509Certificate']/text()")[0]?.nodeValue||"",h=c(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/text()")[0],_=h&&h.nodeValue||"",y=c(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/@Format")[0],d=y&&y.nodeValue||"",g=c(t,"//*[local-name(.)='Conditions']/@NotOnOrAfter")[0],x=ge(g),C={},M=c(t,"//*[local-name(.)='AttributeStatement']//*[local-name(.)='Attribute']");if(M.length)for(const O of M){const P=c(O,"./@Name")[0];if(P.nodeValue){const T=c(O,"./*[local-name(.)='AttributeValue']/text()")[0];T?.nodeValue&&(C[P.nodeValue]=T.nodeValue)}}return{uid:_,success:r,expiresAt:x,issuerId:l,entityId:A,attrs:C,cert:i,nameFormat:d,destination:a}}function ge(e){const t=typeof e?.nodeValue=="string"&&I(Date.parse(e.nodeValue)),n=I(Date.now()),r=I(Date.now()+720*60*1e3);return t?t>n&&t<r?r:t:n}function I(e){return Math.floor(e/1e3)}const k={},S={jwks:{}};async function H(e,t){if(!k[e]){const n=t.configurationUrl?await z(t.configurationUrl):t.configuration;k[e]=xe()?Le(n):n}return k[e]}function xe(){const e=Z.REDOCLY_ENFORCE_RESIDENCY;return!!e&&e.includes("host.docker.internal")}function Le(e){if(typeof e!="object"||e===null)return e;const t={...e};for(const n of Object.keys(t)){const r=t[n];typeof r=="string"&&r.includes("://localhost")&&(t[n]=r.replace("://localhost","://host.docker.internal"))}return t}async function Ie(e){for(const t of Object.keys(e)){const n=e[t];if(!E(n))continue;const r=await H(t,n);if(r.jwks_uri){const o=await z(r.jwks_uri);for(const a of o.keys)S.jwks[a.kid]={...a,idpId:t}}}}async function z(e){return fetch(e,{headers:{Accept:"application/json"}}).then(t=>t.json())}async function st(e){return fetch(`${G}/oidc/userinfo`,{headers:{Accept:"application/json",Authorization:`Bearer ${e}`}}).then(t=>t.status===200?t.json():void 0).catch(()=>{})}function it(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=>ke(t.hostname,r))}function ke(e,t){return e===t||e.endsWith(`.${t}`)}async function ct(e,t){const n=new b().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=le(t),a=new W({publicCert:o});a.loadSignature(r);try{return a.checkSignature(e)}catch{return!1}}function ut(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 a=n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],s=a?.match(/.+@.+/);return o=o||n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]||(s?a: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"]||a,email:o,email_verified:!0,teams:r?ie(n[r]):[]}}function F(e,t={}){return e.map(n=>t[n]||n)}async function lt(e,t){if(!t)return{};const n=t.authorization;if(!n)return{};try{const r=f.decode(n);if(r.header.alg===w.RS256){S.jwks[r.header.kid]===void 0&&await Ie(e);const m=S.jwks[r.header.kid];if(!m)return S.jwks[r.header.kid]=null,{};await f.verify(n,m,w.RS256)}else await f.verify(n,L,w.HS256);const o=r.payload.idpId||S.jwks[r.header.kid]?.idpId,a=e[o]||{},s=Oe(a),l=Me(a);return{...r.payload,email:r.payload.email?.toLowerCase(),idpId:o,teams:Array.from(new Set([...F(r.payload.teams||[],l),..."defaultTeams"in a&&a.defaultTeams||[],...F("teamsClaimName"in a&&r.payload[s||""]||[],l),ne])),name:Ce(r.payload),isAuthenticated:!0,idpAccessToken:r.payload.idp_access_token||t.idp_access_token,federatedAccessToken:t.federated_access_token,federatedIdToken:t.federated_id_token,authCookie:n}}catch(r){r instanceof se||oe.error("Malformed JWT token: %s",r.message)}return{}}function Ce(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 Oe(e){switch(e.type){case u.SAML2:return e.teamsAttributeName;case u.OIDC:return e.teamsClaimName;default:return X}}function c(e,t){return J.select(t,e)||[]}export{nt as buildLoginUrl,fe as buildOidcLoginUrl,Ge as buildOidcLogoutUrl,Ae as buildSAML2LoginUrl,Ze as createMcpAuthorizationCode,tt as createMcpSessionResource,rt as decodeSamlResponse,_e as encodeSAML2,ut as extractUserClaims,Qe as getAuthProviderLoginParams,me as getOidcLoginParams,H as getOidcMetadata,st as getRedoclyTokenPayload,pe as getSaml2LoginParams,lt as getUserParamsFromCookies,Ce as getUsernameFromPayload,E as isOidcProviderConfig,it as isRedoclySso,de as isSaml2ProviderConfig,Xe as oidcExchangeCodeForToken,S as oidcJwksCache,k as oidcMetadataCache,ot as parseOidcState,he as parsePreviewBranch,at as parseSamlResponse,V as rewritePreviewAuthRedirectUri,et as verifyMcpAuthorizationCode,ct as verifySAMLResponse};
@@ -6,6 +6,7 @@
6
6
  * - It does not start with a protocol (e.g., `http://`, `https://`, `ftp://`, etc.).
7
7
  * - It does not start with `//` (protocol-relative URL).
8
8
  * - It does not start with `mailto:`.
9
+ * - It does not start with `data:` or `blob:` (inline / object URLs, not site paths).
9
10
  *
10
11
  * @param path - The input string (or null/undefined).
11
12
  * @returns `true` if the path is a local link, otherwise `false`.
@@ -1 +1 @@
1
- const s=t=>t!=null&&!t.match(/^[a-z]+:\/\//)&&!t.startsWith("//")&&!t.startsWith("mailto:");export{s as isLocalLink};
1
+ const s=t=>t!=null&&!t.match(/^[a-z]+:\/\//)&&!t.startsWith("//")&&!t.startsWith("mailto:")&&!t.startsWith("data:")&&!t.startsWith("blob:");export{s as isLocalLink};
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Parses an absolute URL string; returns it only when the scheme is `https:`.
3
+ * Returns `null` on parse errors or for non-https schemes (e.g. `http:`, relative input).
4
+ *
5
+ * @param uri - Absolute URL string to parse.
6
+ * @returns A `URL` when the string is valid and uses `https:`; otherwise `null`.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * parseHttpsUrl('https://example.com/path');
11
+ * // URL { href: 'https://example.com/path' }
12
+ *
13
+ * parseHttpsUrl('http://example.com');
14
+ * // null
15
+ * ```
16
+ */
17
+ export declare function parseHttpsUrl(uri: string): URL | null;
18
+ //# sourceMappingURL=parse-https-url.d.ts.map
@@ -0,0 +1 @@
1
+ function n(r){try{const t=new URL(r);return t.protocol==="https:"?t:null}catch{return null}}export{n as parseHttpsUrl};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/reef",
3
- "version": "0.133.0-next.5",
3
+ "version": "0.133.0-next.6",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,7 +29,7 @@
29
29
  "@opentelemetry/sdk-trace-web": "2.6.1",
30
30
  "@opentelemetry/semantic-conventions": "1.40.0",
31
31
  "@redocly/ajv": "8.18.0",
32
- "@redocly/openapi-core": "2.30.3",
32
+ "@redocly/openapi-core": "2.30.5",
33
33
  "@shikijs/transformers": "3.21.0",
34
34
  "@tanstack/react-query": "5.62.3",
35
35
  "@tanstack/react-table": "8.21.3",
@@ -53,7 +53,7 @@
53
53
  "flexsearch": "0.7.43",
54
54
  "graphql": "16.12.0",
55
55
  "gray-matter": "4.0.3",
56
- "hono": "4.12.14",
56
+ "hono": "4.12.18",
57
57
  "htmlparser2": "8.0.2",
58
58
  "i18next": "22.4.15",
59
59
  "is-glob": "4.0.3",
@@ -90,13 +90,13 @@
90
90
  "xpath": "0.0.34",
91
91
  "yaml-ast-parser": "0.0.43",
92
92
  "zod": "^3.25.76",
93
- "@redocly/asyncapi-docs": "1.10.0-next.5",
93
+ "@redocly/asyncapi-docs": "1.10.0-next.6",
94
94
  "@redocly/config": "0.48.1",
95
- "@redocly/graphql-docs": "1.10.0-next.5",
96
- "@redocly/openapi-docs": "3.21.0-next.5",
95
+ "@redocly/graphql-docs": "1.10.0-next.6",
96
+ "@redocly/openapi-docs": "3.21.0-next.6",
97
97
  "@redocly/portal-legacy-ui": "0.16.0-next.0",
98
- "@redocly/portal-plugin-mock-server": "0.18.0-next.5",
99
- "@redocly/realm-asyncapi-sdk": "0.11.0-next.3",
98
+ "@redocly/portal-plugin-mock-server": "0.18.0-next.6",
99
+ "@redocly/realm-asyncapi-sdk": "0.11.0-next.4",
100
100
  "@redocly/theme": "0.65.0-next.5"
101
101
  },
102
102
  "peerDependencies": {