From 8a477bd49611fdbaa78df60afadae974fbce5123 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:28:10 +0530 Subject: [PATCH 01/29] sca-scan.yml --- .github/workflows/sca-scan.yml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/workflows/sca-scan.yml b/.github/workflows/sca-scan.yml index a642aef..4fa4560 100644 --- a/.github/workflows/sca-scan.yml +++ b/.github/workflows/sca-scan.yml @@ -6,14 +6,10 @@ jobs: security-sca: runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@master - - uses: snyk/actions/setup@master - - name: Setup .NET - uses: actions/setup-dotnet@v3.0.3 - - name: Restore dependencies - run: dotnet restore ./Contentstack.Utils.sln + - uses: actions/checkout@master - name: Run Snyk to check for vulnerabilities - run: cd Contentstack.Utils && snyk test --fail-on=all + uses: snyk/actions/dotnet@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --fail-on=all From 859fbca96cb827e4a4255c0a1a51f20ab25b83a5 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:28:22 +0530 Subject: [PATCH 02/29] jira.yml --- .github/workflows/jira.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/jira.yml b/.github/workflows/jira.yml index caa4bbd..250abc7 100644 --- a/.github/workflows/jira.yml +++ b/.github/workflows/jira.yml @@ -21,7 +21,7 @@ jobs: project: ${{ secrets.JIRA_PROJECT }} issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} summary: | - ${{ github.event.pull_request.title }} + Snyk | Vulnerability | ${{ github.event.repository.name }} | ${{ github.event.pull_request.title }} description: | PR: ${{ github.event.pull_request.html_url }} From 78a2b45ccf4acd5db6a436cb938d8ef32ec07137 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:28:23 +0530 Subject: [PATCH 03/29] sast-scan.yml From eb23349e6adea3dbdd7bdb07394e59819e3ec8d5 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:28:25 +0530 Subject: [PATCH 04/29] codeql-analysis.yml From a71223f0312f4451e97b7ae13ec440b6dfb7889e Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:28:29 +0530 Subject: [PATCH 05/29] Updated codeowners --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 0773923..1be7e0d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @contentstack/security-admin \ No newline at end of file +* @contentstack/security-admin From 46ee79e41b67140492c25bd69828128c909daf2e Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:55:26 +0530 Subject: [PATCH 06/29] policy-scan.yml --- .github/workflows/policy-scan.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/policy-scan.yml diff --git a/.github/workflows/policy-scan.yml b/.github/workflows/policy-scan.yml new file mode 100644 index 0000000..13bd362 --- /dev/null +++ b/.github/workflows/policy-scan.yml @@ -0,0 +1,27 @@ +name: Checks the security policy and configurations +on: + pull_request: + types: [opened, synchronize, reopened] +jobs: + security-policy: + if: github.event.repository.visibility == 'public' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@master + - name: Checks for SECURITY.md policy file + run: | + if ! [[ -f "SECURITY.md" || -f ".github/SECURITY.md" ]]; then exit 1; fi + security-license: + if: github.event.repository.visibility == 'public' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@master + - name: Checks for License file + run: | + if ! [[ -f "LICENSE" || -f "License.txt" || -f "LICENSE.md" ]]; then exit 1; fi \ No newline at end of file From 61e81a58b2215edf7ccb52d77e1502bdc8fa5261 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:55:38 +0530 Subject: [PATCH 07/29] issues-jira.yml --- .github/workflows/issues-jira.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/issues-jira.yml diff --git a/.github/workflows/issues-jira.yml b/.github/workflows/issues-jira.yml new file mode 100644 index 0000000..7bf0469 --- /dev/null +++ b/.github/workflows/issues-jira.yml @@ -0,0 +1,31 @@ +name: Create Jira Ticket for Github Issue + +on: + issues: + types: [opened] + +jobs: + issue-jira: + runs-on: ubuntu-latest + steps: + + - name: Login to Jira + uses: atlassian/gajira-login@master + env: + JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} + JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} + JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + + - name: Create Jira Issue + id: create_jira + uses: atlassian/gajira-create@master + with: + project: ${{ secrets.JIRA_PROJECT }} + issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} + summary: Github | Issue | ${{ github.event.repository.name }} | ${{ github.event.issue.title }} + description: | + *GitHub Issue:* ${{ github.event.issue.html_url }} + + *Description:* + ${{ github.event.issue.body }} + fields: "${{ secrets.ISSUES_JIRA_FIELDS }}" \ No newline at end of file From cc7f02412afa474385165db8a3de3fba6041c37a Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:55:39 +0530 Subject: [PATCH 08/29] Delete jira.yml --- .github/workflows/jira.yml | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 .github/workflows/jira.yml diff --git a/.github/workflows/jira.yml b/.github/workflows/jira.yml deleted file mode 100644 index 250abc7..0000000 --- a/.github/workflows/jira.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Create JIRA ISSUE -on: - pull_request: - types: [opened] -jobs: - security-jira: - if: ${{ github.actor == 'dependabot[bot]' || github.actor == 'snyk-bot' || contains(github.event.pull_request.head.ref, 'snyk-fix-') || contains(github.event.pull_request.head.ref, 'snyk-upgrade-')}} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Login into JIRA - uses: atlassian/gajira-login@master - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - name: Create a JIRA Issue - id: create - uses: atlassian/gajira-create@master - with: - project: ${{ secrets.JIRA_PROJECT }} - issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} - summary: | - Snyk | Vulnerability | ${{ github.event.repository.name }} | ${{ github.event.pull_request.title }} - description: | - PR: ${{ github.event.pull_request.html_url }} - - fields: "${{ secrets.JIRA_FIELDS }}" - - name: Transition issue - uses: atlassian/gajira-transition@v3 - with: - issue: ${{ steps.create.outputs.issue }} - transition: ${{ secrets.JIRA_TRANSITION }} From 406bedf51c16bbc1e148ef7fbedb44fabc0892e6 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:55:39 +0530 Subject: [PATCH 09/29] Delete sast-scan.yml --- .github/workflows/sast-scan.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .github/workflows/sast-scan.yml diff --git a/.github/workflows/sast-scan.yml b/.github/workflows/sast-scan.yml deleted file mode 100644 index 3b9521a..0000000 --- a/.github/workflows/sast-scan.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: SAST Scan -on: - pull_request: - types: [opened, synchronize, reopened] -jobs: - security-sast: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Semgrep Scan - run: docker run -v /var/run/docker.sock:/var/run/docker.sock -v "${PWD}:/src" returntocorp/semgrep semgrep scan --config auto \ No newline at end of file From c422d6a542a1df0bdd94394f3300767978fd61f3 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:55:41 +0530 Subject: [PATCH 10/29] codeql-analysis.yml From 8430c8fdb3f02ffc3c728fab644abe8793d6cf6b Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:55:44 +0530 Subject: [PATCH 11/29] Updated codeowners From 6c232ea6c0376ceeba908c4f3be0a2351629791f Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 23 Apr 2025 21:43:00 +0530 Subject: [PATCH 12/29] policy-scan.yml --- .github/workflows/policy-scan.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/policy-scan.yml b/.github/workflows/policy-scan.yml index 13bd362..ff25923 100644 --- a/.github/workflows/policy-scan.yml +++ b/.github/workflows/policy-scan.yml @@ -24,4 +24,23 @@ jobs: - uses: actions/checkout@master - name: Checks for License file run: | - if ! [[ -f "LICENSE" || -f "License.txt" || -f "LICENSE.md" ]]; then exit 1; fi \ No newline at end of file + expected_license_files=("LICENSE" "LICENSE.txt" "LICENSE.md" "License.txt") + license_file_found=false + current_year=$(date +"%Y") + + for license_file in "${expected_license_files[@]}"; do + if [ -f "$license_file" ]; then + license_file_found=true + # check the license file for the current year, if not exists, exit with error + if ! grep -q "$current_year" "$license_file"; then + echo "License file $license_file does not contain the current year." + exit 2 + fi + break + fi + done + + if [ "$license_file_found" = false ]; then + echo "No license file found. Please add a license file to the repository." + exit 1 + fi \ No newline at end of file From 46c55b40bf60138475386937dac2fe8a408b3b21 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:16:20 +0530 Subject: [PATCH 13/29] policy-scan.yml From 91e010ce8a49f78fa7fed10d6e6e9d1a2bdd78f1 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:16:28 +0530 Subject: [PATCH 14/29] issues-jira.yml From 5e3c8277a1dc21c64fe03d40cd4d1e6536200d41 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:16:28 +0530 Subject: [PATCH 15/29] secrets-scan.yml --- .github/workflows/secrets-scan.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/secrets-scan.yml diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml new file mode 100644 index 0000000..049c02f --- /dev/null +++ b/.github/workflows/secrets-scan.yml @@ -0,0 +1,29 @@ +name: Secrets Scan +on: + pull_request: + types: [opened, synchronize, reopened] +jobs: + security-secrets: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: '2' + ref: '${{ github.event.pull_request.head.ref }}' + - run: | + git reset --soft HEAD~1 + - name: Install Talisman + run: | + # Download Talisman + wget https://github.com/thoughtworks/talisman/releases/download/v1.37.0/talisman_linux_amd64 -O talisman + + # Checksum verification + checksum=$(sha256sum ./talisman | awk '{print $1}') + if [ "$checksum" != "8e0ae8bb7b160bf10c4fa1448beb04a32a35e63505b3dddff74a092bccaaa7e4" ]; then exit 1; fi + + # Make it executable + chmod +x talisman + - name: Run talisman + run: | + # Run Talisman with the pre-commit hook + ./talisman --githook pre-commit \ No newline at end of file From 31480388744b76c5cebabe929fbb7a33c37e065b Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:16:32 +0530 Subject: [PATCH 16/29] Updated codeowners From 9e9ee2a19e9faac678a8485c415c5317088f8c05 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 23:37:17 +0530 Subject: [PATCH 17/29] talismanrc file updated --- .talismanrc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.talismanrc b/.talismanrc index 4628b50..f94199e 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,7 @@ fileignoreconfig: +- filename: .github/workflows/secrets-scan.yml + ignore_detectors: + - filecontent - filename: Contentstack.Utils/Models/Options.cs checksum: 3dc51f0de02429ef9a43b66e666ac4dbde41195e245f8ecc0094548ca8603245 - filename: Contentstack.Utils/Utils.cs From b1b9cad6fadfbad6473b257324f672c459859c2e Mon Sep 17 00:00:00 2001 From: raj pandey Date: Tue, 3 Jun 2025 17:30:27 +0530 Subject: [PATCH 18/29] Fix: Used the title and target attributes in the a tag --- CHANGELOG.md | 3 ++ .../Constants/JsonToHtmlConstants.cs | 13 +++--- Contentstack.Utils.Tests/DefaultRenderTest.cs | 2 +- Contentstack.Utils.Tests/JsonToHtmlTest.cs | 8 ++++ Contentstack.Utils.sln | 2 +- Contentstack.Utils/Models/Options.cs | 45 ++++++++++++------- Directory.Build.props | 2 +- 7 files changed, 50 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bd0842..ac3b4b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### Version: 1.0.6 +#### Date: June-09-2025 +- Used 'title' and 'target' in a tags ### Version: 1.0.5 #### Date: Oct-10-2024 diff --git a/Contentstack.Utils.Tests/Constants/JsonToHtmlConstants.cs b/Contentstack.Utils.Tests/Constants/JsonToHtmlConstants.cs index 09d6761..2d6ecdb 100644 --- a/Contentstack.Utils.Tests/Constants/JsonToHtmlConstants.cs +++ b/Contentstack.Utils.Tests/Constants/JsonToHtmlConstants.cs @@ -16,11 +16,13 @@ public static class JsonToHtmlResultConstants public const string kTableHtml = "

Header 1

Header 2

Body row 1 data 1

Body row 1 data 2

Body row 2 data 1

Body row 2 data 2

"; public const string kBlockquoteHtml = "
Praesent eu ex sed nibh venenatis pretium.
"; public const string kCodeHtml = "Code template."; - public const string kLinkInPHtml = "

LINK

"; - public const string kLinkInPMailToHtml = "

LINK

"; + public const string kLinkInPHtml = "

LINK

"; + public const string kLinkInPMailToHtml = "

LINK

"; public const string kLinkInPMailToTARGEtHtml = "

LINK

"; public const string kEmbedHtml = ""; - public const string stringClassIdResult = "

This is a text to be ignored

" ; + public const string stringClassIdResult = "

This is a text to be ignored

"; + public const string kJSONRTEResult = "

demoText is demoText

This is same

demoText2

demoText3demoText4

demoText3demoText2

"; + } public static class JsonToHtmlConstants @@ -48,7 +50,7 @@ public static class JsonToHtmlConstants public const string kEntryReferenceLinkJson = "{ \"uid\":\"06e34a7 5e4 e549d\", \"_version\":1, \"attrs\":{ }, \"children\":[{\"uid\":\"7626ea98e0e95d602210\",\"type\":\"reference\",\"attrs\":{\"target\":\"_self\",\"href\":\"/copy-of-entry-final-02\",\"display-type\":\"link\",\"entry-uid\":\"UID_08\",\"content-type-uid\":\"embeddedrte\",\"locale\":\"en-us\",\"type\":\"entry\",\"class-name\":\"embedded-entry\"},\"children\":[{\"text\":\"/copy-of-entry-final-02\"}]}],\"type\":\"doc\"}"; public const string kEntryReferenceInlineJson = "{ \"uid\":\"06e34a7 5e4 e549d\", \"_version\":1, \"attrs\":{ }, \"children\":[{\"uid\":\"506 4878f3f46 s21f0cbc aff\",\"type\":\"reference\",\"attrs\":{\"display-type\":\"inline\",\"entry-uid\":\"UID_09\",\"content-type-uid\":\"embeddedrte\",\"locale\":\"en-us\",\"type\":\"entry\",\"class-name\":\"embedded-entry\"},\"children\":[{\"text\":\"\"}]}],\"type\":\"doc\"}"; public const string kHRJson = "{ \"uid\":\"06e34a7 5e4 e549d\", \"_version\":1, \"attrs\":{ }, \"children\":[{\"uid\":\"f5a7b57 40a8a5c3 576828276b\",\"type\":\"hr\",\"children\":[{\"text\":\"\"}],\"attrs\":{ }}],\"type\":\"doc\"}"; - public const string classId = "{ \"uid\":\"06e34a7 5e4 e549d\", \"_version\":1, \"attrs\":{ }, \"children\":[{\"uid\":\"f5a7b57 40a8a5c3 576828276b\",\"type\":\"doc\",\"children\":[{\"text\":\"Thorisbest\",\"classname\": \"c2\",\"id\": \"i2\"}],\"attrs\":{ }}],\"type\":\"text\"}"; + public const string classId = "{ \"uid\":\"06e34a7 5e4 e549d\", \"_version\":1, \"attrs\":{ }, \"children\":[{\"uid\":\"f5a7b57 40a8a5c3 576828276b\",\"type\":\"doc\",\"children\":[{\"text\":\"demoTextisdemoText\",\"classname\": \"c2\",\"id\": \"i2\"}],\"attrs\":{ }}],\"type\":\"text\"}"; public const string stringClassId = "{ \"type\": \"doc\", \"attrs\": {}, \"uid\": \"8622288a91dc4c76985d776d2540b395\", \"children\": [ { \"type\": \"p\", \"uid\": \"396ee25abd0f4296a45eac63809450ef\", \"attrs\": {}, \"children\": [ { \"text\": \"This\", \"classname\": \"\", \"id\": \"i3\" }, { \"text\": \" is a \" }, { \"text\": \"text\", \"classname\": \"c1\", \"id\": \"i1\" }, { \"text\": \" to be \" }, { \"text\": \"ignored\", \"classname\": \"c2\", \"id\": \"\" } ] } ], \"_version\": 4 }"; public const string KAssetNode = "\"embedded_itemsConnection\": { \"edges\": [{ \"node\": { \"system\": { \"content_type_uid\": \"sys_assets\", \"uid\": \"UID_12\" }, \"created_at\": \"2020-08-19T09:13:32.785Z\", \"updated_at\": \"2020-08-19T09:13:32.785Z\", \"created_by\": \"Created_at\", \"updated_by\": \"Created_at\", \"content_type\": \"application/pdf\", \"file_size\": \"13264\", \"filename\": \"dummy.pdf\", \"url\":\"/v3/assetsUID_12/dummy.pdf\", \"_version\": 1, \"title\": \"dummy.pdf\" } } ]}"; public const string KEntryBlocNode = "\"embedded_itemsConnection\": { \"edges\": [{ \"node\": { \"title\": \"Update this title\", \"url\": \"\", \"locale\": \"en-us\", \"system\": { \"uid\": \"UID_07\", \"content_type_uid\": \"content_block\" }, \"_version\": 5, \"_in_progress\": false, \"multi_line\": \"\", \"rich_text_editor\": \"\" } } ]}"; @@ -56,7 +58,7 @@ public static class JsonToHtmlConstants public const string KEntryInlineNode = "\"embedded_itemsConnection\": { \"edges\": [{ \"node\": { \"title\": \"updated title\", \"rich_text_editor\": [ \"\" ], \"locale\": \"en-us\", \"system\": { \"uid\": \"UID_09\", \"content_type_uid\": \"embeddedrte\", }, \"_in_progress\": false } } ]}"; public static string KGQLModel(string node, string embedConnection = null) { - return $"{{\"multiplerte\":{{\"json\":[{node}]{(embedConnection != null ? ","+embedConnection : "")} }}, \"singlerte\":{{\"json\":{node}{(embedConnection != null ? "," + embedConnection : "")}}} }}"; + return $"{{\"multiplerte\":{{\"json\":[{node}]{(embedConnection != null ? "," + embedConnection : "")} }}, \"singlerte\":{{\"json\":{node}{(embedConnection != null ? "," + embedConnection : "")}}} }}"; } public const string kAssetMeta = "{\"uid\":\"asset_uid\",\"created_by\":\"create_by\",\"updated_by\":\"update_by\",\"content_type\":\"image/jpeg\",\"file_size\":\"62181\",\"tags\":[],\"filename\":\"crop_area.jpeg\",\"url\":\"http://image.contenstack.com/crop_area.jpeg\",\"is_dir\":false,\"parent_uid\":null,\"path\":[],\"_version\":1,\"title\":\"crop_area.jpeg\",\"dimension\":{\"height\":712,\"width\":864},\"_metadata\":{\"extensions\":{\"extension_uid\":{\"local_metadata\":{\"local_data\":\"main\",\"presets\":[{\"uid\":\"preset_01\",\"name\":\"Local Preset\",\"options\":{\"transform\":{\"height\":500,\"width\":500,\"flip-mode\":\"horiz\",\"rotate\":40},\"focal-point\":{\"x\":-0.668935003427432,\"y\":-0.9220385351936531},\"quality\":\"100\",\"image-type\":\"jpeg\"}},{\"uid\":\"preset_02\",\"name\":\"WithCrop\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"569.6\",\"width\":\"569.6\",\"flip-mode\":\"both\"},\"image-type\":\"jpeg\",\"crop\":{\"height\":\"569.6\",\"width\":\"569.6\",\"x\":\"147.2\",\"y\":\"71.2\"}}},{\"uid\":\"preset_03\",\"name\":\"Filter\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":712,\"width\":864},\"image-type\":\"jpeg\",\"effects\":{\"brightness\":52,\"contrast\":15,\"saturate\":-30,\"blur\":16,\"sharpen\":{\"amount\":9,\"radius\":669,\"threshold\":207}}}}]},\"global_metadata\":{\"presets\":[{\"uid\":\"preset_04\",\"name\":\"Global Preset\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"712\",\"width\":\"864\",\"flip-mode\":\"verti\"},\"image-type\":\"jpeg\"}}]}}}}}"; @@ -65,6 +67,7 @@ public static string KGQLModel(string node, string embedConnection = null) public const string kAssetPresets = "{\"uid\":\"asset_uid\",\"created_by\":\"create_by\",\"updated_by\":\"update_by\",\"content_type\":\"image/jpeg\",\"file_size\":\"62181\",\"tags\":[],\"filename\":\"crop_area.jpeg\",\"url\":\"http://image.contenstack.com/crop_area.jpeg\",\"is_dir\":false,\"parent_uid\":null,\"path\":[],\"_version\":1,\"title\":\"crop_area.jpeg\",\"dimension\":{\"height\":712,\"width\":864},\"_metadata\":{\"extensions\":{\"extension_uid\":{\"local_metadata\":{\"local_data\":\"main\",\"presets\":[{\"uid\":\"preset_01\",\"name\":\"Local Preset\",\"options\":{}},{\"uid\":\"preset_02\",\"name\":\"WithCrop\",\"options\":{\"quality\":\"100\",\"transform\":{},\"image-type\":\"jpeg\",\"crop\":{}}},{\"uid\":\"preset_03\",\"name\":\"Filter\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":712,\"width\":864},\"image-type\":\"jpeg\",\"effects\":{}}}]},\"global_metadata\":{\"presets\":[{\"uid\":\"preset_04\",\"name\":\"Global Preset\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"712\",\"width\":\"864\",\"flip-mode\":\"verti\"},\"image-type\":\"jpeg\"}}]}}}}}"; public const string kAsset = "{\"uid\":\"asset_uid\",\"created_by\":\"create_by\",\"updated_by\":\"update_by\",\"content_type\":\"image/jpeg\",\"file_size\":\"62181\",\"tags\":[],\"filename\":\"crop_area.jpeg\",\"url\":\"http://image.contenstack.com/crop_area.jpeg\",\"is_dir\":false,\"parent_uid\":null,\"path\":[],\"_version\":1,\"title\":\"crop_area.jpeg\",\"dimension\":{\"height\":712,\"width\":864},\"_metadata\":{}}"; public const string kAssetMetaURLQuery = "{\"uid\":\"asset_uid\",\"created_by\":\"create_by\",\"updated_by\":\"update_by\",\"content_type\":\"image/jpeg\",\"file_size\":\"62181\",\"tags\":[],\"filename\":\"crop_area.jpeg\",\"url\":\"http://image.contenstack.com/crop_area.jpeg?render=full&noval\",\"is_dir\":false,\"parent_uid\":null,\"path\":[],\"_version\":1,\"title\":\"crop_area.jpeg\",\"dimension\":{\"height\":712,\"width\":864},\"_metadata\":{\"extensions\":{\"extension_uid\":{\"local_metadata\":{\"local_data\":\"main\",\"presets\":[{\"uid\":\"preset_01\",\"name\":\"Local Preset\",\"options\":{\"transform\":{\"height\":500,\"width\":500,\"flip-mode\":\"horiz\",\"rotate\":40},\"focal-point\":{\"x\":-0.668935003427432,\"y\":-0.9220385351936531},\"quality\":\"100\",\"image-type\":\"jpeg\"}},{\"uid\":\"preset_02\",\"name\":\"WithCrop\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"569.6\",\"width\":\"569.6\",\"flip-mode\":\"both\"},\"image-type\":\"jpeg\",\"crop\":{\"height\":\"569.6\",\"width\":\"569.6\",\"x\":\"147.2\",\"y\":\"71.2\"}}},{\"uid\":\"preset_03\",\"name\":\"Filter\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":712,\"width\":864},\"image-type\":\"jpeg\",\"effects\":{\"brightness\":52,\"contrast\":15,\"saturate\":-30,\"blur\":16,\"sharpen\":{\"amount\":9,\"radius\":669,\"threshold\":207}}}}]},\"global_metadata\":{\"presets\":[{\"uid\":\"preset_04\",\"name\":\"Global Preset\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"712\",\"width\":\"864\",\"flip-mode\":\"verti\"},\"image-type\":\"jpeg\"}}]}}}}}"; + public const string kJSONRTE = "{ \"uid\":\"uid\",\"_version\":1,\"locale\":\"en-us\",\"children\":[{\"type\":\"p\",\"children\":[{\"text\":\"demoText\",\"bold\":true},{\"text\":\" is\",\"underline\":true},{\"text\":\" demoText\",\"italic\":true}]},{\"type\":\"p\",\"children\":[{\"text\":\"This\",\"italic\":true,\"subscript\":true},{\"text\":\" \",\"italic\":true},{\"text\":\"is\",\"italic\":true,\"superscript\":true},{\"text\":\" \",\"italic\":true},{\"text\":\"same \",\"italic\":true,\"strikethrough\":true}]},{\"type\":\"p\",\"children\":[{\"text\":\"demoText2\",\"strikethrough\":true,\"inlineCode\":true}]},{\"type\":\"p\",\"children\":[{\"text\":\"demoText3\",\"strikethrough\":true,\"inlineCode\":true},{\"text\":\"demoText4\"}]},{\"type\":\"p\",\"children\":[{\"text\":\"demoText3\"},{\"type\":\"a\",\"attrs\":{\"url\":\"https://www.google.com/\",\"target\":\"_blank\",\"title\":\"demoText5\"},\"children\":[{\"text\":\"demoText2\"}]}]}],\"type\":\"doc\"}"; } } diff --git a/Contentstack.Utils.Tests/DefaultRenderTest.cs b/Contentstack.Utils.Tests/DefaultRenderTest.cs index 776f6c9..e69b0cd 100644 --- a/Contentstack.Utils.Tests/DefaultRenderTest.cs +++ b/Contentstack.Utils.Tests/DefaultRenderTest.cs @@ -178,7 +178,7 @@ public void testLinkhDocument() string result = defaultRender.RenderNode("a", nodeLink, (nodes) => { return text; }); - Assert.Equal($"{text}", result); + Assert.Equal($"Text To set Link", result); } [Fact] diff --git a/Contentstack.Utils.Tests/JsonToHtmlTest.cs b/Contentstack.Utils.Tests/JsonToHtmlTest.cs index 9f4b4e1..e49da43 100644 --- a/Contentstack.Utils.Tests/JsonToHtmlTest.cs +++ b/Contentstack.Utils.Tests/JsonToHtmlTest.cs @@ -489,5 +489,13 @@ public void TestForClassandId() Assert.Equal(new List() { JsonToHtmlResultConstants.stringClassIdResult }, result); } + + [Fact] + public void Should_Render_All_Marks_And_Target_Attribute() + { + Node node = NodeParser.parse(JsonToHtmlConstants.kJSONRTE); + var result = Utils.JsonToHtml(node, defaultRender); + Assert.Equal(JsonToHtmlResultConstants.kJSONRTEResult, result); + } } } diff --git a/Contentstack.Utils.sln b/Contentstack.Utils.sln index 12afb40..382b162 100644 --- a/Contentstack.Utils.sln +++ b/Contentstack.Utils.sln @@ -21,7 +21,7 @@ Global {EB2B5E23-E45F-4C6C-BF98-FE3971DE4250}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution - version = 1.0.5 + version = 1.0.6 Policies = $0 $0.DotNetNamingPolicy = $1 $1.DirectoryNamespaceAssociation = PrefixedHierarchical diff --git a/Contentstack.Utils/Models/Options.cs b/Contentstack.Utils/Models/Options.cs index 7cab2fc..724322a 100644 --- a/Contentstack.Utils/Models/Options.cs +++ b/Contentstack.Utils/Models/Options.cs @@ -1,6 +1,6 @@ -using System; +using System; using System.Collections.Generic; -using Contentstack.Utils.Enums; +using Contentstack.Utils.Enums; using Contentstack.Utils.Interfaces; using Newtonsoft.Json.Linq; @@ -23,14 +23,14 @@ public virtual string RenderOption(IEmbeddedObject embeddedObject, Metadata meta switch (metadata.StyleType) { case Enums.StyleType.Block: - string renderString = "

" + embeddedObject.Uid + "

"; + string renderString = "

" + embeddedObject.Uid + "

"; if (embeddedObject is IEmbeddedEntry) { - renderString += "

Content type: " + ((IEmbeddedEntry)embeddedObject).Title + "

"; + renderString += "

Content type: " + ((IEmbeddedEntry)embeddedObject).Title + "

"; } else { - renderString += "

Content type: " + embeddedObject.ContentTypeUid + "

"; + renderString += "

Content type: " + embeddedObject.ContentTypeUid + "

"; } renderString = renderString + "
"; return renderString; @@ -38,32 +38,32 @@ public virtual string RenderOption(IEmbeddedObject embeddedObject, Metadata meta case Enums.StyleType.Inline: if (embeddedObject is IEmbeddedEntry) { - return "" + ((IEmbeddedEntry)embeddedObject).Title + ""; + return "" + ((IEmbeddedEntry)embeddedObject).Title + ""; } - return "" + embeddedObject.Uid + ""; + return "" + embeddedObject.Uid + ""; case Enums.StyleType.Link: if (embeddedObject is IEmbeddedEntry) { - return "" + (metadata.Text ?? ((IEmbeddedEntry)embeddedObject).Title) + ""; + return "" + (metadata.Text ?? ((IEmbeddedEntry)embeddedObject).Title) + ""; } - return "" + (metadata.Text ?? embeddedObject.Uid) + ""; + return "" + (metadata.Text ?? embeddedObject.Uid) + ""; case Enums.StyleType.Display: if (embeddedObject is IEmbeddedAsset) { - return "\"""; + return "\"""; } - return "\"""; + return "\"""; case Enums.StyleType.Download: if (embeddedObject is IEmbeddedAsset) { - return "" + (metadata.Text ?? ((IEmbeddedAsset)embeddedObject).Title) + ""; + return "" + (metadata.Text ?? ((IEmbeddedAsset)embeddedObject).Title) + ""; } - return "" + (metadata.Text ?? embeddedObject.Uid) + ""; + return "" + (metadata.Text ?? embeddedObject.Uid) + ""; } - return ""; + return ""; } public virtual string RenderMark(MarkType markType, string text, string className = "", string id = "") @@ -97,8 +97,10 @@ public virtual string RenderNode(string nodeType, Node node, NodeChildrenCallBac { string href = ""; string styleAttrs = ""; + string target = ""; + string title = ""; - if (node.attrs.ContainsKey("style")) + if (node.attrs?.ContainsKey("style") == true) { var styleVal = node.attrs["style"]; if (styleVal != null) @@ -125,11 +127,20 @@ public virtual string RenderNode(string nodeType, Node node, NodeChildrenCallBac case "p": return $"{callBack(node.children)}

"; case "a": - if (node.attrs.ContainsKey("url")) + if (node.attrs?.ContainsKey("url")==true) { href = (string)node.attrs["url"]; } - return $"{callBack(node.children)}"; + if (node.attrs?.ContainsKey("target") == true) + { + target = (string)node.attrs["target"]; + } + if (node.attrs?.ContainsKey("title") == true) + { + title = (string)node.attrs["title"]; + } + return $"{callBack(node.children)}"; + case "img": if (node.attrs.ContainsKey("url")) { diff --git a/Directory.Build.props b/Directory.Build.props index 18f9aae..2a251d5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@ - 1.0.5 + 1.0.6 From 342722baf89362546ddf1f68c7853312c4dc5bfa Mon Sep 17 00:00:00 2001 From: raj pandey Date: Tue, 3 Jun 2025 17:55:50 +0530 Subject: [PATCH 19/29] Fixed Test cases --- Contentstack.Utils.Tests/DefaultRenderTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Contentstack.Utils.Tests/DefaultRenderTest.cs b/Contentstack.Utils.Tests/DefaultRenderTest.cs index e69b0cd..a13bd5b 100644 --- a/Contentstack.Utils.Tests/DefaultRenderTest.cs +++ b/Contentstack.Utils.Tests/DefaultRenderTest.cs @@ -1,4 +1,4 @@ -using Contentstack.Utils.Models; +using Contentstack.Utils.Models; using Xunit; using Contentstack.Utils.Tests.Mocks; using Contentstack.Utils.Enums; @@ -178,7 +178,7 @@ public void testLinkhDocument() string result = defaultRender.RenderNode("a", nodeLink, (nodes) => { return text; }); - Assert.Equal($"Text To set Link", result); + Assert.Equal($"Text To set Link", result); } [Fact] From c3c69dee52ef51e47b8a5dcafa1d12556fd801f5 Mon Sep 17 00:00:00 2001 From: raj pandey Date: Tue, 3 Jun 2025 18:08:31 +0530 Subject: [PATCH 20/29] License updated --- Contentstack.Utils/LICENSE.txt | 2 +- LICENSE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Contentstack.Utils/LICENSE.txt b/Contentstack.Utils/LICENSE.txt index 3333caa..501f936 100644 --- a/Contentstack.Utils/LICENSE.txt +++ b/Contentstack.Utils/LICENSE.txt @@ -1,6 +1,6 @@ MIT License -Copyright © 2012-2024 Contentstack. All Rights Reserved +Copyright © 2012-2025 Contentstack. All Rights Reserved Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/LICENSE b/LICENSE index 3333caa..501f936 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright © 2012-2024 Contentstack. All Rights Reserved +Copyright © 2012-2025 Contentstack. All Rights Reserved Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 58b671586911549794906b6af45fb2c3f730cab3 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:28:23 +0530 Subject: [PATCH 21/29] sast-scan.yml From cfcfc04788722df7de87521ced2c5204bbd0a7dd Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 20 Jan 2025 12:28:25 +0530 Subject: [PATCH 22/29] codeql-analysis.yml From cfe2f38f1411ed896df0530540a700e323034b8e Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:55:41 +0530 Subject: [PATCH 23/29] codeql-analysis.yml From 3bfbec813c80709bbad89d37a5b75f6b37297a36 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Wed, 16 Apr 2025 10:55:44 +0530 Subject: [PATCH 24/29] Updated codeowners From 501e205f683629013d162be3a7c3d145c13dfd47 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:16:20 +0530 Subject: [PATCH 25/29] policy-scan.yml From 764674b6d7394a3be1040c4874051259ef66fa41 Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:16:28 +0530 Subject: [PATCH 26/29] issues-jira.yml From 7b9e565153811f3e8c178272d7860d1af588b89d Mon Sep 17 00:00:00 2001 From: Aravind Kumar Date: Mon, 5 May 2025 22:16:32 +0530 Subject: [PATCH 27/29] Updated codeowners From 7cd49ae9b0c61bf5b4c40c477226a189199bdd31 Mon Sep 17 00:00:00 2001 From: raj pandey Date: Fri, 6 Jun 2025 18:38:12 +0530 Subject: [PATCH 28/29] Workflow Update --- .github/workflows/sca-scan.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/sca-scan.yml b/.github/workflows/sca-scan.yml index 4fa4560..485f1a5 100644 --- a/.github/workflows/sca-scan.yml +++ b/.github/workflows/sca-scan.yml @@ -3,13 +3,17 @@ on: pull_request: types: [opened, synchronize, reopened] jobs: - security-sca: + security: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master + - name: Checkout repository + uses: actions/checkout@master + - uses: snyk/actions/setup@master + - name: Setup .NET + uses: actions/setup-dotnet@v3.0.3 + - name: Restore dependencies + run: dotnet restore ./Contentstack.Utils.sln - name: Run Snyk to check for vulnerabilities - uses: snyk/actions/dotnet@master + run: cd Contentstack.Utils && snyk test --fail-on=all env: - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} - with: - args: --fail-on=all + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} \ No newline at end of file From ac55d81358c305f7a53448b33c418a0469ee400f Mon Sep 17 00:00:00 2001 From: harshithad0703 <104908717+harshithad0703@users.noreply.github.com> Date: Mon, 9 Jun 2025 16:48:53 +0530 Subject: [PATCH 29/29] Update sca-scan.yml --- .github/workflows/sca-scan.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sca-scan.yml b/.github/workflows/sca-scan.yml index 485f1a5..a642aef 100644 --- a/.github/workflows/sca-scan.yml +++ b/.github/workflows/sca-scan.yml @@ -3,7 +3,7 @@ on: pull_request: types: [opened, synchronize, reopened] jobs: - security: + security-sca: runs-on: ubuntu-latest steps: - name: Checkout repository @@ -16,4 +16,4 @@ jobs: - name: Run Snyk to check for vulnerabilities run: cd Contentstack.Utils && snyk test --fail-on=all env: - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} \ No newline at end of file + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}