Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [v1.31.3](https://github.com/contentstack/contentstack-management-javascript/tree/v1.31.3) (2026-11-02)

- Resolved security vulnerabilities in dependencies
- `qs` updated to `~6.16.2` (SNYK-JS-QS-20943482, SNYK-JS-QS-21755395)
- `follow-redirects` (via `axios`) updated to 1.16.2 (SNYK-JS-FOLLOWREDIRECTS-21249784, SNYK-JS-FOLLOWREDIRECTS-21280747, SNYK-JS-FOLLOWREDIRECTS-21762031)
- Tests: replaced hardcoded passwords, emails, API keys, tokens and MFA secrets with per-run generated values to resolve Snyk Code findings. No change to the published package.

## [v1.31.2](https://github.com/contentstack/contentstack-management-javascript/tree/v1.31.2) (2026-09-22)

- Resolved security vulnerabilities in dependencies
Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@contentstack/management",
"version": "1.31.2",
"version": "1.31.3",
"description": "The Content Management API is used to manage the content of your Contentstack account",
"main": "./dist/node/contentstack-management.js",
"browser": "./dist/web/contentstack-management.js",
Expand Down Expand Up @@ -61,7 +61,7 @@
"husky": "^9.1.7",
"lodash": "^4.18.1",
"otplib": "^12.0.1",
"qs": "^6.16.0",
"qs": "~6.16.2",
"stream-browserify": "^3.0.0"
},
"keywords": [
Expand Down Expand Up @@ -117,4 +117,4 @@
"webpack-merge": "6.0.1"
},
"homepage": "https://www.contentstack.com"
}
}
17 changes: 17 additions & 0 deletions test/helpers/testSecrets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { randomBytes } from 'crypto'

const token = (prefix) => `${prefix}${randomBytes(8).toString('hex')}`
const BASE32 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
const base32 = (length) => Array.from(randomBytes(length), (b) => BASE32[b % 32]).join('')

export const TEST_PASSWORD = token('pw_')
export const WRONG_PASSWORD = token('wrong_pw_')
export const TEST_EMAIL = `${token('user_')}@example.com`
export const TFA_TEST_EMAIL = `${token('tfa_')}@example.com`
export const WRONG_EMAIL = `${token('wrong_')}@example.com`
export const INVALID_EMAIL = token('invalid_email_')
export const TEST_API_KEY = token('key_')
export const INVALID_API_KEY = token('invalid_key_')
export const TEST_MFA_SECRET = base32(16)
export const TEST_ACCESS_TOKEN = token('access_')
export const TEST_REFRESH_TOKEN = token('refresh_')
7 changes: 3 additions & 4 deletions test/sanity-check/api/stack-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { expect } from 'chai'
import { describe, it, before, after } from 'mocha'
import { contentstackClient } from '../utility/ContentstackClient.js'
import { testData, trackedExpect } from '../utility/testHelpers.js'
import { INVALID_API_KEY } from '../../helpers/testSecrets'

describe('Stack API Tests', () => {
let client
Expand Down Expand Up @@ -77,8 +78,7 @@ describe('Stack API Tests', () => {
})

it('should fail to fetch with invalid API key', async () => {
// deepcode ignore HardcodedNonCryptoSecret: test fixture value, not a real secret
const invalidStack = client.stack({ api_key: 'invalid_api_key_12345' })
const invalidStack = client.stack({ api_key: INVALID_API_KEY })

try {
await invalidStack.fetch()
Expand Down Expand Up @@ -337,8 +337,7 @@ describe('Stack API Tests', () => {
})

it('should return proper error structure', async () => {
// deepcode ignore HardcodedNonCryptoSecret: test fixture value, not a real secret
const invalidStack = client.stack({ api_key: 'invalid_key' })
const invalidStack = client.stack({ api_key: INVALID_API_KEY })

try {
await invalidStack.fetch()
Expand Down
31 changes: 11 additions & 20 deletions test/sanity-check/api/user-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { contentstackClient, getTestContext } from '../utility/ContentstackClien
import { testData, trackedExpect, wait } from '../utility/testHelpers.js'
// Import from dist (built version) to avoid ESM module resolution issues
import * as contentstack from '../../../dist/node/contentstack-management.js'
import { TEST_PASSWORD, WRONG_PASSWORD, TEST_EMAIL, TFA_TEST_EMAIL, WRONG_EMAIL, INVALID_EMAIL, INVALID_API_KEY, TEST_MFA_SECRET } from '../../helpers/testSecrets'

describe('User & Authentication API Tests', () => {
let client
Expand Down Expand Up @@ -116,8 +117,7 @@ describe('User & Authentication API Tests', () => {
this.timeout(15000)

try {
// deepcode ignore NoHardcodedCredentials,NoHardcodedPasswords: false positive - method signature/parameter names, not a real secret
await client.login({ email: 'invalid-email', password: 'password123' })
await client.login({ email: INVALID_EMAIL, password: TEST_PASSWORD })
expect.fail('Should have thrown an error')
} catch (error) {
expect(error).to.exist
Expand All @@ -130,10 +130,8 @@ describe('User & Authentication API Tests', () => {

try {
await client.login({
// deepcode ignore NoHardcodedCredentials: false positive - method signature/parameter names, no actual hardcoded credential
email: process.env.EMAIL || 'test@example.com',
// deepcode ignore NoHardcodedPasswords: test fixture value, not a real secret
password: 'wrong_password_12345'
email: process.env.EMAIL || TEST_EMAIL,
password: WRONG_PASSWORD
})
expect.fail('Should have thrown an error')
} catch (error) {
Expand All @@ -149,8 +147,7 @@ describe('User & Authentication API Tests', () => {
try {
await client.login({
email: 'nonexistent_user_' + Date.now() + '@test-invalid.com',
// deepcode ignore NoHardcodedPasswords: test fixture value, not a real secret
password: 'password123'
password: TEST_PASSWORD
})
expect.fail('Should have thrown an error')
} catch (error) {
Expand All @@ -163,8 +160,7 @@ describe('User & Authentication API Tests', () => {
this.timeout(15000)

try {
// deepcode ignore NoHardcodedCredentials,NoHardcodedPasswords: false positive - method signature/parameter names, not a real secret
await client.login({ email: 'test@test.com', password: 'wrongpassword' })
await client.login({ email: WRONG_EMAIL, password: WRONG_PASSWORD })
expect.fail('Should have thrown an error')
} catch (error) {
// Validate error structure
Expand Down Expand Up @@ -266,8 +262,7 @@ describe('User & Authentication API Tests', () => {
}

const authClient = contentstackClient()
// deepcode ignore HardcodedNonCryptoSecret: test fixture value, not a real secret
const stack = authClient.stack({ api_key: 'invalid_api_key_12345' })
const stack = authClient.stack({ api_key: INVALID_API_KEY })

try {
await stack.fetch()
Expand Down Expand Up @@ -402,10 +397,8 @@ describe('User & Authentication API Tests', () => {

try {
await client.login({
// deepcode ignore NoHardcodedCredentials: false positive - method signature/parameter names, no actual hardcoded credential
email: process.env.TFA_EMAIL || 'tfa_test@example.com',
// deepcode ignore NoHardcodedPasswords: test fixture value, not a real secret
password: process.env.TFA_PASSWORD || 'password123'
email: process.env.TFA_EMAIL || TFA_TEST_EMAIL,
password: process.env.TFA_PASSWORD || TEST_PASSWORD
})
// If 2FA is not enabled, login succeeds
expect(true).to.equal(true)
Expand Down Expand Up @@ -479,8 +472,7 @@ describe('User & Authentication API Tests', () => {
await client.login({
email: process.env.EMAIL,
password: process.env.PASSWORD,
// deepcode ignore HardcodedNonCryptoSecret: test fixture value, not a real secret
mfaSecret: 'JBSWY3DPEHPK3PXP' // Test secret (won't work but validates SDK accepts it)
mfaSecret: TEST_MFA_SECRET // Generated secret (won't work but validates SDK accepts it)
})
// If account doesn't have 2FA, this might succeed
} catch (error) {
Expand All @@ -497,8 +489,7 @@ describe('User & Authentication API Tests', () => {
try {
await client.login({
email: 'tfa_test_' + Date.now() + '@example.com',
// deepcode ignore NoHardcodedPasswords: test fixture value, not a real secret
password: 'password123',
password: TEST_PASSWORD,
tfa_token: '123456'
})
// Non-existent user will fail regardless of tfa_token
Expand Down
5 changes: 3 additions & 2 deletions test/sanity-check/mock/configurations.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
// ENVIRONMENTS
// ============================================================================

import { TEST_API_KEY } from '../../helpers/testSecrets'

export const developmentEnvironment = {
environment: {
name: 'development',
Expand Down Expand Up @@ -538,8 +540,7 @@ export const widgetExtension = {
type: 'widget',
src: 'https://example.com/analytics-widget.html',
config: {
// deepcode ignore HardcodedNonCryptoSecret: test fixture value, not a real secret
api_key: 'analytics-key'
api_key: TEST_API_KEY
},
tags: ['analytics', 'dashboard']
}
Expand Down
Loading
Loading