@redocly/realm 0.140.0-next.1 → 0.140.0-next.10
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 +416 -204
- package/dist/api-schemas/mcp-fetch-count.d.ts +2 -18
- package/dist/api-schemas/otel-traces.d.ts +7 -1345
- package/dist/api-schemas/otel-traces.js +1 -1
- package/dist/api-schemas/search-facets.d.ts +3 -31
- package/dist/api-schemas/search.d.ts +6 -52
- package/dist/cli/build/index.js +1 -1
- package/dist/cli/eject/resolveEjectParams.js +1 -1
- package/dist/cli/generate/get-schema-template.js +1 -1
- package/dist/client/app/hooks/markdown/useMarkdocRenderer.js +1 -1
- package/dist/client/app/hooks/markdown/useMarkdownText.js +1 -1
- package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.d.ts +2 -0
- package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -1
- package/dist/client/app/markdoc/custom-components/openapi/use-markdown-adapter.d.ts +1 -33
- package/dist/client/app/useGlobalData.d.ts +1 -1
- package/dist/client/providers/post-message/use-post-message.d.ts +1 -1
- package/dist/compiled/@redocly/pii/index.mjs +1 -0
- package/dist/compiled/@redocly/pii/package.json +1 -0
- package/dist/compiled/svgo/svgo-node.js +1 -1
- package/dist/constants/l10n/langs/ar.js +1 -1
- package/dist/constants/l10n/langs/de.js +1 -1
- package/dist/constants/l10n/langs/en.js +1 -1
- package/dist/constants/l10n/langs/es.js +1 -1
- package/dist/constants/l10n/langs/fr.js +1 -1
- package/dist/constants/l10n/langs/hi.js +1 -1
- package/dist/constants/l10n/langs/it.js +1 -1
- package/dist/constants/l10n/langs/ja.js +1 -1
- package/dist/constants/l10n/langs/ko.js +1 -1
- package/dist/constants/l10n/langs/pl.js +1 -1
- package/dist/constants/l10n/langs/pt-BR.js +1 -1
- package/dist/constants/l10n/langs/pt.js +1 -1
- package/dist/constants/l10n/langs/ru.js +1 -1
- package/dist/constants/l10n/langs/uk.js +1 -1
- package/dist/constants/l10n/langs/zh.js +1 -1
- package/dist/markdoc/attributes/definition-path.d.ts +1 -1
- package/dist/markdoc/attributes/json-example-ref.d.ts +1 -1
- package/dist/markdoc/attributes/json-schema-ref.d.ts +1 -1
- package/dist/markdoc/attributes/parsed-yaml.d.ts +1 -1
- package/dist/markdoc/attributes/raw-content.d.ts +1 -1
- package/dist/markdoc/attributes/sample-from-json-schema.d.ts +1 -1
- package/dist/markdoc/helpers/extract-rbac-from-condition-node.d.ts +1 -1
- package/dist/markdoc/helpers/get-inner-text.d.ts +1 -1
- package/dist/markdoc/helpers/get-node-attribute.d.ts +1 -1
- package/dist/markdoc/helpers/get-variable.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-conditional-node.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-function.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-node.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-prompt-node.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-tag.d.ts +1 -1
- package/dist/markdoc/helpers/guards/is-variable.d.ts +1 -1
- package/dist/markdoc/helpers/parse-partials.d.ts +1 -1
- package/dist/markdoc/helpers/parse-partials.js +1 -1
- package/dist/markdoc/helpers/remove-markdoc-tags.js +1 -1
- package/dist/markdoc/helpers/set-node-attribute-value.d.ts +1 -1
- package/dist/markdoc/nodes/fence/index.d.ts +1 -1
- package/dist/markdoc/nodes/fence/index.js +1 -1
- package/dist/markdoc/nodes/gfm-list-item.d.ts +1 -1
- package/dist/markdoc/nodes/gfm-list-item.js +1 -1
- package/dist/markdoc/nodes/heading.d.ts +1 -1
- package/dist/markdoc/nodes/heading.js +1 -1
- package/dist/markdoc/nodes/index.d.ts +6 -165
- package/dist/markdoc/nodes/index.js +1 -1
- package/dist/markdoc/nodes/table.d.ts +1 -1
- package/dist/markdoc/nodes/table.js +1 -1
- package/dist/markdoc/nodes/text.d.ts +1 -1
- package/dist/markdoc/tags/json-example.js +1 -1
- package/dist/markdoc/tags/openapi-code-sample.js +1 -1
- package/dist/server/api-routes/execute-api-route.js +1 -1
- package/dist/server/api-routes/run-api-routes-worker.js +1 -1
- package/dist/server/config/env-config.d.ts +26 -24
- package/dist/server/config/env-schema.d.ts +87 -326
- package/dist/server/config/env-schemas/api-urls.d.ts +2 -14
- package/dist/server/config/env-schemas/auth.d.ts +10 -32
- package/dist/server/config/env-schemas/catalog.d.ts +6 -9
- package/dist/server/config/env-schemas/database.d.ts +2 -8
- package/dist/server/config/env-schemas/environment-detection.d.ts +20 -18
- package/dist/server/config/env-schemas/feature-flags.d.ts +29 -33
- package/dist/server/config/env-schemas/feature-flags.js +1 -1
- package/dist/server/config/env-schemas/organization-project.d.ts +3 -21
- package/dist/server/config/env-schemas/scorecards.d.ts +2 -6
- package/dist/server/config/env-schemas/search.d.ts +9 -15
- package/dist/server/config/env-schemas/server-config.d.ts +6 -31
- package/dist/server/config/env-schemas/site.d.ts +1 -5
- package/dist/server/config/env-schemas/ssr.d.ts +7 -12
- package/dist/server/config/env-schemas/telemetry.d.ts +1 -7
- package/dist/server/constants/common.d.ts +3 -0
- package/dist/server/constants/common.js +1 -1
- package/dist/server/esbuild/plugins/dependency-resolver.js +1 -1
- package/dist/server/esbuild/plugins/themes-resolver.js +3 -3
- package/dist/server/external-plugins/resolve-external-plugins.js +1 -1
- package/dist/server/node-bundle-entry.js +1 -1
- package/dist/server/plugins/api-docs/definition-access.d.ts +22 -0
- package/dist/server/plugins/api-docs/definition-access.js +1 -0
- package/dist/server/plugins/api-docs/index.js +1 -1
- package/dist/server/plugins/api-docs/loader.d.ts +1 -1
- package/dist/server/plugins/api-docs/options.js +1 -1
- package/dist/server/plugins/api-docs/spec-download.api.js +1 -1
- package/dist/server/plugins/config-parser/index.js +1 -1
- package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/code-walkthrough/filesets-resolver.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/index.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-code-snippet-from-file.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-diagram-from-file.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-html-href.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-html-source-attribute.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-image-gallery.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-image-src-set.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-image-src.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-example-ref.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-schema-ref.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-native-md-link.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-nav-links.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-open-api-ref.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-response-samples.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-parsed-yaml.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-raw-content.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-relative-or-cdn-icon.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-relative-path.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-sample-from-json-schema.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-svg-content.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-tag-raw-content.d.ts +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-tag-raw-content.js +2 -2
- package/dist/server/plugins/markdown/attribute-resolvers/utils.d.ts +1 -1
- package/dist/server/plugins/markdown/compiler.d.ts +1 -1
- package/dist/server/plugins/markdown/compiler.js +1 -1
- package/dist/server/plugins/markdown/errors.d.ts +1 -1
- package/dist/server/plugins/markdown/get-server-props.js +1 -1
- package/dist/server/plugins/markdown/html/normalize-html-headings.d.ts +1 -1
- package/dist/server/plugins/markdown/html/normalize-html-headings.js +1 -1
- package/dist/server/plugins/markdown/markdoc/functions/concat.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/markdoc-options.d.ts +5 -165
- package/dist/server/plugins/markdown/markdoc/markdoc-options.js +1 -1
- package/dist/server/plugins/markdown/markdoc/partials.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/plugins/headings.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/plugins/utils.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/reparse-example-fences.d.ts +1 -1
- package/dist/server/plugins/markdown/markdoc/reparse-example-fences.js +1 -1
- package/dist/server/plugins/markdown/runtime-transform.d.ts +2 -2
- package/dist/server/plugins/markdown/runtime-transform.js +1 -1
- package/dist/server/plugins/markdown/search/get-ai-search-documents.js +1 -1
- package/dist/server/plugins/markdown/search/nodes/section-node.d.ts +1 -1
- package/dist/server/plugins/markdown/search/search-resolver.js +1 -1
- package/dist/server/plugins/markdown/search/to-markdown.d.ts +1 -1
- package/dist/server/plugins/markdown/search/walk-sections.d.ts +1 -1
- package/dist/server/plugins/markdown/search/walk-sections.js +1 -1
- package/dist/server/plugins/markdown/utils/stringify-tag-children-objects.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +1 -3
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type-list.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/list-graphql-apis.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.d.ts +4 -4
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/types.d.ts +2 -2
- package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/errors.d.ts +0 -5
- package/dist/server/plugins/mcp/handlers/errors.js +1 -1
- package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
- package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +1 -1
- package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
- package/dist/server/plugins/mcp/servers/mcp-server.js +2 -2
- package/dist/server/plugins/mcp/types.d.ts +10 -0
- package/dist/server/plugins/mcp/utils/available-tools.d.ts +5 -0
- package/dist/server/plugins/mcp/utils/available-tools.js +1 -0
- package/dist/server/plugins/mcp/workers/worker-context.d.ts +4 -0
- package/dist/server/plugins/mcp/workers/worker-context.js +1 -0
- package/dist/server/plugins/scorecard-classic/compute-scorecard.d.ts +2 -2
- package/dist/server/plugins/scorecard-classic/compute-scorecard.js +1 -1
- package/dist/server/plugins/scorecard-classic/index.js +1 -1
- package/dist/server/plugins/scorecard-classic/shared-utils.js +1 -1
- package/dist/server/plugins/scorecard-classic/template/Grid/GridHeader.js +3 -3
- package/dist/server/plugins/scorecard-classic/template/views.js +1 -1
- package/dist/server/plugins/search/engines/typesense/index.js +1 -1
- package/dist/server/store-config.d.ts +33 -0
- package/dist/server/store-config.js +1 -0
- package/dist/server/store.d.ts +11 -16
- package/dist/server/store.js +1 -1
- package/dist/server/tools/notifiers/formatter.js +3 -3
- package/dist/server/tools/notifiers/helpers/colors.d.ts +1 -1
- package/dist/server/types/plugins/api-routes.d.ts +4 -1
- package/dist/server/types/plugins/common.d.ts +1 -1
- package/dist/server/utils/codeframes/codeframes.d.ts +1 -1
- package/dist/server/utils/codeframes/yaml-ast.d.ts +1 -1
- package/dist/server/utils/decode-request-path.d.ts +2 -0
- package/dist/server/utils/decode-request-path.js +1 -0
- package/dist/server/utils/envs/env-boolean-string.d.ts +9 -3
- package/dist/server/utils/envs/get-api-route-allowed-env-variables.d.ts +2 -0
- package/dist/server/utils/envs/get-api-route-allowed-env-variables.js +1 -1
- package/dist/server/utils/envs/interpolate-env-variables.d.ts +5 -1
- package/dist/server/utils/envs/interpolate-env-variables.js +1 -1
- package/dist/server/utils/envs/load-env-variables.js +1 -1
- package/dist/server/utils/envs/replace-env-variables-deep.d.ts +17 -9
- package/dist/server/utils/envs/replace-env-variables-deep.js +1 -1
- package/dist/server/utils/errors.d.ts +3 -0
- package/dist/server/utils/errors.js +1 -1
- package/dist/server/utils/llmstxt/resolve-llms-txt-md.js +1 -1
- package/dist/server/utils/rbac-expand.js +1 -1
- package/dist/server/utils/rbac.d.ts +5 -1
- package/dist/server/utils/rbac.js +1 -1
- package/dist/server/utils/report-all-errors.js +1 -1
- package/dist/server/web-server/auth.d.ts +2 -0
- package/dist/server/web-server/auth.js +2 -2
- package/dist/server/web-server/middleware/jsonValidatorMiddleware.d.ts +5 -325
- package/dist/server/web-server/routes/auth.js +1 -1
- package/dist/server/web-server/routes/dynamic-route.js +1 -1
- package/dist/server/web-server/routes/error.js +1 -1
- package/dist/server/web-server/routes/helpers/process-redirects.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-consent-page.d.ts +2 -2
- package/dist/server/web-server/routes/mcp-routes/mcp-consent-page.js +18 -18
- package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
- package/dist/server/web-server/utils/ssrf-safe-lookup.d.ts +2 -1
- package/dist/server/web-server/utils/ssrf-safe-lookup.js +1 -1
- package/dist/server/workers/mcp-tool-worker-methods.d.ts +7 -0
- package/dist/server/workers/mcp-tool-worker-methods.js +1 -0
- package/dist/server/workers/mcp-tool-worker-pool.d.ts +0 -1
- package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
- package/dist/server/workers/mcp-tool-worker.js +1 -1
- package/dist/server/workers/types.d.ts +4 -8
- package/dist/server/workers/worker-config.d.ts +33 -0
- package/dist/server/workers/worker-config.js +1 -0
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/markdoc.d.ts +1 -1
- package/package.json +11 -11
- package/dist/server/plugins/markdown/html/html-jsx-attribute-mapping.d.ts +0 -6
- package/dist/server/plugins/markdown/html/html-jsx-attribute-mapping.js +0 -1
- package/dist/server/plugins/markdown/html/process-html-tokens.d.ts +0 -2
- package/dist/server/plugins/markdown/html/process-html-tokens.js +0 -1
- package/dist/server/plugins/markdown/source.d.ts +0 -4
- package/dist/server/plugins/markdown/source.js +0 -1
- package/dist/server/plugins/mcp/utils/available-sandbox-tools.d.ts +0 -4
- package/dist/server/plugins/mcp/utils/available-sandbox-tools.js +0 -1
- package/dist/server/tools/notifiers/helpers/privacy/mask-email.d.ts +0 -25
- package/dist/server/tools/notifiers/helpers/privacy/mask-email.js +0 -1
- package/dist/server/tools/notifiers/helpers/privacy/mask-subject.d.ts +0 -13
- package/dist/server/tools/notifiers/helpers/privacy/mask-subject.js +0 -1
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii-from-url.d.ts +0 -25
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii-from-url.js +0 -1
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii.d.ts +0 -36
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii.js +0 -1
|
@@ -1,15 +1,19 @@
|
|
|
1
|
+
import { readEnvVariable } from './read-env-variable.js';
|
|
2
|
+
/** False when `value` has no env variable template. Cheaper than `interpolateEnvVariables`. */
|
|
3
|
+
export declare function mayHaveEnvVariables(value: string): boolean;
|
|
1
4
|
/**
|
|
2
5
|
* Interpolates environment variables in a string using the format {{ process.env.VARIABLE_NAME }}.
|
|
3
6
|
* Supports optional quoted default values applied when the variable is not set,
|
|
4
7
|
* e.g. {{ process.env.VARIABLE_NAME || "default" }} (both `|` and `||` separators are accepted).
|
|
5
8
|
*
|
|
6
9
|
* @param value - The string containing environment variable templates to interpolate
|
|
10
|
+
* @param readEnv - Returns the value of an environment variable; reads `process.env` by default
|
|
7
11
|
* @returns An object containing:
|
|
8
12
|
* - interpolatedValue: The string with all environment variables replaced with their values
|
|
9
13
|
* - unsetVars: Array of environment variable names that were not found and had no default
|
|
10
14
|
* - interpolatedVars: Array of environment variable names that were successfully resolved
|
|
11
15
|
*/
|
|
12
|
-
export declare function interpolateEnvVariables(value: string): {
|
|
16
|
+
export declare function interpolateEnvVariables(value: string, readEnv?: typeof readEnvVariable): {
|
|
13
17
|
interpolatedValue: string;
|
|
14
18
|
unsetVars: string[];
|
|
15
19
|
interpolatedVars: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readEnvVariable as d}from"./read-env-variable.js";const
|
|
1
|
+
import{readEnvVariable as d}from"./read-env-variable.js";const f=/{{\s*process\.env\.([A-Z0-9_]+)\s*(?:\|\|?\s*(?:"([^"]*)"|'([^']*)')\s*)?}}/gi;function p(a){return a.includes("{{")}function u(a,c=d){let e=a;const s=new Set,t=new Set,i=[...a.matchAll(f)];for(const n of i){const r=n[1].toUpperCase(),o=n[2]??n[3],l=c(r);l!==void 0?(e=e.replace(n[0],l),t.add(r)):o!==void 0?(e=e.replace(n[0],o),t.add(r)):s.add(r)}return{interpolatedValue:e,unsetVars:Array.from(s),interpolatedVars:Array.from(t)}}export{u as interpolateEnvVariables,p as mayHaveEnvVariables};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as o from"dotenv";import*as n from"path";import{simpleGit as
|
|
1
|
+
import*as o from"dotenv";import*as n from"path";import{simpleGit as E}from"simple-git";import{envConfig as s,reloadEnvConfig as c,setEnv as p}from"../../config/env-config.js";import{readEnvVariable as m}from"../../utils/envs/read-env-variable.js";import{sanitizeBranchName as f}from"../../utils/envs/sanitize-branch-name.js";async function l(e){try{return(await E(e??process.cwd()).revparse(["--abbrev-ref","HEAD"])).trim()}catch{return""}}const _=["REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED","REDOCLY_EXP_REPLAY_ASYNCAPI_ENABLED"];async function d(e){const a=Object.fromEntries(_.map(t=>[t,m(t)]));o.config({path:n.resolve(e??"",".env")}),c();const i=s.PUBLIC_REDOCLY_BRANCH_NAME||await l(e);if(i){const t=f(i);o.config({path:n.resolve(e??"",`.env.branch.${t}`),override:!0}),c()}const v=s.REDOCLY_ENV;let r;switch(v){case"production":r=".env.production";break;case"preview":r=".env.preview";break;default:r=".env.development";break}o.config({path:n.resolve(e??"",r),override:!0}),p(a)}export{d as loadEnvVariables};
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
+
import { readEnvVariable } from './read-env-variable.js';
|
|
2
|
+
type EnvReplacement = {
|
|
3
|
+
unsetEnvVars: string[];
|
|
4
|
+
interpolatedEnvVars: string[];
|
|
5
|
+
replacedValues: Record<string, {
|
|
6
|
+
original: string;
|
|
7
|
+
replaced: string;
|
|
8
|
+
}>;
|
|
9
|
+
};
|
|
1
10
|
/**
|
|
2
11
|
* Recursively traverses an object or array and interpolates environment variables in all string values.
|
|
3
12
|
* Keeps track of the path to each modified value and maintains a record of original and replaced values.
|
|
4
13
|
*
|
|
5
14
|
* @param obj - The object or array to process
|
|
6
|
-
* @param currentPath - Array of keys representing current position in object tree
|
|
7
15
|
*
|
|
8
16
|
* @returns An object containing:
|
|
9
|
-
* - resolvedObj:
|
|
17
|
+
* - resolvedObj: A copy of the plain objects and arrays, with all environment variables replaced
|
|
10
18
|
* - unsetEnvVars: Array of environment variable names that were not found
|
|
11
19
|
* - interpolatedEnvVars: Array of environment variable names that were successfully resolved
|
|
12
20
|
* - replacedValues: Record of paths where values were replaced, with original and new values
|
|
@@ -14,13 +22,13 @@
|
|
|
14
22
|
* For usage examples and test cases, see:
|
|
15
23
|
* [unit tests](./__tests__/env.test.ts)
|
|
16
24
|
*/
|
|
17
|
-
export declare function replaceEnvVariablesDeep<T extends Record<string, unknown> | Array<unknown>>(obj: T
|
|
25
|
+
export declare function replaceEnvVariablesDeep<T extends Record<string, unknown> | Array<unknown>>(obj: T): EnvReplacement & {
|
|
18
26
|
resolvedObj: T;
|
|
19
|
-
unsetEnvVars: string[];
|
|
20
|
-
interpolatedEnvVars: string[];
|
|
21
|
-
replacedValues: Record<string, {
|
|
22
|
-
original: string;
|
|
23
|
-
replaced: string;
|
|
24
|
-
}>;
|
|
25
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* `replaceEnvVariablesDeep` without the copy: changes the strings of `container` in place.
|
|
30
|
+
* `readEnv` returns the value of an environment variable; it reads `process.env` by default.
|
|
31
|
+
*/
|
|
32
|
+
export declare function replaceEnvVariablesInPlace(container: object, readEnv?: typeof readEnvVariable): EnvReplacement;
|
|
33
|
+
export {};
|
|
26
34
|
//# sourceMappingURL=replace-env-variables-deep.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject as
|
|
1
|
+
import{isObject as c}from"../../../utils/guards/is-object.js";import{interpolateEnvVariables as E,mayHaveEnvVariables as b}from"./interpolate-env-variables.js";import{readEnvVariable as v}from"./read-env-variable.js";function g(r){const n=p(r);return{resolvedObj:n,...A(n)}}function A(r,n=v){const t=new Set,f=new Set,l={},i=[],V=u=>{const o=u;for(const a in o){const e=o[a];if(typeof e=="string"){if(!b(e))continue;const{interpolatedValue:d,unsetVars:y,interpolatedVars:m}=E(e,n);y.forEach(s=>t.add(s)),m.forEach(s=>f.add(s)),m.length>0&&(o[a]=d,l[[...i,a].join(":")]={original:e,replaced:d})}else(c(e)||Array.isArray(e))&&(i.push(a),V(e),i.pop())}};return(c(r)||Array.isArray(r))&&V(r),{unsetEnvVars:Array.from(t),interpolatedEnvVars:Array.from(f),replacedValues:l}}function p(r){return Array.isArray(r)?r.map(p):c(r)?Object.fromEntries(Object.entries(r).map(([n,t])=>[n,p(t)])):r}export{g as replaceEnvVariablesDeep,A as replaceEnvVariablesInPlace};
|
|
@@ -2,4 +2,7 @@ export declare class HttpError extends Error {
|
|
|
2
2
|
status: number;
|
|
3
3
|
constructor(status: number, message: string);
|
|
4
4
|
}
|
|
5
|
+
export declare class OidcDiscoveryError extends Error {
|
|
6
|
+
constructor(url: string, status: number, contentType: string | null);
|
|
7
|
+
}
|
|
5
8
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class r extends Error{status;constructor(t,e){super(e),this.status=t,Object.setPrototypeOf(this,r.prototype)}}class s extends Error{constructor(t,e,o){super(`OIDC discovery failed: ${new URL(t).host} answered HTTP ${e} (${o??"no content type"})`),this.name="OidcDiscoveryError",Object.setPrototypeOf(this,s.prototype)}}export{r as HttpError,s as OidcDiscoveryError};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import n from"path";import{removeLeadingSlash as s}from"../../../utils/url/remove-leading-slash.js";import{fileExistsAsync as l}from"../index.js";async function f(e,o,r){if(r){const t=await r.getPageMarkdown(e);return{exists:t!==void 0,content:t?.content,route:t?.route}}const i=e==="/index.html.md"?"/":e.replace(/\.md$/i,"");return{exists:await l(n.resolve(o.outdir,s(e))),content:void 0,route:o.getRouteBySlug(i,{followRedirect:!1})}}export{f as resolveLlmsTxtMd};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getHigherRole as c}from"./rbac.js";function R(e,r){if(!e)return;if(!p(e))return e;const o={
|
|
1
|
+
import{getHigherRole as c}from"./rbac.js";function R(e,r){if(!e)return;if(!p(e))return e;const o={platform:{},content:i(e)},n=f(e,r);for(const t of n)o.platform[t.teamName]=t.projectRole,o.content={...o.content,...Object.fromEntries((e.teamFolders||[]).flatMap(a=>{const l={...e.teamFoldersBaseRoles||{authenticated:"READ"},[t.teamName]:t.projectRole,"redocly.owners":"ADMIN"},m=a.replaceAll("{teamPathSegment}",t.teamPathSegment),s=m+"/**";return[[m,l],[s,l]]}))};return{...e,platform:{...e.platform,...o.platform},content:{...d(e.content||{},o.content)}}}function p(e){return!!(e.teamNamePatterns&&e.teamFolders)}function u(e,r){for(const o of e.teamNamePatterns||[]){if(!o.includes("{teamPathSegment}")&&!o.includes("{projectRole}"))continue;const n="^"+o.replace("{teamPathSegment}","(?<teamPathSegment>[a-zA-Z0-9_.-]+)").replace("{projectRole}","(?<projectRole>admin|maintain|triage|write|read|none)")+"$",a=new RegExp(n,"i").exec(r)?.groups;if(a?.projectRole||a?.teamPathSegment)return{teamName:r,projectRole:a.projectRole?.toUpperCase(),teamPathSegment:a.teamPathSegment?.toLowerCase()}}return null}function g(e,r){for(const o of e?.teamFolders||[]){if(!o.includes("{teamPathSegment}"))continue;const n=`^${o.replace("{teamPathSegment}","(?<teamPathSegment>[a-zA-Z0-9_.-]+)")}($|/)`,t=new RegExp(n,"i");for(const a of r){const l=t.exec(a)?.groups;if(l?.teamPathSegment)return{teamPathSegment:l.teamPathSegment.toLowerCase()}}}return null}function f(e,r){const o=r.map(t=>u(e,t));let n=null;for(const t of o)t?.projectRole&&!t.teamPathSegment&&(n=n?c(n,t.projectRole):t.projectRole);return o.map(t=>!t?.teamPathSegment||!t.projectRole&&!n?null:(t.projectRole=t.projectRole??n??void 0,t)).filter(Boolean)}function i(e){const r={};if(e.teamFoldersBaseRoles)for(const o of e.teamFolders){const n=o.replaceAll("{teamPathSegment}","**");r[n]=e.teamFoldersBaseRoles}return r}function d(e,r){const o={...e};for(const[n,t]of Object.entries(r))o[n]?o[n]={...o[n],...t}:o[n]=t;return o}export{p as canExpandConfig,R as expandRbacConfig,i as getTeamFolderDefaults,g as parseTeamFoldersTemplate,u as parseTeamNameTemplate,f as parseTeams};
|
|
@@ -2,6 +2,7 @@ import '../node-crypto-polyfill.js';
|
|
|
2
2
|
import { REDOCLY_TEAMS_RBAC, REDOCLY_ROUTE_RBAC } from '@redocly/config';
|
|
3
3
|
import type { RbacConfig, RbacScopeItems, RedoclyConfig, SsoConfig } from '@redocly/config';
|
|
4
4
|
import type { AuthDetails } from '../types';
|
|
5
|
+
import type { ApiDefinitionAccess } from '../plugins/api-docs/definition-access.js';
|
|
5
6
|
import type { ContentFs } from '../fs/content-fs.js';
|
|
6
7
|
import type { RbacFeatures } from '../../constants/common.js';
|
|
7
8
|
export type ProjectRole = 'NONE' | 'READ' | 'TRIAGE' | 'WRITE' | 'MAINTAIN' | 'ADMIN';
|
|
@@ -33,7 +34,7 @@ export declare function canDownloadApiDefinition(pathname: string, rbacConfig: R
|
|
|
33
34
|
isAuthenticated?: boolean;
|
|
34
35
|
email?: string;
|
|
35
36
|
teams?: string[];
|
|
36
|
-
}): boolean;
|
|
37
|
+
}, definitionAccess?: ApiDefinitionAccess): boolean;
|
|
37
38
|
export declare function canAccessAsset(pathname: string, rbacConfig: RbacConfig, requiresLogin: boolean, directoryPaths: Record<string, string>, user?: {
|
|
38
39
|
isAuthenticated?: boolean;
|
|
39
40
|
email?: string;
|
|
@@ -145,6 +146,9 @@ export declare const normalizeRbacConfig: (rbacConfig: RbacConfig) => {
|
|
|
145
146
|
[x: string]: string;
|
|
146
147
|
} | undefined;
|
|
147
148
|
} | undefined;
|
|
149
|
+
platform?: {
|
|
150
|
+
[x: string]: string;
|
|
151
|
+
} | undefined;
|
|
148
152
|
reunite?: {
|
|
149
153
|
[x: string]: string;
|
|
150
154
|
} | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import y from"path";import O from"picomatch";import"../node-crypto-polyfill.js";import{REDOCLY_TEAMS_RBAC as T,REDOCLY_ROUTE_RBAC as R}from"@redocly/config";import{MCP_ROUTE as U,PUBLIC_MCP_ROUTE as k}from"@redocly/theme/core/constants/mcp";import{ServerRoutes as w}from"../../constants/api.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as D,PUBLIC_RBAC_SCOPE_ITEM as _,RBAC_ALL_OTHER_TEAMS as l,DEFAULT_RBAC_SCOPE as x,GRAPHQL_SPEC_SLUG as B}from"../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as g,PUBLIC_API_DEFINITIONS_FOLDER as I,PUBLIC_ASSETS_FOLDER as b,RUNTIME_RESOURCES_DIR as $,SCORECARD_CLASSIC_FOLDER as W,SITEMAP_FILE_NAME as v,LLMS_TXT_FILE_NAME as Y}from"../constants/common.js";import{MCP_CREDENTIALS_ROUTE as G}from"../constants/mcp.js";import{ANONYMOUS_AUTH_DETAILS as H}from"../constants/rbac.js";import{removeTrailingSlash as S}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as z}from"../../utils/url/remove-leading-slash.js";import{parsePathVersions as K}from"../../utils/path/parse-path-versions.js";import{reporter as V}from"../tools/notifiers/reporter.js";import{bold as J}from"../tools/notifiers/helpers/colors.js";import{shaDirPathShort as Q}from"../utils/crypto/sha-dir-path-short.js";import{isTruthy as X}from"../../utils/guards/is-truthy.js";import{isPathInFolder as C}from"../../utils/path/is-path-in-folder.js";import{canExpandConfig as Z,expandRbacConfig as q,getTeamFolderDefaults as tt,parseTeamFoldersTemplate as et,parseTeamNameTemplate as rt}from"./rbac-expand.js";import{getUserParamsFromCookies as nt}from"../web-server/auth.js";import{getDeeperGlobPattern as ot}from"./globs.js";import{EntitlementsProvider as st}from"../entitlements/entitlements-provider.js";const j=["NONE","READ","TRIAGE","WRITE","MAINTAIN","ADMIN"],ct=new Set(["x-parsed-md-description","x-parsed-md-summary"]),at=new Set(Object.values(w).map(t=>S(t.split(":")[0])));function wt(t,e){const r=j.indexOf(t.toUpperCase()),n=j.indexOf(e.toUpperCase());return r>n?t:e}const P={};function F(t,e){if(!t?.content)return _;const r=t.content,{slug:n,fsPath:o}=e;if(!n&&!o)return _;const s=f=>{const E=`slug:${f}`,p=P[E]??O(f);P[E]=p;const A=`fsPath:${f}`,L=P[A]??O(z(f));return P[A]=L,!!(n&&p(n))||!!(o&&L(o))};if(ut(n||o||"")&&Object.keys(r).filter(p=>s(p)).length===0)return r[x]||_;const i=Object.keys(r).filter(f=>s(f));if(i.length==0)return _;const u=i.map(f=>O.scan(f,{tokens:!0,parts:!0}));let h=u[0];for(let f=1;f<u.length;f++)h=ot(h,u[f]);return r[h.input]}function N(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 Bt(t,e,r={},n=!1){if(n&&Object.keys(r).length===0)return e.isAuthenticated;const o=r.features?.[t];return o?N(o,e.teams):!0}function bt(t,e){return d(t,H,e.access?.rbac||{},e.access?.requiresLogin||!1)}function d(t,e={},r={},n=!1){if(t.slug&&typeof t.slug=="string"&&at.has(S(t.slug))||(t.slug===U||t.slug===k||t.slug===G)&&st.instance().canAccessFeature("mcp"))return!0;if(n&&Object.keys(r).length===0)return!!e.isAuthenticated;const o=q(r,e.teams||[]),s=t[T]||F(o,t[R]||{});return Object.keys(s||{}).length===0?!1:Object.keys(s).length===1&&s[l]&&s[l].toLowerCase()!=="none"?!0:N(s,e?.teams||[],e?.email)}function $t(t,e,r,n,o){if(!t.startsWith(I)&&!t.startsWith(g))return!0;if(o){const u={[T]:o.rbac,[R]:{slug:o.slug,fsPath:o.sourcePath}};return d(u,n,e,r)}const s=t.replace(new RegExp(`^${I}/`),"").replace(new RegExp(`^${g}/`),"").replace(new RegExp(`^${B}/`),""),a=s==="."?"":s,i={[R]:{slug:t,fsPath:a},slug:t};return d(i,n,e,r)}function Wt(t,e,r,n,o){if(!C(t,b))return[`/${v}`,`/${Y}`].includes(t)||[$,W].some(A=>C(t,A));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:a,ext:i}=y.parse(t),u=a.split(".")[0],h=i.split(".").join(""),E=c==="."?"":c,p={[R]:{slug:t,fsPath:y.posix.join(E,`${u}.${h}`)},slug:t};return d(p,o,e,r)}async function vt(t,e){const{isAuthenticated:r=!1,idpAccessToken:n,federatedAccessToken:o,federatedIdToken:s,...c}=await nt(t,e),{teams:a=[]}=c;let i;return r?i=a.filter(u=>u!==D):i=[D],{isAuthenticated:r,idpAccessToken:n,teams:i,claims:c}}function M(t,e,r={},n=!1){if(!t)return t;if(Array.isArray(t)){const o=[];for(const s of t){const c=M(s,e,r,n);c!==void 0&&o.push(c)}return o}if(typeof t=="object"){if(!d(t,e,r,n))return;let o=!1;const s={};for(const c in t){if(c===T||c===R)continue;if(ct.has(c)){s[c]=t[c];continue}const a=M(t[c],e,r,n);if(!t.link&&(c==="items"||c==="menu"&&t.type==="tab")&&Array.isArray(a)&&a.length===0&&t[c].length!==0){o=!0;continue}a!==void 0&&(s[c]=a),c==="paths"&&it(a)&&ft(a)}return o?void 0:s}return t}function Yt(t){return typeof t=="string"?t.split(" ").filter(Boolean):Array.isArray(t)?t.map(e=>e.toString()):[]}function Gt(t,e){if(!e)return;const r=e.content;if(!r)return e;const n=Object.entries(r).flatMap(([s,c])=>s===x?[[s,c]]:[[s,c]].concat(t.localeFolders.map(a=>[s.startsWith("/")?`/${a.toLocaleLowerCase()}${s}`:y.posix.join(t.localizationFolder,a,s),c]))),o=Object.fromEntries(n);return{...e,content:o}}async function Ht(t,e){if(!e)return{};const r={},n=new Set(t.scan().flatMap(({relativePath:o})=>{const{versionFolderPath:s}=K(o)||{},c=y.dirname(o);return s?[s,c]:c}));for(const o of n)r[Q(o)]=o;return r}const m=t=>typeof t=="object"&&t!==null&&!Array.isArray(t);function it(t){return m(t)&&Object.keys(t).length>0}function ft(t){for(const e of Object.keys(t)){const r=t[e];m(r)&&Object.keys(r).length===0&&delete t[e]}}function ut(t){return t?t.split("/").filter(Boolean).some(r=>r.startsWith(".")):!1}const lt=t=>{if(t&&m(t)&&("content"in t&&m(t.content)||"platform"in t&&m(t.platform)||"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},zt=async t=>{if(t){if(Object.keys(t).length===0)return{};if(lt(t))return mt(t);await V.panicOnContentError(`You are using an incorrect format of ${J("rbac:")} configuration. See: https://redocly.com/docs/realm/access`)}},mt=t=>{const e={...t};if(e.content){const r={};for(const n in e.content)if(e.content[n]!==void 0){const o=S(n);r[o]=e.content[n]}e.content=r}return e};function Kt(t,e){const r=t.fsPath,n=t.slug,o=[],s=Z(e)&&(r||n)?et(e,[r,n].filter(X)):null;if(s){const a=e?.teamNamePatterns?.map(i=>i.replace("{teamPathSegment}",s.teamPathSegment).replace("{projectRole}","read"))??[];o.push(...a)}const c=F(s?{content:{...tt(e),...e.content}}:e,t);return o.push(...pt(c)),ht(e,o)}function pt(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 ht(t,e){return e.map(n=>rt(t,n)??{teamName:n}).map(n=>n.projectRole&&n.projectRole!=="READ"?n.teamName?.toLowerCase().replace(n.projectRole?.toLowerCase?.()??"","read")??"":n.teamName?.toLowerCase()??"")}export{j as PROJECT_ROLES_ORDERED_BY_ACCESS_LEVEL,Gt as applyL10nToRbacConfig,Wt as canAccessAsset,Bt as canAccessFeature,d as canAccessResource,$t as canDownloadApiDefinition,ht as expandTeamsForRead,pt as extractTeamsFromScopeItems,M as filterDataByAccessDeep,vt as getAuthDetailsFromCookies,wt as getHigherRole,Kt as getRbacTeamsListForResource,F as getScopeItemsForResource,N as hasScopeAccess,lt as isRbacConfigValid,bt as isResourcePubliclyAccessible,mt as normalizeRbacConfig,zt as parseRbacConfig,Yt as parseTeamClaimToArray,Ht as resolveDirectoryHashes};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{envConfig as p}from"../config/env-config.js";import{logger as l}from"../tools/notifiers/logger.js";import{reporter as r}from"../tools/notifiers/reporter.js";import{isMarkdocError as d}from"../plugins/markdown/errors.js";import{telemetryTraceStep as g}from"../../cli/telemetry/helpers/trace-step.js";import{writeProblemsReport as u}from"./write-problems-report.js";async function M(
|
|
1
|
+
import{envConfig as p}from"../config/env-config.js";import{logger as l}from"../tools/notifiers/logger.js";import{reporter as r}from"../tools/notifiers/reporter.js";import{isMarkdocError as d}from"../plugins/markdown/errors.js";import{telemetryTraceStep as g}from"../../cli/telemetry/helpers/trace-step.js";import{writeProblemsReport as u}from"./write-problems-report.js";async function M(o){await g("com.redocly.build.validationErrors",async e=>{let t=0;for(const[c,f]of o.cache.errors.entries()){const m=c.split(":")[1];for(const i of f)d(i)?(r.reportMarkdocProblem(i),i.type!=="BROKEN_LINK"&&t++):await r.panicOnBuild(i.message,m)}const n=await o.getConfig();if(!p.isBuildMode)return;const s=r.getPageRenderProblems().length;e?.setAttribute("markdocErrors",t.toString()),e?.setAttribute("pageRenderErrors",s.toString()),t>0&&!n?.platform?.ignoreMarkdocErrors?await a(`Need to fix ${t} Markdoc issue(s) or set the \`ignoreMarkdocErrors\` option to \`true\` in the \`platform\` section of your \`redocly.yaml\``):s>0&&await a(`Need to fix ${s} runtime error(s) in React pages`)})}async function a(o){r.printErrors();try{u()}catch(e){l.warn("Failed to write the problems report: "+e.message)}await r.panic(o)}export{M as reportAllErrors};
|
|
@@ -160,7 +160,9 @@ export declare const oidcJwksCache: {
|
|
|
160
160
|
export declare const UNKNOWN_KID_RETRY_MS = 60000;
|
|
161
161
|
export declare function getOidcMetadata(idpId: string, providerConfig: OidcProviderConfig): Promise<OidcIssuerMetadata>;
|
|
162
162
|
export declare function discoverJwks(ssoConfig: SsoConfig): Promise<void>;
|
|
163
|
+
export declare const OIDC_DISCOVERY_RETRY_MS = 60000;
|
|
163
164
|
export declare function getRedoclyTokenPayload(token: string): Promise<Record<string, unknown>>;
|
|
165
|
+
export declare function exchangeTokenLoginCode(code: string): Promise<string | undefined>;
|
|
164
166
|
export declare function isRedoclySso(config: OidcProviderConfig): boolean;
|
|
165
167
|
export declare function verifySAMLResponse(responseXml: string, cert: string): Promise<boolean>;
|
|
166
168
|
export declare function orderTeamsRbacFirst(teams: string[], rbacConfig: RbacConfig | undefined, teamsMapping: Record<string, string> | undefined): string[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import"../node-crypto-polyfill.js";import{DOMParser as j}from"@xmldom/xmldom";import{SignedXml as
|
|
1
|
+
import"../node-crypto-polyfill.js";import{DOMParser as j}from"@xmldom/xmldom";import{SignedXml as ne}from"xml-crypto";import re from"xpath";import{deflateSync as oe,inflateSync as se}from"fflate";import{createHash as ie}from"crypto";import{ulid as ae}from"ulid";import{AuthProviderType as p,DEFAULT_TEAM_CLAIM_NAME as U}from"@redocly/config";import{ALTERNATIVE_AUD_CLAIM_NAME as ce,AUTH_URL as V,JWT_SECRET_KEY as y,MAX_AUTH_TOKEN_COOKIE_BYTES as ue}from"../constants/common.js";import{ensureArray as O}from"../../utils/array/ensure-array.js";import{envConfig as de}from"../config/env-config.js";import{decryptClaimValue as le}from"../utils/crypto/decrypt-claim-value.js";import{decryptAesGcm as fe}from"../utils/crypto/decrypt-aes-gcm.js";import{encryptAesGcm as me}from"../utils/crypto/encrypt-aes-gcm.js";import{getPathPrefix as pe,withPathPrefix as he,withoutPathPrefix as ye}from"@redocly/theme/core/utils";import{ServerRoutes as K}from"../../constants/api.js";import{AuthCookieNames as I,DEFAULT_AUTHENTICATED_TEAM as Ae,REQUIRED_OIDC_SCOPES as $}from"../../constants/common.js";import{appendQueryParams as we}from"../../utils/url/append-query-params.js";import{parsePreviewUrl as B}from"../../utils/url/parse-preview-url.js";import{logger as E}from"../tools/notifiers/logger.js";import{OidcDiscoveryError as F}from"../utils/errors.js";import{randomString as _e}from"../utils/crypto/random-string.js";import{randomUUID as M}from"../utils/crypto/random-uuid.js";import{AlgorithmTypes as l,JwtTokenExpired as Se}from"./jwt/types.js";import*as m from"./jwt/jwt.js";import{InternalTokenTypes as g}from"./jwt/token-types.js";import{parseTeamClaimToArray as Te}from"../utils/index.js";import{parseTeamNameTemplate as ge}from"../utils/rbac-expand.js";import{arrayBufferToBase64 as xe,decodeBase64 as H,encodeBase64URL as Ie,urlSafeBase64 as z}from"./jwt/encode.js";import{formatSamlCertificate as Ee}from"./utils/format-saml-certificate.js";const ke=new Set(Object.values(g));function x(e){return e?.type===p.OIDC}function Re(e){return e?.type===p.SAML2}async function Ct(e,t){if(x(t))return Oe(e,t);if(Re(t))return Me(e,t)}async function Oe(e,t){const n=await X(e,t),r=new Set((t.scopes||[]).concat($)),o=t.authorizationRequestCustomParams||{};return{type:p.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 Me(e,t){return{type:p.SAML2,idpId:e,name:"SAML2 provider",ssoUrl:t.ssoUrl,issuerId:t.issuerId,entityId:t.entityId||t.issuerId}}function W(e){return Array.from(new Set((e.scopes||[]).concat($))).join(" ")}async function J(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 bt(e,t,n,r,o={}){return await J(e,r,{scope:W(r),code:t,redirect_uri:q(n),grant_type:"authorization_code",...o})}async function vt(e,t,n){return await J(e,n,{scope:W(n),grant_type:"refresh_token",refresh_token:t})}function De(e,{authorizationEndpoint:t,clientId:n,responseType:r,scope:o,extraParams:s,idpId:i,pkce:c},d,h,u){if(!t||!n||!r||!o)return{loginUrl:void 0};const a=new URL(t),w=u?.redirectUriOverride??`${e}${he(K.OIDC_CALLBACK)}`,S={state:M(),idpId:i,redirectUri:w,redirectTo:d,branch:u?.branchOverride??be(e),inviteCode:h,source:u?.sourceOverride??"portal",uiLocales:u?.uiLocales},T={};if(c){const A=z(_e(50)),k=z(ie("sha256").update(A).digest("base64")),R="S256";a.searchParams.append("code_challenge",k),a.searchParams.append("code_challenge_method",R),T.code_verifier={value:A,options:{secure:!0,httpOnly:!0,expires:new Date(Date.now()+1e3*60*10),path:pe()||"/"}}}a.searchParams.append("client_id",n),a.searchParams.append("scope",o),a.searchParams.append("response_type",r),a.searchParams.append("redirect_uri",q(w)),a.searchParams.append("state",Ie(JSON.stringify(S))),u?.uiLocales&&a.searchParams.append("ui_locales",u.uiLocales);for(const A in s)s[A]!==void 0&&a.searchParams.append(A,s[A]);return{loginUrl:a.toString(),cookies:T}}function Pt(e,t,n,r){const o=new URL(e);return n&&(o.searchParams.append("post_logout_redirect_uri",t),r&&o.searchParams.append("state",r),o.searchParams.append("id_token_hint",n)),o.toString()}function Le(e,t){const n=O(t?.audience??[]);return!n.length||Y(e,n)}function Y(e,t){const n=[e.aud,e[ce]].flat();return t.some(r=>r!==""&&n.includes(r))}function Ne(e,t){return!t||!x(t)?!0:Le(e,t)&&Ce(e,t)}function Ce(e,t){return!x(t)||!Qe(t)||!t.clientId?!0:O(e.aud||[]).includes(t.clientId)}function jt(e){if(!e)return!1;try{return m.decode(e).header.alg===l.RS256}catch{return!1}}async function Ut(e){const t=Math.floor(Date.now()/1e3),n=t+(e.ttlSec??600);return m.sign({type:g.MCP_AUTHORIZATION_CODE,client_id:e.clientId,redirect_uri:e.redirectUri,id_token_enc:me(e.idToken,y),...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,l.HS256)}async function Vt(e){await m.verify(e,y,l.HS256);const{payload:t}=m.decode(e);if(t.type!==g.MCP_AUTHORIZATION_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");if(typeof t.id_token_enc!="string")throw new Error("Authorization code missing session");return{...t,id_token:fe(t.id_token_enc,y)}}async function Kt(e){const t=Math.floor(Date.now()/1e3);return m.sign({type:g.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,jti:M()},y,l.HS256)}async function $t(e){await m.verify(e,y,l.HS256);const{payload:t}=m.decode(e);if(t.type!==g.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 Bt(e){const t=e||ae(),n=t.startsWith("mcp_")?t:`mcp_${t}`;return{id:n,object:"mcpSession",uri:`urn:redocly:realm:mcp:session:${n}`}}function q(e){const t=B(e);if(!t)return e;const n=ve(t.hostname);if(n)return t.hostname=`previewauth--${n.previewBranch}${n.after}`,G(e,t);const r=Q(t.hostname);return r?(t.hostname=`${r.projectSlug}.previewauth.${r.after}`,G(e,t)):e}function be(e){const t=B(e);if(t)return Q(t.hostname)?.previewBranch}function G(e,t){const n=e.replace(/^https?:\/\/[^/?#]+/i,"");return`${t.protocol}//${t.host}${ye(n)}`}function Q(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),i=n.slice(o+2);return!s||!i||i.includes(".")?null:{projectSlug:s,previewBranch:i,after:r}}function ve(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 Pe(e){return e.type===p.OIDC}function je(e){return e.type===p.SAML2}function Ft(e,t,n,r,o){return Pe(e)?De(t,e,n,r,{uiLocales:o}):je(e)?Ue(t,e,n,r,o):{}}function Ue(e,t,n,r,o){const i=`<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="_${M()}"
|
|
@@ -9,4 +9,4 @@ import"../node-crypto-polyfill.js";import{DOMParser as j}from"@xmldom/xmldom";im
|
|
|
9
9
|
<samlp:NameIDPolicy
|
|
10
10
|
AllowCreate="true"
|
|
11
11
|
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
|
|
12
|
-
</samlp:AuthnRequest>`,c=
|
|
12
|
+
</samlp:AuthnRequest>`,c=Ve(i);return{loginUrl:we(t.ssoUrl,{SAMLRequest:c,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:n,inviteCode:r,source:"portal",uiLocales:o})})}}function Ve(e){return xe(oe(new TextEncoder().encode(e)).buffer)}function Ht(e){const t=H(e);if(t.startsWith("<samlp:Response")||t.indexOf("<saml2p:Response")>-1)return t;const n=se(new Uint8Array(atob(e).split("").map(r=>r.charCodeAt(0))));return new TextDecoder().decode(n)}function zt(e){try{return JSON.parse(H(e||""))}catch{throw new Error("Invalid OAuth2 state")}}function Wt(e){const t=new j().parseFromString(e,"application/xml"),r=f(t,"//*[local-name(.)='StatusCode']/@Value")[0]?.nodeValue?.endsWith("Success")||!1,s=f(t,"//*[local-name(.)='Response']/@Destination")[0]?.nodeValue||"",i=f(t,"//*[local-name(.)='Assertion']//*[local-name(.)='Issuer']/text()")[0],c=i&&i.nodeValue||void 0,d=f(t,"//*[local-name(.)='Audience']/text()")[0],h=d&&d.nodeValue||void 0,a=f(t,"//*[local-name(.)='Assertion']//*[local-name(.)='X509Certificate']/text()")[0]?.nodeValue||"",w=f(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/text()")[0],S=w&&w.nodeValue||"",T=f(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/@Format")[0],A=T&&T.nodeValue||"",k=f(t,"//*[local-name(.)='Conditions']/@NotOnOrAfter")[0],R=Ke(k),N={},C=f(t,"//*[local-name(.)='AttributeStatement']//*[local-name(.)='Attribute']");if(C.length)for(const b of C){const v=f(b,"./@Name")[0];if(v.nodeValue){const P=f(b,"./*[local-name(.)='AttributeValue']/text()")[0];P?.nodeValue&&(N[v.nodeValue]=P.nodeValue)}}return{uid:S,success:r,expiresAt:R,issuerId:c,entityId:h,attrs:N,cert:a,nameFormat:A,destination:s}}function Ke(e){const t=typeof e?.nodeValue=="string"&&D(Date.parse(e.nodeValue)),n=D(Date.now()),r=D(Date.now()+720*60*1e3);return t?t>n&&t<r?r:t:n}function D(e){return Math.floor(e/1e3)}const L={},_={jwks:{},missedAt:{}},$e=6e4;function Be(e){const t=_.jwks[e];return t===void 0?!0:t===null&&Date.now()-(_.missedAt[e]??0)>=$e}async function X(e,t){if(!L[e]){const n=t.configurationUrl?await ee(t.configurationUrl):t.configuration;L[e]=Fe()?ze(n):n}return L[e]}function Fe(){const e=de.REDOCLY_ENFORCE_RESIDENCY;return!!e&&e.includes("host.docker.internal")}const He=["authorization_endpoint","end_session_endpoint"];function ze(e){if(typeof e!="object"||e===null)return e;const t={...e};for(const n of Object.keys(t)){if(He.includes(String(n)))continue;const r=t[n];typeof r=="string"&&r.includes("://localhost")&&(t[n]=r.replace("://localhost","://host.docker.internal"))}return t}const We=["kty","n","e","crv","x","y"];function Je(e,t){return We.every(n=>e[n]===t[n])}async function Ye(e){const t={};for(const n of Object.keys(e)){const r=e[n];if(!x(r))continue;const o=await X(n,r);if(o.jwks_uri){const s=await ee(o.jwks_uri);for(const i of s.keys){const c=t[i.kid],d=c&&Je(c,i)?[...c.idpIds,n]:[n];t[i.kid]={...i,idpIds:d},_.jwks[i.kid]=t[i.kid]}}}}function qe(e,t,n){const r=_.jwks[e]?.idpIds??[];return r.find(o=>{const s=n[o];if(!x(s))return!1;const i=O(s.audience??[]);return Y(t,i.length?i:[s.clientId])})??r.at(-1)}const Ge=6e4,Z={};async function ee(e){const t=Z[e];if(t&&Date.now()-t.failedAt<Ge)throw t.error;const n=await fetch(e,{headers:{Accept:"application/json"}}),r=n.ok?await n.json().catch(()=>{}):void 0;if(r===void 0){const o=new F(e,n.status,n.headers.get("content-type"));throw Z[e]={error:o,failedAt:Date.now()},o}return r}async function Jt(e){return fetch(`${V}/oidc/userinfo`,{headers:{Accept:"application/json",Authorization:`Bearer ${e}`}}).then(t=>t.status===200?t.json():void 0).catch(()=>{})}async function Yt(e){return fetch(`${V}/api/auth/organization-session/login-code/exchange`,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({code:e})}).then(t=>t.status===200?t.json():void 0).then(t=>typeof t?.token=="string"?t.token:void 0).catch(()=>{})}function Qe(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=>Xe(t.hostname,r))}function Xe(e,t){return e===t||e.endsWith(`.${t}`)}async function qt(e,t){const n=new j().parseFromString(e,"application/xml"),r=f(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=Ee(t),s=new ne({publicCert:o});s.loadSignature(r);try{return s.checkSignature(e)}catch{return!1}}function Ze(e){const t=new Set,n=r=>{if(!(!r||typeof r!="object"||Array.isArray(r)))for(const[o,s]of Object.entries(r))typeof s=="string"?t.add(o):n(s)};return n(e),t}function et(e,t,n){if(!t)return e;const r=Ze(t),o=s=>{const i=n?.[s]||s;return r.has(i)||!!ge(t,i)};return[...e.filter(o),...e.filter(s=>!o(s))]}async function Gt(e,t,n,r){const o=n?e[n]:void 0,s=Array.isArray(o)?et(o.map(String),r?.rbacConfig,r?.teamsMapping):[];let i=s.length;const c=s.length+1;for(let d=0;d<c;d++){const h={...e,idpId:t};n&&s.length&&(h[n]=s.slice(0,i));const u=await m.sign(h,y,l.HS256),a=Buffer.byteLength(u)-ue;if(a<=0)return{token:u,teamsTotal:s.length,teamsKept:i,droppedTeams:s.slice(i)};if(i===0)return null;const w=Buffer.byteLength(JSON.stringify(s.slice(0,i))),S=Math.max(1,w/i*4/3);i=Math.max(0,i-Math.max(1,Math.ceil(a/S)))}return null}function Qt(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(/^.+@.+/m)&&(o=e);const s=n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],i=s?.match(/^.+@.+/m);return o=o||n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]||(i?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?Te(n[r]):[]}}function te(e,t={}){return e.map(n=>t[n]||n)}async function Xt(e,t){if(!t)return{};const n=t[I.AUTHORIZATION];if(!n)return{};try{const r=m.decode(n);if(typeof r.payload.type=="string"&&ke.has(r.payload.type))return{};if(r.header.alg===l.RS256){const h=Be(r.header.kid);h&&await Ye(e);const u=_.jwks[r.header.kid];if(!u)return h&&(_.missedAt[r.header.kid]=Date.now()),_.jwks[r.header.kid]=null,{};await m.verify(n,u,l.RS256)}else await m.verify(n,y,l.HS256);const s=r.header.alg===l.RS256?qe(r.header.kid,r.payload,e):r.payload.idpId,i=e[s]||{};if(r.header.alg===l.RS256&&typeof r.payload.exp!="number")return E.warn("Rejected id_token: it has no exp claim"),{};if(r.header.alg===l.RS256&&!Ne(r.payload,i))return E.warn("Rejected id_token: it was issued for another project"),{};const c=rt(i),d=nt(i);return{...r.payload,email:r.payload.email?.toLowerCase(),idpId:s,teams:Array.from(new Set([...te(r.payload.teams||[],d),..."defaultTeams"in i&&i.defaultTeams||[],...te("teamsClaimName"in i&&r.payload[c||""]||[],d),Ae])),name:tt(r.payload),isAuthenticated:!0,idpAccessToken:le(r.payload.idp_access_token,y)||t[I.IDP_ACCESS_TOKEN],federatedAccessToken:t[I.FEDERATED_ACCESS_TOKEN],federatedIdToken:t[I.FEDERATED_ID_TOKEN],authCookie:n}}catch(r){r instanceof Se||(r instanceof F?E.error(r.message):E.error("Malformed JWT token: %s",r.message))}return{}}function tt(e){return(e.firstName&&e.lastName?`${e.firstName} ${e.lastName}`:e.name||e.given_name||e.firstName||e.lastName)||e.email}function nt(e){switch(e.type){case p.SAML2:return e.teamsAttributeMap;case p.OIDC:return e.teamsClaimMap;default:return}}function rt(e){switch(e.type){case p.SAML2:return e.teamsAttributeName??U;case p.OIDC:return e.teamsClaimName;default:return U}}function f(e,t){return re.select(t,e)||[]}export{Ge as OIDC_DISCOVERY_RETRY_MS,$e as UNKNOWN_KID_RETRY_MS,Ft as buildLoginUrl,De as buildOidcLoginUrl,Pt as buildOidcLogoutUrl,Ue as buildSAML2LoginUrl,Ut as createMcpAuthorizationCode,Kt as createMcpRefreshToken,Bt as createMcpSessionResource,Ht as decodeSamlResponse,Ye as discoverJwks,Ve as encodeSAML2,Yt as exchangeTokenLoginCode,Qt as extractUserClaims,Ct as getAuthProviderLoginParams,Oe as getOidcLoginParams,X as getOidcMetadata,Jt as getRedoclyTokenPayload,Me as getSaml2LoginParams,Xt as getUserParamsFromCookies,tt as getUsernameFromPayload,Le as idTokenAudienceIsAllowed,Ne as idTokenIsForThisProject,jt as isIdpIssuedToken,x as isOidcProviderConfig,Qe as isRedoclySso,Re as isSaml2ProviderConfig,bt as oidcExchangeCodeForToken,_ as oidcJwksCache,L as oidcMetadataCache,vt as oidcRefreshTokenGrant,et as orderTeamsRbacFirst,zt as parseOidcState,be as parsePreviewBranch,Wt as parseSamlResponse,q as rewritePreviewAuthRedirectUri,Gt as signTokenWithinCookieSizeLimit,Vt as verifyMcpAuthorizationCode,$t as verifyMcpRefreshToken,qt as verifySAMLResponse};
|