@redocly/redoc 0.133.0-next.5 → 0.133.0
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 +105 -24
- package/dist/server/plugins/search/engines/typesense/index.js +1 -1
- package/dist/server/web-server/auth.js +3 -3
- package/dist/utils/path/is-local-link.d.ts +1 -0
- package/dist/utils/path/is-local-link.js +1 -1
- package/dist/utils/url/parse-https-url.d.ts +18 -0
- package/dist/utils/url/parse-https-url.js +1 -0
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,86 @@
|
|
|
1
1
|
# @redocly/redoc
|
|
2
2
|
|
|
3
|
+
## 0.133.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0f097a8536: Added multi-version API support for Docs MCP tools.
|
|
8
|
+
- e2b2f2e27f: Improved visibility and accessibility of Markdown links by adding an underline.
|
|
9
|
+
- 76cad3a2f3: Updated styles for page navigation buttons.
|
|
10
|
+
- b5906fb936: Updated the icon displayed alongside hyperlinks in the project.
|
|
11
|
+
- 0858f54ae5: Added Client ID Metadata Document (CIMD) support to the MCP OAuth flow.
|
|
12
|
+
- f2f525c850: Added support for callback URLs in `developerOnboarding`.
|
|
13
|
+
- 7e407eeb7c: Added `hreflang` alternate links for translated pages.
|
|
14
|
+
- 7e407eeb7c: Improved language picker accessibility by converting menu options to links.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- e271a42c40: Prevented search engines from indexing Markdown pages generated by the `llms.txt` feature.
|
|
19
|
+
- ba76c06785: Fixed unauthenticated callback execution in the MCP docs server.
|
|
20
|
+
- 3367a23fae: Fixed an issue in OpenAPI docs route resolution where lines not tied to an operation generated incorrect URLs by duplicating the base slug.
|
|
21
|
+
- e13c79eb30: Fixed an issue where searching in projects without searchable content caused a server error.
|
|
22
|
+
- 36c67eafc2: Fixed rendering of non-Latin characters by enforcing UTF-8 encoding.
|
|
23
|
+
- f7725b9cc7: Fixed an issue where login and logout redirects caused 404 and URI mismatch errors in projects with path prefix.
|
|
24
|
+
- eeb767e9b4: Fixed an issue where preview login redirects failed when the branch hostname contained double hyphens.
|
|
25
|
+
- fac8607a7b: Fixed an issue where closing the search dialog modal locked page scrolling.
|
|
26
|
+
- 7cd2d9f19e: Fixed an issue in Realm Markdown image handling where inline `data:` image URLs were incorrectly treated as broken local routes.
|
|
27
|
+
- 84838a59f0: Excluded buttons and links from heading content to improve accessibility.
|
|
28
|
+
- 4d93e20695: Fixed an issue where MCP connect actions were hidden for OpenAPI pages excluded from search (`openapi.excludeFromSearch`).
|
|
29
|
+
- c9c36d6ac3: Fixed curation in Typesense search.
|
|
30
|
+
- 7447d30745: Fixed security vulnerabilities `CVE-2026-44455`, `CVE-2026-44456`, `CVE-2026-44457`, `CVE-2026-44458` and `CVE-2026-44459` by upgrading `hono` to version `4.12.18`.
|
|
31
|
+
- a1bb760b29: Fixed an issue where the tooltips in API docs and Replay might partially render outside the viewport.
|
|
32
|
+
- c768a98d39: Fixed an issue where operation-level `x-rbac` rules removed the OpenAPI definition link from `llms.txt`.
|
|
33
|
+
- ba76c06785: Fixed an issue where MCP auth URLs were displayed after MCP docs had been disabled.
|
|
34
|
+
- 46f103f0c4: Updated `@redocly/openapi-core` to version `2.30.5`.
|
|
35
|
+
- Updated dependencies [e2b2f2e27f]
|
|
36
|
+
- Updated dependencies [76cad3a2f3]
|
|
37
|
+
- Updated dependencies [3367a23fae]
|
|
38
|
+
- Updated dependencies [b5906fb936]
|
|
39
|
+
- Updated dependencies [36c67eafc2]
|
|
40
|
+
- Updated dependencies [f2f525c850]
|
|
41
|
+
- Updated dependencies [49d39a0486]
|
|
42
|
+
- Updated dependencies [f2a18386e5]
|
|
43
|
+
- Updated dependencies [7e407eeb7c]
|
|
44
|
+
- Updated dependencies [fac8607a7b]
|
|
45
|
+
- Updated dependencies [5e5d990eac]
|
|
46
|
+
- Updated dependencies [84838a59f0]
|
|
47
|
+
- Updated dependencies [4d93e20695]
|
|
48
|
+
- Updated dependencies [7e407eeb7c]
|
|
49
|
+
- Updated dependencies [a1bb760b29]
|
|
50
|
+
- Updated dependencies [ab8c509bb9]
|
|
51
|
+
- Updated dependencies [e5a4a33708]
|
|
52
|
+
- Updated dependencies [4a857b489d]
|
|
53
|
+
- Updated dependencies [46f103f0c4]
|
|
54
|
+
- Updated dependencies [59198fb803]
|
|
55
|
+
- Updated dependencies [9f60402b86]
|
|
56
|
+
- Updated dependencies [4002f20f63]
|
|
57
|
+
- Updated dependencies [62ea0748ec]
|
|
58
|
+
- @redocly/theme@0.65.0
|
|
59
|
+
- @redocly/openapi-docs@3.21.0
|
|
60
|
+
- @redocly/asyncapi-docs@1.10.0
|
|
61
|
+
- @redocly/graphql-docs@1.10.0
|
|
62
|
+
- @redocly/realm-asyncapi-sdk@0.11.0
|
|
63
|
+
- @redocly/portal-plugin-mock-server@0.18.0
|
|
64
|
+
- @redocly/portal-legacy-ui@0.16.0
|
|
65
|
+
|
|
66
|
+
## 0.133.0-next.6
|
|
67
|
+
|
|
68
|
+
### Patch Changes
|
|
69
|
+
|
|
70
|
+
- eeb767e9b48: Fixed an issue where preview login redirects failed when the branch hostname contained double hyphens.
|
|
71
|
+
- 7cd2d9f19e6: Fixed an issue in Realm Markdown image handling where inline `data:` image URLs were incorrectly treated as broken local routes.
|
|
72
|
+
- c9c36d6ac34: Fixed an issue where Typesense search didn't resolve types for curation fields.
|
|
73
|
+
- 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`.
|
|
74
|
+
- 46f103f0c48: Updated `@redocly/openapi-core` to version `2.30.5`.
|
|
75
|
+
- Updated dependencies [5e5d990eacb]
|
|
76
|
+
- Updated dependencies [46f103f0c48]
|
|
77
|
+
- @redocly/realm-asyncapi-sdk@0.11.0-next.4
|
|
78
|
+
- @redocly/openapi-docs@3.21.0-next.6
|
|
79
|
+
- @redocly/theme@0.65.0-next.5
|
|
80
|
+
- @redocly/portal-plugin-mock-server@0.18.0-next.6
|
|
81
|
+
- @redocly/asyncapi-docs@1.10.0-next.6
|
|
82
|
+
- @redocly/graphql-docs@1.10.0-next.6
|
|
83
|
+
|
|
3
84
|
## 0.133.0-next.5
|
|
4
85
|
|
|
5
86
|
### Minor Changes
|
|
@@ -173,7 +254,7 @@
|
|
|
173
254
|
### Minor Changes
|
|
174
255
|
|
|
175
256
|
- ae3272861b: Added support for `x-badges` in OpenAPI and AsyncAPI parameters and schema properties.
|
|
176
|
-
Badges can
|
|
257
|
+
Badges can be rendered before and after field names.
|
|
177
258
|
- ce5a165177: Added support for `or` functions in RBAC conditions within Markdoc content.
|
|
178
259
|
|
|
179
260
|
### Patch Changes
|
|
@@ -365,7 +446,7 @@
|
|
|
365
446
|
|
|
366
447
|
- 60b9b77bc39: Fixed a bug that caused search result highlighting to break in Flexsearch when the query contained duplicate words.
|
|
367
448
|
- ae3272861b4: Added support for `x-badges` in OpenAPI and AsyncAPI parameters and schema properties.
|
|
368
|
-
Badges can
|
|
449
|
+
Badges can be rendered before and after field names.
|
|
369
450
|
- 87a97521127: Fixed an issue where `partial` Markdoc tags in OpenAPI and AsyncAPI `description` fields did not resolve when path separators differed.
|
|
370
451
|
- Updated dependencies [4003b73d9ca]
|
|
371
452
|
- Updated dependencies [ae3272861b4]
|
|
@@ -458,14 +539,14 @@
|
|
|
458
539
|
- f7b6c52055: Improved appearance and deep linking for the `tabs` Markdoc tag.
|
|
459
540
|
- d0b99c0768: Fixed URL fragment duplication when opening docs for endpoints with path parameters (e.g. `/foo/{id}/bar`).
|
|
460
541
|
- 2d305eec36: Fixed the built-in CORS proxy failing with "fetch failed" for certain URLs.
|
|
461
|
-
|
|
542
|
+
The browser's `accept-encoding` header isn't forwarded and the error message surfaces the underlying cause.
|
|
462
543
|
- 1eb287db9f: Fixed code sample generation when path parameter examples contain integer values.
|
|
463
544
|
- 807547ecbd: Improved build memory usage for large projects.
|
|
464
545
|
- 7276b4e5d6: Fixed an issue in AI Search where clearing the product tag would still include the product in the search request.
|
|
465
546
|
- a9a1ee0fe1: Fixed an issue where page actions remained visible even though `search` was disabled.
|
|
466
547
|
- 9b9b43a1b4: Improved the accessibility of AsyncAPI docs.
|
|
467
548
|
- 1cc1909566: Fixed an issue where optional properties of API operations were inconsistently displayed between API docs and Replay.
|
|
468
|
-
The optional properties
|
|
549
|
+
The optional properties respect the configuration in `redocly.yaml`.
|
|
469
550
|
- 130c111688: Fixed security vulnerability `CVE-2026-26996` by upgrading `minimatch` to version `10.2.1`.
|
|
470
551
|
- 7e3400d4a8: Fixed page actions overlapping the navbar.
|
|
471
552
|
- d264713872: Fixed an issue where `rbac` configuration ignored versioned content folder paths with leading slashes.
|
|
@@ -527,7 +608,7 @@
|
|
|
527
608
|
### Patch Changes
|
|
528
609
|
|
|
529
610
|
- 2d305eec36a: Fixed the built-in CORS proxy failing with "fetch failed" for certain URLs.
|
|
530
|
-
|
|
611
|
+
The browser's `accept-encoding` header isn't forwarded and the error message surfaces the underlying cause.
|
|
531
612
|
|
|
532
613
|
## 0.131.0-next.13
|
|
533
614
|
|
|
@@ -557,7 +638,7 @@
|
|
|
557
638
|
- 43955ab32fd: Improved the accessibility of OpenAPI and GraphQL docs.
|
|
558
639
|
- 7276b4e5d63: Fixed an issue in AI Search where clearing the product tag would still include the product in the search request.
|
|
559
640
|
- 1cc1909566f: Fixed an issue where optional properties of API operations were inconsistently displayed between API docs and Replay.
|
|
560
|
-
The optional properties are
|
|
641
|
+
The optional properties are displayed or hidden according to configuration in `redocly.yaml`.
|
|
561
642
|
- d59b5669cea: Updated `@redocly/openapi-core` to version `2.20.4`.
|
|
562
643
|
- Updated dependencies [43955ab32fd]
|
|
563
644
|
- Updated dependencies [7276b4e5d63]
|
|
@@ -811,7 +892,7 @@
|
|
|
811
892
|
|
|
812
893
|
- 85818157d8: Added bundling support for OpenAPI 3.2 `components/mediaTypes` references used in request and response content.
|
|
813
894
|
- 1ff6da217d: Added support for branch-specific configuration in `redocly.yaml`.
|
|
814
|
-
- 12fd642835: Transitioned AI Search to agent mode,
|
|
895
|
+
- 12fd642835: Transitioned AI Search to agent mode, featuring expanded search capabilities and direct integration with the Docs MCP.
|
|
815
896
|
- c585ce5de8: Improved tooltip positioning and performance.
|
|
816
897
|
- 053051e82f: Added `rbac` support for banners to allow conditional visibility based on user team membership.
|
|
817
898
|
|
|
@@ -875,7 +956,7 @@
|
|
|
875
956
|
|
|
876
957
|
### Minor Changes
|
|
877
958
|
|
|
878
|
-
- 12fd642835: Transitioned AI Search to agent mode,
|
|
959
|
+
- 12fd642835: Transitioned AI Search to agent mode, featuring expanded search capabilities and direct integration with the Docs MCP.
|
|
879
960
|
- 053051e82f: Added `rbac` support for banners to allow conditional visibility based on user team membership.
|
|
880
961
|
|
|
881
962
|
### Patch Changes
|
|
@@ -3644,7 +3725,7 @@
|
|
|
3644
3725
|
### Minor Changes
|
|
3645
3726
|
|
|
3646
3727
|
- ec9eff8ad9: Added support for partial loading of items included in large OpenAPI descriptions to improve performance.
|
|
3647
|
-
|
|
3728
|
+
If a `tag` has more than 15 operations, the items are loaded quicker.
|
|
3648
3729
|
- 86f7780631: Added AI conversations UI with follow up questions.
|
|
3649
3730
|
Added configurable suggestions to AI search.
|
|
3650
3731
|
|
|
@@ -3655,11 +3736,11 @@
|
|
|
3655
3736
|
- 9e76b1f148: Updated version of the `@markdoc/markdoc` from `0.4.0` to `0.5.1`
|
|
3656
3737
|
- 03608f2a01: Fixed AI search error handling for Unauthorized and Forbidden errors.
|
|
3657
3738
|
- a85ddf0b86: Resolved an issue with AI search resource styles being overridden by custom styles for `<Tag>` component.
|
|
3658
|
-
- 6b9933d961: Fixed script handling in single page application (SPA) mode. Inline scripts are
|
|
3739
|
+
- 6b9933d961: Fixed script handling in single page application (SPA) mode. Inline scripts are executed on navigation.
|
|
3659
3740
|
- c34c0da390: Fixed an issue where in development mode updates to `redocly.yaml` config were processed much longer than updates to other files.
|
|
3660
3741
|
- 463b9fb93e: Fixed an issue where the `navigation.nextButton.text` and `navigation.previousButton.text` config properties did not change the text of the navigation buttons.
|
|
3661
3742
|
- b74163612d: Resolved an issue where active operation items were incorrectly rendered on the server side.
|
|
3662
|
-
- 074dc10262: Improved the check for the `Complex` badge in `openapi-docs`. The badge
|
|
3743
|
+
- 074dc10262: Improved the check for the `Complex` badge in `openapi-docs`. The badge appears only when the nesting of `allOf` exceeds 5 levels.
|
|
3663
3744
|
- bcb712fe03: Resolved an issue where the discriminator did not update the property type.
|
|
3664
3745
|
- 328b992074: Resolved an issue where an additional slash was incorrectly added to the URL in code samples when using server variables.
|
|
3665
3746
|
|
|
@@ -3728,7 +3809,7 @@
|
|
|
3728
3809
|
### Patch Changes
|
|
3729
3810
|
|
|
3730
3811
|
- 99358a34e5: Resolved an issue where switching to a product opened a non-priority page instead of an index page.
|
|
3731
|
-
|
|
3812
|
+
If a product has an index page, it is displayed first.
|
|
3732
3813
|
- Updated dependencies [bcb712fe03]
|
|
3733
3814
|
- Updated dependencies [ec9eff8ad9]
|
|
3734
3815
|
- @redocly/openapi-docs@3.7.0-next.2
|
|
@@ -3832,7 +3913,7 @@
|
|
|
3832
3913
|
### Minor Changes
|
|
3833
3914
|
|
|
3834
3915
|
- bc13399880: Enhanced development mode error handling showing compilation errors instead of `Internal Server Error` page.
|
|
3835
|
-
CSS errors
|
|
3916
|
+
CSS errors display in an a toast message.
|
|
3836
3917
|
Pages automatically rebuild after fixing errors without server restart.
|
|
3837
3918
|
|
|
3838
3919
|
## 0.115.1
|
|
@@ -3925,8 +4006,8 @@
|
|
|
3925
4006
|
### Patch Changes
|
|
3926
4007
|
|
|
3927
4008
|
- a058d3103e: Improved the OpenAPI definition bundling error message by including the path to the file, making it easier to identify the location of the error.
|
|
3928
|
-
- f08b1cfdd2: Headers are
|
|
3929
|
-
- 7a285f0828: Improved AI search dialog:
|
|
4009
|
+
- f08b1cfdd2: Headers are excluded from page data for anonymous users to prevent potential cache deception attacks.
|
|
4010
|
+
- 7a285f0828: Improved AI search dialog: links open in new tabs, the search button is always enabled, and the search field label is updated.
|
|
3930
4011
|
- 44110c4c7c: Changed the text color in the total page counter to improve readability in light mode.
|
|
3931
4012
|
- 698f536b5c: Updated version of the `@redocly/openapi-core` dependency to `1.26.1`.
|
|
3932
4013
|
- Updated dependencies [44110c4c7c]
|
|
@@ -3995,7 +4076,7 @@
|
|
|
3995
4076
|
### Patch Changes
|
|
3996
4077
|
|
|
3997
4078
|
- 5ffc1db4e8: Updated version of the `@redocly/openapi-core` dependency to `1.26.0`.
|
|
3998
|
-
- 001406d157: Improved error handling in the project: project pages that display an error message are
|
|
4079
|
+
- 001406d157: Improved error handling in the project: project pages that display an error message are automatically refreshed after the user resolves the error in the editor.
|
|
3999
4080
|
This occurs both for Reunite and local projects.
|
|
4000
4081
|
- Updated dependencies [5ffc1db4e8]
|
|
4001
4082
|
- Updated dependencies [b6b91308d6]
|
|
@@ -4183,7 +4264,7 @@
|
|
|
4183
4264
|
|
|
4184
4265
|
### Patch Changes
|
|
4185
4266
|
|
|
4186
|
-
- ae03d1fc71: Improved the `output` property for `apis` configuration. The property
|
|
4267
|
+
- ae03d1fc71: Improved the `output` property for `apis` configuration. The property works as a reference from `openapi` Markdoc tags.
|
|
4187
4268
|
- be7d2e6286: Fixed an issue where if you set `REDOCLY_PREFIX_PATHS` in the environment variables for a project, the Reunite Webview would stop updating based on the page selected in the editor.
|
|
4188
4269
|
- Updated dependencies [9574a87b33]
|
|
4189
4270
|
- Updated dependencies [47065856c6]
|
|
@@ -4373,7 +4454,7 @@
|
|
|
4373
4454
|
|
|
4374
4455
|
### Patch Changes
|
|
4375
4456
|
|
|
4376
|
-
- 5e5916b415: Resolved an issue that caused the page to crash when using the OpenAPI Code Sample Markdoc tags if the `descriptionFile` value was an incorrect path.
|
|
4457
|
+
- 5e5916b415: Resolved an issue that caused the page to crash when using the OpenAPI Code Sample Markdoc tags if the `descriptionFile` value was an incorrect path. If the path is invalid, users are presented with an error directing them to correct it.
|
|
4377
4458
|
|
|
4378
4459
|
## 0.104.3
|
|
4379
4460
|
|
|
@@ -4702,8 +4783,8 @@
|
|
|
4702
4783
|
|
|
4703
4784
|
### Minor Changes
|
|
4704
4785
|
|
|
4705
|
-
- 176b280257: Deprecated the `theme.imports` property. Themes and plugins must
|
|
4706
|
-
- 7e71bf855b: Deprecated the `theme` property of `redocly.yaml` config. All of the configuration properties under `theme`
|
|
4786
|
+
- 176b280257: Deprecated the `theme.imports` property. Themes and plugins must be enabled through the `plugins` configuration property. Using the `theme.imports` does not fail the build, but produces warnings in the build log.
|
|
4787
|
+
- 7e71bf855b: Deprecated the `theme` property of `redocly.yaml` config. All of the configuration properties under `theme` reside in the root of the config.
|
|
4707
4788
|
|
|
4708
4789
|
### Patch Changes
|
|
4709
4790
|
|
|
@@ -4796,13 +4877,13 @@
|
|
|
4796
4877
|
|
|
4797
4878
|
### Patch Changes
|
|
4798
4879
|
|
|
4799
|
-
- ed391e8607: Resolved an issue with audience verification. Users without access permissions to the project are
|
|
4880
|
+
- ed391e8607: Resolved an issue with audience verification. Users without access permissions to the project are redirected to the sign up page.
|
|
4800
4881
|
|
|
4801
4882
|
## 0.92.2
|
|
4802
4883
|
|
|
4803
4884
|
### Patch Changes
|
|
4804
4885
|
|
|
4805
|
-
- 8b3aa69af2: Each error in the `redocly.yaml` file is
|
|
4886
|
+
- 8b3aa69af2: Each error in the `redocly.yaml` file is reported separately. Previously, all validation errors from `redocly.yaml` were bundled and reported as one error.
|
|
4806
4887
|
- Updated dependencies [ac665b40f7]
|
|
4807
4888
|
- Updated dependencies [a0e2645687]
|
|
4808
4889
|
- Updated dependencies [c848158ee4]
|
|
@@ -4820,7 +4901,7 @@
|
|
|
4820
4901
|
|
|
4821
4902
|
### Minor Changes
|
|
4822
4903
|
|
|
4823
|
-
- 2ad34ae141: **IMPORTANT**: Markdoc errors
|
|
4904
|
+
- 2ad34ae141: **IMPORTANT**: Markdoc errors fail production builds.\
|
|
4824
4905
|
To make Realm ignore Markdoc errors during production builds, set the `reunite.ignoreMarkdocErrors` property in `redocly.yaml` to `true`.
|
|
4825
4906
|
|
|
4826
4907
|
### Patch Changes
|
|
@@ -4991,7 +5072,7 @@
|
|
|
4991
5072
|
### Patch Changes
|
|
4992
5073
|
|
|
4993
5074
|
- e50e90b554: Fixed an issue when versioned content had a separate sidebars.yaml defined for each version, the navbar groups and separators were displayed for all versions of the content.
|
|
4994
|
-
|
|
5075
|
+
The navbar groups and separators are displayed only for the corresponding version chosen in the version picker.
|
|
4995
5076
|
|
|
4996
5077
|
## 0.88.2
|
|
4997
5078
|
|
|
@@ -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;#
|
|
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
|
|
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}${
|
|
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>`,
|
|
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/redoc",
|
|
3
|
-
"version": "0.133.0
|
|
3
|
+
"version": "0.133.0",
|
|
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.
|
|
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.
|
|
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,14 +90,14 @@
|
|
|
90
90
|
"xpath": "0.0.34",
|
|
91
91
|
"yaml-ast-parser": "0.0.43",
|
|
92
92
|
"zod": "^3.25.76",
|
|
93
|
-
"@redocly/
|
|
93
|
+
"@redocly/graphql-docs": "1.10.0",
|
|
94
94
|
"@redocly/config": "0.48.1",
|
|
95
|
-
"@redocly/
|
|
96
|
-
"@redocly/
|
|
97
|
-
"@redocly/
|
|
98
|
-
"@redocly/
|
|
99
|
-
"@redocly/
|
|
100
|
-
"@redocly/
|
|
95
|
+
"@redocly/portal-legacy-ui": "0.16.0",
|
|
96
|
+
"@redocly/asyncapi-docs": "1.10.0",
|
|
97
|
+
"@redocly/theme": "0.65.0",
|
|
98
|
+
"@redocly/openapi-docs": "3.21.0",
|
|
99
|
+
"@redocly/portal-plugin-mock-server": "0.18.0",
|
|
100
|
+
"@redocly/realm-asyncapi-sdk": "0.11.0"
|
|
101
101
|
},
|
|
102
102
|
"peerDependencies": {
|
|
103
103
|
"react": "^19.2.4",
|