Skip to content

Commit da67212

Browse files
authored
Merge pull request #14 from contentstack/CS-30332--set-images-as-references
CS 30332 fixes
2 parents 4539165 + 3cbba9c commit da67212

File tree

9 files changed

+367
-62
lines changed

9 files changed

+367
-62
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# For most projects, this workflow file will not need changing; you simply need
2+
# to commit it to your repository.
3+
#
4+
# You may wish to alter this file to override the set of languages analyzed,
5+
# or to provide custom queries or build logic.
6+
#
7+
# ******** NOTE ********
8+
# We have attempted to detect the languages in your repository. Please check
9+
# the `language` matrix defined below to confirm you have the correct set of
10+
# supported CodeQL languages.
11+
#
12+
name: "CodeQL"
13+
14+
on:
15+
pull_request:
16+
# The branches below must be a subset of the branches above
17+
branches: '*'
18+
19+
jobs:
20+
analyze:
21+
name: Analyze
22+
runs-on: ubuntu-latest
23+
permissions:
24+
actions: read
25+
contents: read
26+
security-events: write
27+
28+
strategy:
29+
fail-fast: false
30+
matrix:
31+
language: [ 'javascript' ]
32+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
33+
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
34+
35+
steps:
36+
- name: Checkout repository
37+
uses: actions/checkout@v3
38+
39+
# Initializes the CodeQL tools for scanning.
40+
- name: Initialize CodeQL
41+
uses: github/codeql-action/init@v2
42+
with:
43+
languages: ${{ matrix.language }}
44+
# If you wish to specify custom queries, you can do so here or in a config file.
45+
# By default, queries listed here will override any specified in a config file.
46+
# Prefix the list here with "+" to use these queries and those in the config file.
47+
48+
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
49+
# queries: security-extended,security-and-quality
50+
51+
52+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
53+
# If this step fails, then you should remove it and run the build manually (see below)
54+
- name: Autobuild
55+
uses: github/codeql-action/autobuild@v2
56+
57+
# ℹ️ Command-line programs to run using the OS shell.
58+
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
59+
60+
# If the Autobuild fails above, remove it and uncomment the following three lines.
61+
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
62+
63+
# - run: |
64+
# echo "Run, Build Application using script"
65+
# ./location_of_script_within_repo/buildscript.sh
66+
67+
- name: Perform CodeQL Analysis
68+
uses: github/codeql-action/analyze@v2

.github/workflows/jira.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Create JIRA ISSUE
2+
on:
3+
pull_request:
4+
types: [opened]
5+
jobs:
6+
security:
7+
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-')}}
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
- name: Login into JIRA
12+
uses: atlassian/gajira-login@master
13+
env:
14+
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
15+
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
16+
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
17+
- name: Create a JIRA Issue
18+
id: create
19+
uses: atlassian/gajira-create@master
20+
with:
21+
project: ${{ secrets.JIRA_PROJECT }}
22+
issuetype: ${{ secrets.JIRA_ISSUE_TYPE }}
23+
summary: |
24+
${{ github.event.pull_request.title }}
25+
description: |
26+
PR: ${{ github.event.pull_request.html_url }}
27+
28+
fields: "${{ secrets.JIRA_FIELDS }}"

.github/workflows/sast-scan.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: SAST Scan
2+
on:
3+
pull_request:
4+
types: [opened, synchronize, reopened]
5+
jobs:
6+
security:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v2
10+
- name: Horusec Scan
11+
run: docker run -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/src horuszup/horusec-cli:latest horusec start -p /src -P $(pwd)

.github/workflows/sca-scan.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Source Composition Analysis Scan
2+
on:
3+
pull_request:
4+
types: [opened, synchronize, reopened]
5+
jobs:
6+
security:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@master
10+
- name: Run Snyk to check for vulnerabilities
11+
uses: snyk/actions/node@master
12+
env:
13+
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
14+
with:
15+
args: --all-projects

.github/workflows/secrets-scan.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: Secrets Scan
2+
on:
3+
pull_request:
4+
types: [opened, synchronize, reopened]
5+
jobs:
6+
security:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v2
10+
- name: Gittyleaks
11+
uses: gupy-io/gittyleaks-action@v0.1

CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @contentstack/security-admin
1+
* @contentstack/security-admin @contentstack/ghost-admin

src/fromRedactor.tsx

Lines changed: 100 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@ const ELEMENT_TAGS: IHtmlToJsonElementTags = {
3232
IMG: (el: HTMLElement) => {
3333
let imageUrl = el.getAttribute('src')?.split(".") || ["png"]
3434
let imageType = imageUrl[imageUrl?.length - 1]
35-
return { type: 'reference', attrs: { "asset-link": el.getAttribute('src'), default: true, "asset-type": `image/${imageType}`, "display-type": "display", "type": "asset" } }
35+
const assetUid = el.getAttribute('asset_uid')
36+
if(assetUid){
37+
38+
const splittedUrl = el.getAttribute('src')?.split('/')! || [null]
39+
const assetName = splittedUrl[splittedUrl?.length - 1]
40+
return { type: 'reference', attrs: { "asset-name": assetName,"content-type-uid" : "sys_assets", "asset-link": el.getAttribute('src'), "asset-type": `image/${imageType}`, "display-type": "display", "type": "asset", "asset-uid": assetUid } }
41+
}
42+
return { type: 'img', attrs: { url: el.getAttribute('src') } }
3643
},
3744
LI: () => ({ type: 'li', attrs: {} }),
3845
OL: () => ({ type: 'ol', attrs: {} }),
@@ -46,7 +53,17 @@ const ELEMENT_TAGS: IHtmlToJsonElementTags = {
4653
TR: (el: HTMLElement) => ({ type: 'tr', attrs: {} }),
4754
TD: (el: HTMLElement) => ({ type: 'td', attrs: {} }),
4855
TH: (el: HTMLElement) => ({ type: 'th', attrs: {} }),
49-
FIGURE: (el: HTMLElement) => ({ type: 'reference', attrs: { default: true, "display-type": "display", "type": "asset" } }),
56+
// FIGURE: (el: HTMLElement) => ({ type: 'reference', attrs: { default: true, "display-type": "display", "type": "asset" } }),
57+
58+
FIGURE: (el: HTMLElement) => {
59+
if (el.lastChild && el.lastChild.nodeName === 'P') {
60+
return { type: 'figure', attrs: {} }
61+
}
62+
else {
63+
return { type: 'img', attrs: {} }
64+
}
65+
66+
},
5067
SPAN: (el: HTMLElement) => {
5168
return { type: 'span', attrs: {} }
5269
},
@@ -383,7 +400,7 @@ export const fromRedactor = (el: any, options?:IHtmlToJsonOptions) : IAnyObject
383400
const attrs = {
384401
type: 'grid-container',
385402
attrs: {
386-
gutter
403+
gutter
387404
}
388405
}
389406
return jsx('element', attrs, children)
@@ -493,39 +510,61 @@ export const fromRedactor = (el: any, options?:IHtmlToJsonOptions) : IAnyObject
493510
sizeAttrs.width = el.style.width
494511
if (sizeAttrs.width[sizeAttrs.width.length - 1] === '%') {
495512
sizeAttrs.width = Number(sizeAttrs.width.slice(0, sizeAttrs.width.length - 1))
496-
} else if (sizeAttrs.width.slice(sizeAttrs.width.length - 2) === 'px') {
497-
sizeAttrs.width = (Number(sizeAttrs.width.slice(0, sizeAttrs.width.length - 2)) / window?.screen?.width || 1920) * 100
513+
}
514+
515+
else if (sizeAttrs.width.slice(sizeAttrs.width.length - 2) === 'px') {
516+
sizeAttrs.width = Number(sizeAttrs.width.slice(0, sizeAttrs.width.length - 2))
498517
}
499518
}
500519
if (el.style?.['max-width']) {
501520
sizeAttrs['max-width'] = el.style['max-width']
502521
if (sizeAttrs['max-width'][sizeAttrs['max-width'].length - 1] === '%') {
503522
sizeAttrs['max-width'] = Number(sizeAttrs['max-width'].slice(0, sizeAttrs['max-width'].length - 1))
504-
} else if (sizeAttrs['max-width'].slice(sizeAttrs['max-width'].length - 2) === 'px') {
523+
}
524+
525+
else if (sizeAttrs['max-width'].slice(sizeAttrs['max-width'].length - 2) === 'px') {
505526
sizeAttrs['max-width'] =
506-
(Number(sizeAttrs['max-width'].slice(0, sizeAttrs['max-width'].length - 2)) / window?.screen?.width || 1920) * 100
527+
Number(sizeAttrs['max-width'].slice(0, sizeAttrs['max-width'].length - 2))
507528
}
508529
}
509530
let captionElements = el.getElementsByTagName("FIGCAPTION")
510-
if (captionElements?.[0]?.textContent) {
511-
extraAttrs['asset-caption'] = captionElements?.[0]?.textContent
531+
532+
if (captionElements?.[0]) {
533+
let caption = captionElements[0]
534+
const captionElementsAttrs = caption.attributes
535+
const captionAttrs = {}
536+
if (captionElementsAttrs) {
537+
Array.from(captionElementsAttrs).forEach((child: any) => {
538+
captionAttrs[child.nodeName] = child.nodeValue
539+
})
540+
}
541+
extraAttrs['captionAttrs'] = captionAttrs
542+
extraAttrs['caption'] = captionElements?.[0]?.textContent
543+
544+
}
545+
if (newChildren[0]?.type === 'img') {
546+
elementAttrs = getFinalImageAttributes({elementAttrs, newChildren, extraAttrs, sizeAttrs})
547+
}
548+
if (newChildren[0]?.type === 'reference') {
549+
elementAttrs = getReferenceAttributes({elementAttrs, newChildren, extraAttrs, sizeAttrs})
512550
}
513551
if (newChildren[0]?.type === 'a') {
514-
const { link, target } = newChildren[0].attrs?.["redactor-attributes"]
515-
extraAttrs['link'] = link
552+
const { href, target } = newChildren[0].attrs?.["redactor-attributes"]
553+
extraAttrs['anchorLink'] = href;
516554
if (target && target !== '') {
517-
extraAttrs['target'] = true
555+
extraAttrs['target'] = true;
556+
}
557+
const imageAttrs = newChildren[0].children;
558+
559+
if(imageAttrs[0].type === 'img'){
560+
elementAttrs = getFinalImageAttributes({elementAttrs, newChildren : imageAttrs, extraAttrs, sizeAttrs})
561+
562+
}
563+
if(imageAttrs[0].type === 'reference'){
564+
elementAttrs = getReferenceAttributes({elementAttrs, newChildren: imageAttrs, extraAttrs, sizeAttrs})
518565
}
519-
const imageAttrs = newChildren[0].children[0]
520-
elementAttrs = getImageAttributes(elementAttrs, imageAttrs.attrs || {}, { ...extraAttrs, ...sizeAttrs })
521-
}
522-
if (newChildren[0]?.type === 'reference' && newChildren[0]?.attrs?.default) {
523-
elementAttrs = getImageAttributes(
524-
elementAttrs,
525-
{ ...newChildren[0].attrs, ...sizeAttrs },
526-
{ ...extraAttrs, ...sizeAttrs }
527-
)
528566
}
567+
529568
return jsx('element', elementAttrs, [{ text: '' }])
530569
}
531570

@@ -713,3 +752,43 @@ const getImageAttributes = (elementAttrs: any, childAttrs: any, extraAttrs: any)
713752
}
714753
return elementAttrs
715754
}
755+
756+
const getReferenceAttributes = ({elementAttrs, newChildren, extraAttrs, sizeAttrs} : any) => {
757+
758+
let { style } = elementAttrs.attrs;
759+
760+
extraAttrs['asset-caption'] = extraAttrs['caption'];
761+
762+
const childAttrs = { ...newChildren[0].attrs, ...sizeAttrs, style: { 'text-align': style['text-align'] }, position: extraAttrs.position }
763+
extraAttrs = { ...extraAttrs, ...sizeAttrs }
764+
765+
if (!childAttrs.position) {
766+
delete childAttrs.position
767+
}
768+
769+
const referenceAttrs = getImageAttributes(elementAttrs, childAttrs, extraAttrs);
770+
771+
referenceAttrs.type = "reference";
772+
773+
return referenceAttrs
774+
}
775+
776+
const getFinalImageAttributes = ({elementAttrs, newChildren, extraAttrs, sizeAttrs} : any) => {
777+
778+
let { style } = elementAttrs.attrs;
779+
780+
if (newChildren[0].attrs.width) {
781+
sizeAttrs.width = newChildren[0].attrs.width.toString();
782+
}
783+
784+
const childAttrs = { ...newChildren[0].attrs, ...sizeAttrs, style: { 'text-align': style['text-align'] }, caption: extraAttrs['caption'] }
785+
extraAttrs = { ...extraAttrs, ...sizeAttrs }
786+
787+
if (!childAttrs.caption) {
788+
delete childAttrs.caption
789+
}
790+
791+
const imageAttrs = getImageAttributes(elementAttrs, childAttrs, extraAttrs);
792+
793+
return imageAttrs
794+
}

0 commit comments

Comments
 (0)