Skip to content

Commit ae78835

Browse files
authored
Merge pull request #117 from contentstack/fix/MKT-17450-audit-fix
Fix/mkt 17450 audit fix
2 parents 0f3bcbb + 9c69900 commit ae78835

20 files changed

Lines changed: 8265 additions & 12162 deletions

.env.local.sample

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11

22
# This is a settings file for our application.
33

4-
# Contentstack is the tool we use to manage our website's content.
5-
# You need to replace 'your_stack_api_key', 'your_delivery_token', and 'your_environment_name' with the actual information.
6-
CONTENTSTACK_API_KEY=your_stack_api_key
7-
CONTENTSTACK_DELIVERY_TOKEN=your_delivery_token
8-
CONTENTSTACK_ENVIRONMENT=your_environment_name
4+
# Contentstack — use NEXT_PUBLIC_* only (available in browser + server via Next.js).
5+
NEXT_PUBLIC_CONTENTSTACK_API_KEY=your_stack_api_key
6+
NEXT_PUBLIC_CONTENTSTACK_DELIVERY_TOKEN=your_delivery_token
7+
NEXT_PUBLIC_CONTENTSTACK_ENVIRONMENT=your_environment_name
98

10-
# Live Preview lets us see changes before they are shown on the website.
11-
# Replace 'your_live_preview_token' with the actual information.
12-
CONTENTSTACK_PREVIEW_HOST=rest-preview.contentstack.com
13-
CONTENTSTACK_PREVIEW_TOKEN=your_live_preview_token
14-
CONTENTSTACK_APP_HOST=app.contentstack.com
15-
CONTENTSTACK_LIVE_PREVIEW=true
16-
CONTENTSTACK_LIVE_EDIT_TAGS=false
9+
# Live Preview
10+
NEXT_PUBLIC_CONTENTSTACK_PREVIEW_HOST=rest-preview.contentstack.com
11+
NEXT_PUBLIC_CONTENTSTACK_PREVIEW_TOKEN=your_live_preview_token
12+
NEXT_PUBLIC_CONTENTSTACK_APP_HOST=app.contentstack.com
13+
NEXT_PUBLIC_CONTENTSTACK_LIVE_PREVIEW=true
14+
NEXT_PUBLIC_CONTENTSTACK_LIVE_EDIT_TAGS=false
1715

18-
# These are extra settings. You can remove the '#' at the start of the line and fill these if needed.
19-
# CONTENTSTACK_API_HOST= api.contentstack.io
20-
# CONTENTSTACK_REGION=us
21-
# CONTENTSTACK_BRANCH=main
16+
# Optional (defaults in next.config.js if unset)
17+
# NEXT_PUBLIC_CONTENTSTACK_API_HOST=api.contentstack.io
18+
# NEXT_PUBLIC_CONTENTSTACK_REGION=us
19+
# NEXT_PUBLIC_CONTENTSTACK_BRANCH=main
2220

23-
#site-map
21+
# Site map
2422
NEXT_PUBLIC_HOSTED_URL=http://localhost:3000
2523

2624
# Notes:
27-
# - CONTENTSTACK_API_HOST: This is for setting a custom address for the Contentstack tool.
28-
# - CONTENTSTACK_REGION: This is for setting a custom region for the Contentstack tool (default is 'us').
29-
# - CONTENTSTACK_BRANCH: This is for setting a custom branch for the Contentstack tool (default is 'main').
30-
# - CONTENTSTACK_PREVIEW_HOST: If you're in the EU just append "eu-" to "rest-preview.contentstack.com"
31-
# - example eu-rest-preview.contentstack.com
25+
# - NEXT_PUBLIC_CONTENTSTACK_API_HOST: custom Contentstack API host if needed.
26+
# - NEXT_PUBLIC_CONTENTSTACK_REGION: default is us.
27+
# - NEXT_PUBLIC_CONTENTSTACK_BRANCH: default is main.
28+
# - NEXT_PUBLIC_CONTENTSTACK_PREVIEW_HOST: EU example — eu-rest-preview.contentstack.com
29+
# - Delivery + preview tokens are exposed in the client bundle; use preview-scoped tokens only.

.eslintrc.json

Lines changed: 0 additions & 28 deletions
This file was deleted.

.github/workflows/sca-scan.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ jobs:
1313
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
1414
with:
1515
args: --all-projects --fail-on=all
16+
json: true
17+
continue-on-error: true
18+
- uses: contentstack/sca-policy@main

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ yarn-error.log*
2626
.pnpm-debug.log*
2727

2828
# local env files
29+
.env
2930
.env*.local
3031

3132
# vercel

.npmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
timeout=60000
1+
fetch-timeout=60000

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 Contentstack
3+
Copyright (c) 2026 Contentstack
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

components/layout.tsx

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,41 @@
1-
import React, { useState, useEffect } from 'react';
1+
import React, { useMemo } from 'react';
22
import Header from './header';
33
import Footer from './footer';
44
import DevTools from './devtools';
55
import { HeaderProps, FooterProps, PageProps, Posts, ChilderenProps, Entry, NavLinks, Links } from "../typescript/layout";
66

7+
function buildNavigation(ent: Entry, hd: HeaderProps, ft: FooterProps) {
8+
let newHeader = { ...hd };
9+
let newFooter = { ...ft };
10+
if (ent.length !== newHeader.navigation_menu.length) {
11+
ent.forEach((entry) => {
12+
const hFound = newHeader?.navigation_menu.find(
13+
(navLink: NavLinks) => navLink.label === entry.title
14+
);
15+
if (!hFound) {
16+
newHeader.navigation_menu?.push({
17+
label: entry.title,
18+
page_reference: [
19+
{ title: entry.title, url: entry.url, $: entry.$ },
20+
],
21+
$: {},
22+
});
23+
}
24+
const fFound = newFooter?.navigation.link.find(
25+
(nlink: Links) => nlink.title === entry.title
26+
);
27+
if (!fFound) {
28+
newFooter.navigation.link?.push({
29+
title: entry.title,
30+
href: entry.url,
31+
$: entry.$,
32+
});
33+
}
34+
});
35+
}
36+
return [newHeader, newFooter];
37+
}
38+
739
export default function Layout({
840
header,
941
footer,
@@ -14,51 +46,19 @@ export default function Layout({
1446
children,
1547
}: { header: HeaderProps, footer: FooterProps, page: PageProps, blogPost: Posts, blogList: Posts, entries: Entry, children: ChilderenProps }) {
1648

17-
const [getLayout, setLayout] = useState({ header, footer });
49+
const getLayout = useMemo(() => {
50+
if (footer && header && entries) {
51+
const [newHeader, newFooter] = buildNavigation(entries, header, footer);
52+
return { header: newHeader, footer: newFooter };
53+
}
54+
return { header, footer };
55+
}, [header, footer, entries]);
56+
1857
const jsonObj: any = { header, footer };
1958
page && (jsonObj.page = page);
2059
blogPost && (jsonObj.blog_post = blogPost);
2160
blogList && (jsonObj.blog_post = blogList);
2261

23-
function buildNavigation(ent: Entry, hd: HeaderProps, ft: FooterProps) {
24-
let newHeader = { ...hd };
25-
let newFooter = { ...ft };
26-
if (ent.length !== newHeader.navigation_menu.length) {
27-
ent.forEach((entry) => {
28-
const hFound = newHeader?.navigation_menu.find(
29-
(navLink: NavLinks) => navLink.label === entry.title
30-
);
31-
if (!hFound) {
32-
newHeader.navigation_menu?.push({
33-
label: entry.title,
34-
page_reference: [
35-
{ title: entry.title, url: entry.url, $: entry.$ },
36-
],
37-
$: {},
38-
});
39-
}
40-
const fFound = newFooter?.navigation.link.find(
41-
(nlink: Links) => nlink.title === entry.title
42-
);
43-
if (!fFound) {
44-
newFooter.navigation.link?.push({
45-
title: entry.title,
46-
href: entry.url,
47-
$: entry.$,
48-
});
49-
}
50-
});
51-
}
52-
return [newHeader, newFooter];
53-
}
54-
55-
useEffect(() => {
56-
if (footer && header && entries) {
57-
const [newHeader, newFooter] = buildNavigation(entries, header, footer);
58-
setLayout({ header: newHeader, footer: newFooter });
59-
}
60-
}, [header, footer]);
61-
6262
return (
6363
<>
6464
{header ? <Header header={getLayout.header} entries={entries} /> : ''}

components/tool-tip.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,37 @@ type TooltipProps = {
1010
}
1111

1212
const Tooltip = (props: TooltipProps) => {
13-
let timeout: any;
13+
const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
1414
const toolTipRef = useRef() as MutableRefObject <HTMLDivElement>;
1515

1616
const showTip = () => {
17-
timeout = setTimeout(() => {
17+
hideTimeoutRef.current = setTimeout(() => {
1818
toolTipRef.current.style.display = "block";
1919
}, props.delay || 400);
2020
};
2121

2222
const hideTip = () => {
23-
clearInterval(timeout);
23+
if (hideTimeoutRef.current !== null) {
24+
clearTimeout(hideTimeoutRef.current);
25+
hideTimeoutRef.current = null;
26+
}
2427
toolTipRef.current.style.display = "none";
2528
};
2629

2730
useEffect(() => {
2831
if (props.dynamic) {
2932
props.status !== 0 && (toolTipRef.current.style.display = "block");
30-
timeout = setTimeout(() => {
33+
hideTimeoutRef.current = setTimeout(() => {
3134
toolTipRef.current.style.display = "none";
3235
}, props.delay || 400);
3336
}
34-
}, [props.content]);
37+
return () => {
38+
if (hideTimeoutRef.current !== null) {
39+
clearTimeout(hideTimeoutRef.current);
40+
hideTimeoutRef.current = null;
41+
}
42+
};
43+
}, [props.content, props.delay, props.dynamic, props.status]);
3544

3645
return (
3746
<div

contentstack-sdk/index.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as Utils from "@contentstack/utils";
22
import ContentstackLivePreview from "@contentstack/live-preview-utils";
3-
import getConfig from "next/config";
43
import {
54
customHostUrl,
65
initializeContentStackSdk,
@@ -20,14 +19,12 @@ type GetEntryByUrl = {
2019
jsonRtePath: string[] | undefined;
2120
};
2221

23-
const { publicRuntimeConfig } = getConfig();
24-
const envConfig = process.env.CONTENTSTACK_API_KEY
25-
? process.env
26-
: publicRuntimeConfig;
22+
let customHostBaseUrl = process.env
23+
.NEXT_PUBLIC_CONTENTSTACK_API_HOST as string;
2724

28-
let customHostBaseUrl = envConfig.CONTENTSTACK_API_HOST as string;
29-
30-
customHostBaseUrl = customHostBaseUrl? customHostUrl(customHostBaseUrl): '';
25+
customHostBaseUrl = customHostBaseUrl
26+
? customHostUrl(customHostBaseUrl)
27+
: "";
3128

3229
// SDK initialization
3330
const Stack = initializeContentStackSdk();
@@ -41,10 +38,10 @@ if (!!customHostBaseUrl && isValidCustomHostUrl(customHostBaseUrl)) {
4138
ContentstackLivePreview.init({
4239
//@ts-ignore
4340
stackSdk: Stack,
44-
clientUrlParams:{
45-
host: envConfig.CONTENTSTACK_APP_HOST,
41+
clientUrlParams: {
42+
host: process.env.NEXT_PUBLIC_CONTENTSTACK_APP_HOST,
4643
},
47-
ssr:false,
44+
ssr: false,
4845
})?.catch((err) => console.error(err));
4946

5047
export const { onEntryChange } = ContentstackLivePreview;

0 commit comments

Comments
 (0)