-
Notifications
You must be signed in to change notification settings - Fork 2.4k
feat: Redoc v3.0.0 #2735
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: Redoc v3.0.0 #2735
Conversation
| async verifyHeaderDeepLink(headerId: string) { | ||
| await expect(this.page.locator(`[id="${headerId}"] a`)).toHaveAttribute( | ||
| 'href', | ||
| new RegExp(`.*#${headerId.replace(/\//g, '\\/')}`), |
Check failure
Code scanning / CodeQL
Incomplete string escaping or encoding High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the problem, we need to properly escape all RegExp meta-characters (especially backslashes) in headerId before embedding it in a RegExp constructor.
- The best way to do this is to use a utility function that escapes all RegExp meta-characters in a string (not just forward slashes).
- One reliable approach is to use an external, well-tested library (such as
escape-string-regexp), but if that's not available or allowed, we can define a simple, robust internal utility to escape RegExp special characters ([-\/\\^$*+?.()|[\]{}]). - Implement such a function (e.g.,
escapeRegExp) within this file, and use it onheaderIdbefore interpolation into theRegExpconstructor.
Edit details:
- Add an
escapeRegExpfunction at the top or inside the class. - Replace the call to
headerId.replace(/\//g, '\\/')in line 60 withescapeRegExp(headerId). - No new imports are required; implement the utility inline.
-
Copy modified lines R3-R6 -
Copy modified line R64
| @@ -1,5 +1,9 @@ | ||
| import { type Page, expect } from '@playwright/test'; | ||
|
|
||
| function escapeRegExp(string: string): string { | ||
| return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); | ||
| } | ||
|
|
||
| export default class Section { | ||
| readonly page: Page; | ||
| readonly sectionId: string; | ||
| @@ -57,7 +61,7 @@ | ||
| async verifyHeaderDeepLink(headerId: string) { | ||
| await expect(this.page.locator(`[id="${headerId}"] a`)).toHaveAttribute( | ||
| 'href', | ||
| new RegExp(`.*#${headerId.replace(/\//g, '\\/')}`), | ||
| new RegExp(`.*#${escapeRegExp(headerId)}`), | ||
| ); | ||
| } | ||
| } |
| if (Object.keys(result).length) { | ||
| return result; | ||
| } |
Check failure
Code scanning / CodeQL
Double escaping or unescaping High
here
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the unescaping order in the unescapeHTMLChars function, we need to modify the sequence of .replace operations so that & is unescaped last. This prevents " from becoming " (and then ") in a single pass, preserving correct character decoding and output. Only lines within this function (lines 154–158) need editing. No extra dependencies or imports are needed; we simply rearrange the .replace calls.
-
Copy modified lines R156-R157
| @@ -153,8 +153,8 @@ | ||
| export function unescapeHTMLChars(str: string): string { | ||
| return str | ||
| .replace(/&#(\d+);/g, (_m, code) => String.fromCharCode(parseInt(code, 10))) | ||
| .replace(/&/g, '&') | ||
| .replace(/"/g, '"'); | ||
| .replace(/"/g, '"') | ||
| .replace(/&/g, '&'); | ||
| } | ||
|
|
||
| export function sanitizeItemId(id: string): string { |
| try { | ||
| return decodeURIComponent(str); | ||
| } catch (e) { | ||
| console.error(`Decoding failed: ${str}`, e); |
Check failure
Code scanning / CodeQL
Use of externally-controlled format string High
user-provided value
Format string depends on a
user-provided value
Format string depends on a
user-provided value
Format string depends on a
user-provided value
Format string depends on a
user-provided value
Format string depends on a
user-provided value
Format string depends on a
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the problem, we should ensure that user-supplied input is not used directly as a format string argument in logging functions. Instead, the safest and most standard approach is to use a format string with only safe, non-user origins (such as a literal string like "Decoding failed: %s") and pass the user-controlled value as a second argument. Therefore, in console.error(Decoding failed: ${str}, e);, change this to console.error("Decoding failed: %s", str, e); on line 46 of src/utils/string.ts. This way, format tokens in user input cannot interfere with the formatting of the log call.
No new imports or definitions are needed. Only a change in the way the log line is constructed.
-
Copy modified line R46
| @@ -43,7 +43,7 @@ | ||
| try { | ||
| return decodeURIComponent(str); | ||
| } catch (e) { | ||
| console.error(`Decoding failed: ${str}`, e); | ||
| console.error("Decoding failed: %s", str, e); | ||
| return str; | ||
| } | ||
| } |
| try { | ||
| return URL?.parse ? URL?.parse(processedUrl) : new URL(processedUrl); | ||
| } catch (error) { | ||
| console.error(`Invalid URL: ${processedUrl}`, error); |
Check failure
Code scanning / CodeQL
Use of externally-controlled format string High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix this issue without altering the functional output, ensure untrusted data never controls the format string in a logging statement with multiple arguments. That is, rather than interpolating user data into the string with a template literal, use the %s format and pass the untrusted string as a separate argument. This ensures the log printing remains predictable and safe regardless of input. Specifically, change
console.error(`Invalid URL: ${processedUrl}`, error);
to
console.error('Invalid URL: %s', processedUrl, error);
in src/utils/url.ts (inside the catch block at line 12).
-
Copy modified line R12
| @@ -9,7 +9,7 @@ | ||
| try { | ||
| return URL?.parse ? URL?.parse(processedUrl) : new URL(processedUrl); | ||
| } catch (error) { | ||
| console.error(`Invalid URL: ${processedUrl}`, error); | ||
| console.error('Invalid URL: %s', processedUrl, error); | ||
| return null; | ||
| } | ||
| } |
5eacf46 to
c01c687
Compare
| name: Release | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| published: ${{ steps.changesets.outputs.published }} | ||
| publishedPackages: ${{ steps.changesets.outputs.publishedPackages }} | ||
| steps: | ||
| - name: Checkout Repo | ||
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 | ||
| - name: Setup Node.js | ||
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 | ||
| with: | ||
| node-version: 22.17 | ||
| cache: 'npm' | ||
| - name: Install Dependencies | ||
| run: npm ci | ||
|
|
||
| - name: Create Release Pull Request or Publish to npm | ||
| id: changesets | ||
| uses: RomanHotsiy/changesets-action@v1 | ||
| with: | ||
| publish: npm run release | ||
| commit: 'chore: 🔖 release new versions' | ||
| title: 'chore: 🔖 release new versions' | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
|
|
||
| dockerhub: |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
The best way to fix this problem is to add an explicit permissions block to your workflow, either at the workflow root or for each job, specifying the least privileges required to successfully complete the actions. As a minimum starting point (per CodeQL suggestion), set contents: read at the root level. If individual jobs need greater permissions (e.g., to create GitHub releases, modify contents, or open pull requests), add a permissions section specifying those details for each job. To implement this, uncomment and adjust the permissions section at the top of the workflow file (.github/workflows/release.yml), right below name: Release. If you're unsure which permissions are necessary for each job, start with contents: read at the root.
-
Copy modified lines R3-R4 -
Copy modified line R6
| @@ -1,9 +1,9 @@ | ||
| name: Release | ||
|
|
||
| # permissions: | ||
| # id-token: write | ||
| # contents: read | ||
| permissions: | ||
| contents: read | ||
|
|
||
|
|
||
| on: | ||
| push: | ||
| branches: |
| needs: [release] | ||
| if: needs.release.outputs.published == 'true' | ||
| uses: ./.github/workflows/docker.yml | ||
| secrets: | ||
| DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} | ||
| DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} | ||
|
|
||
| publish-cdn: |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
-
General approach:
To fix the issue, set an explicitpermissionsblock at the workflow level (root), which applies to all jobs unless overridden. If a job requires more than the minimal permissions, add a more permissive block at that job. Typically, start withcontents: readand add others as required (e.g.,id-token: writefor OIDC,pull-requests: writefor PR operations). -
Best way to fix for this workflow:
Uncomment and apply the permissions block at the top/root of the workflow (lines 3–5), so all jobs run with the explicit permissions ofid-token: writeandcontents: read. This covers most modern workflows for releases, including publish to npm or S3 using OIDC. If further jobs need more permissions, define them at the job level, but for the provided code it does not appear necessary.- Uncomment lines 3–5 so the root-level
permissionsblock is active.
- Uncomment lines 3–5 so the root-level
-
Files/Regions to change:
Only.github/workflows/release.ymllines 3–5.
No new imports, code, or methods are required.
-
Copy modified lines R3-R5
| @@ -1,8 +1,8 @@ | ||
| name: Release | ||
|
|
||
| # permissions: | ||
| # id-token: write | ||
| # contents: read | ||
| permissions: | ||
| id-token: write | ||
| contents: read | ||
|
|
||
| on: | ||
| push: |
| name: Publish to CDN | ||
| needs: [release] | ||
| if: needs.release.outputs.published == 'true' | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v3 | ||
| - name: Configure AWS | ||
| uses: aws-actions/configure-aws-credentials@v1 | ||
| with: | ||
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
| aws-region: us-east-1 | ||
| - name: Download all artifact | ||
| uses: actions/download-artifact@v4 | ||
| - name: Publish to S3 | ||
| run: npm run publish-cdn | ||
|
|
||
| invalidate-cache: |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
To address this issue, we need to add a permissions block to the publish-cdn job to ensure that the job runs with minimal privileges. Review of the steps in this job shows that none of them require write access to the repository or other resources; only reading repository contents (to check out code, etc) is necessary. Therefore, setting permissions: contents: read (the minimal recommended value) is sufficient. The update must be made to the publish-cdn job definition in .github/workflows/release.yml, under jobs.publish-cdn. No imports or other structural changes are necessary.
-
Copy modified lines R55-R56
| @@ -52,6 +52,8 @@ | ||
|
|
||
| publish-cdn: | ||
| name: Publish to CDN | ||
| permissions: | ||
| contents: read | ||
| needs: [release] | ||
| if: needs.release.outputs.published == 'true' | ||
| runs-on: ubuntu-latest |
| name: Clear cache | ||
| runs-on: ubuntu-latest | ||
| needs: [release, publish-cdn] | ||
| if: needs.release.outputs.published == 'true' | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v3 | ||
| - name: Configure AWS | ||
| uses: aws-actions/configure-aws-credentials@v1 | ||
| with: | ||
| aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
| aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
| aws-region: us-east-1 | ||
| - name: Invalidate cache | ||
| run: ./scripts/clear-cache.sh | ||
| shell: bash | ||
| env: | ||
| DISTRIBUTION: ${{ secrets.DISTRIBUTION }} No newline at end of file |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 7 hours ago
The problem should be fixed by adding a permissions block to the invalidate-cache job starting at line 73. As a starting point, {contents: read} is sufficient since this job checks out the code and does not appear to need to write or modify repository contents, pull requests, or any other privileged resources. Add the following under the job beginning with name: Clear cache, i.e., line 74:
permissions:
contents: readNo other changes, imports, or dependencies are needed, and no steps or functionality will change.
-
Copy modified lines R75-R76
| @@ -72,6 +72,8 @@ | ||
| invalidate-cache: | ||
| name: Clear cache | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| needs: [release, publish-cdn] | ||
| if: needs.release.outputs.published == 'true' | ||
| steps: |
Co-authored-by: Roman Hotsiy <[email protected]> Co-authored-by: Alex Varchuk <[email protected]> Co-authored-by: Oprysk Vyacheslav <[email protected]> Co-authored-by: Ivan Kropyvnytskyi <[email protected]> Co-authored-by: Yevhen Pylyp <[email protected]> Co-authored-by: Vladyslav Makarenko <[email protected]> Co-authored-by: Yevhenii Medviediev <[email protected]> Co-authored-by: Oleksii Horbachevskyi <[email protected]> Co-authored-by: volodymyr-rutskyi <[email protected]> Co-authored-by: Adam Altman <[email protected]> Co-authored-by: Andrew Tatomyr <[email protected]> Co-authored-by: Anastasiia Derymarko <[email protected]> Co-authored-by: Roman Marshevskyy <[email protected]> Co-authored-by: Lorna Mitchell <[email protected]> Co-authored-by: Taylor Krusen <[email protected]>
What/Why/How?
Redoc v3.0.0 release:
Reference
Tests
Screenshots (optional)