Skip to content

Commit 681833d

Browse files
Merge pull request #424 from contentstack/staging
DX | 18-08-2025 | Release
2 parents 946eef7 + e9e8218 commit 681833d

10 files changed

+386
-39
lines changed

.talismanrc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ fileignoreconfig:
99
ignore_detectors:
1010
- filecontent
1111
- filename: package-lock.json
12-
checksum: b043facad4b4aca7a013730746bdb9cb9e9dfca1e5d6faf11c068fc2525569c0
12+
checksum: c37956b0e6ccd5267dac7fd6f4347fbb5ad41defe1c42d39aaaeaf64d2cf8605
1313
- filename: .husky/pre-commit
1414
checksum: 52a664f536cf5d1be0bea19cb6031ca6e8107b45b6314fe7d47b7fad7d800632
1515
- filename: test/sanity-check/api/user-test.js
@@ -26,4 +26,8 @@ fileignoreconfig:
2626
checksum: e8a32ffbbbdba2a15f3d327273f0a5b4eb33cf84cd346562596ab697125bbbc6
2727
- filename: test/sanity-check/api/bulkOperation-test.js
2828
checksum: f40a14c84ab9a194aaf830ca68e14afde2ef83496a07d4a6393d7e0bed15fb0e
29+
- filename: lib/contentstackClient.js
30+
checksum: b76ca091caa3a1b2658cd422a2d8ef3ac9996aea0aff3f982d56bb309a3d9fde
31+
- filename: test/unit/ContentstackClient-test.js
32+
checksum: 974a4f335aef025b657d139bb290233a69bed1976b947c3c674e97baffe4ce2f
2933
version: "1.0"

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22

3-
## [v1.23.1](https://github.com/contentstack/contentstack-management-javascript/tree/v1.24.0) (2025-07-28)
3+
## [v1.24.0](https://github.com/contentstack/contentstack-management-javascript/tree/v1.24.0) (2025-08-18)
4+
- Feat
5+
- Added Support for MFA
6+
7+
## [v1.23.1](https://github.com/contentstack/contentstack-management-javascript/tree/v1.23.1) (2025-07-28)
48
- Fix
59
- Add asset types support in bulk operations
610

README.md

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,31 @@ Install it via npm:
1919
```bash
2020
npm i @contentstack/management
2121
```
22-
To import the SDK, use the following command:
23-
```javascript
24-
import contentstack from ‘@contentstack/management’
25-
26-
contentstackClient = contentstack.client()
27-
```
22+
To import the SDK, use one of the following ways :
23+
1. **JavaScript ES Modules**
24+
```javascript
25+
import contentstack from '@contentstack/management';
26+
```
27+
- Requires `"type": "module"` in package.json
28+
29+
2. **TypeScript with esModuleInterop**
30+
```typescript
31+
import contentstack from '@contentstack/management';
32+
```
33+
- Requires `"esModuleInterop": true` in tsconfig.json
34+
35+
3. **TypeScript Namespace Import**
36+
```typescript
37+
import * as contentstack from '@contentstack/management';
38+
```
39+
- Works regardless of esModuleInterop setting
40+
41+
4. **TypeScript Destructuring**
42+
```typescript
43+
import contentstack from '@contentstack/management';
44+
const { client } = contentstack;
45+
```
46+
- Access client function from default export
2847

2948
### Authentication
3049
To use this SDK, you need to authenticate your users by using the Authtoken, credentials, or Management Token (stack-level token).

lib/contentstackClient.js

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import cloneDeep from 'lodash/cloneDeep'
77
import { User } from './user/index'
88
import error from './core/contentstackError'
99
import OAuthHandler from './core/oauthHandler'
10+
import { authenticator } from 'otplib'
1011

1112
export default function contentstackClient ({ http }) {
1213
/**
@@ -16,7 +17,8 @@ export default function contentstackClient ({ http }) {
1617
* @param {Object} parameters - login parameters
1718
* @prop {string} parameters.email - email id for user to login
1819
* @prop {string} parameters.password - password for user to login
19-
* @prop {string} parameters.token - token for user to login
20+
* @prop {string} parameters.tfa_token - tfa token for user to login (2FA token)
21+
* @prop {string} parameters.mfaSecret - TOTP secret key for generating 2FA token
2022
* @returns {Promise}
2123
* @example
2224
* import * as contentstack from '@contentstack/management'
@@ -25,10 +27,23 @@ export default function contentstackClient ({ http }) {
2527
* client.login({ email: <emailid>, password: <password> })
2628
* .then(() => console.log('Logged in successfully'))
2729
*
30+
* @example
31+
* client.login({ email: <emailid>, password: <password>, tfa_token: <tfa_token> })
32+
* .then(() => console.log('Logged in successfully'))
33+
*
34+
* @example
35+
* client.login({ email: <emailid>, password: <password>, mfaSecret: <mfa_secret> })
36+
* .then(() => console.log('Logged in successfully'))
2837
*/
29-
function login (requestBody, params = {}) {
38+
function login (requestBody = {}, params = {}) {
3039
http.defaults.versioningStrategy = 'path'
3140

41+
const { mfaSecret, ...credentials } = requestBody
42+
requestBody = credentials
43+
44+
if (!requestBody.tfa_token && mfaSecret) {
45+
requestBody.tfa_token = authenticator.generate(mfaSecret)
46+
}
3247
return http.post('/user-session', { user: requestBody }, { params: params })
3348
.then((response) => {
3449
if (response.data.user != null && response.data.user.authtoken != null) {
@@ -55,10 +70,9 @@ export default function contentstackClient ({ http }) {
5570
*/
5671
function getUser (params = {}) {
5772
http.defaults.versioningStrategy = 'path'
58-
return http.get('/user', { params: params })
59-
.then((response) => {
60-
return new User(http, response.data)
61-
}, error)
73+
return http.get('/user', { params: params }).then((response) => {
74+
return new User(http, response.data)
75+
}, error)
6276
}
6377
/**
6478
* @description Get Stack instance. A stack is a space that stores the content of a project.
@@ -127,13 +141,16 @@ export default function contentstackClient ({ http }) {
127141
*/
128142
function organization (uid = null) {
129143
http.defaults.versioningStrategy = 'path'
130-
return new Organization(http, uid !== null ? { organization: { uid: uid } } : null)
144+
return new Organization(
145+
http,
146+
uid !== null ? { organization: { uid: uid } } : null
147+
)
131148
}
132149

133150
/**
134151
* @description The Log out of your account call is used to sign out the user of Contentstack account.
135152
* @memberof ContentstackClient
136-
* @param {String} authtoken - Authtoken to logout from.
153+
* @param {String} authtoken - Authtoken to logout from.
137154
* @func logout
138155
* @returns {Object} Response object.
139156
*
@@ -152,25 +169,25 @@ export default function contentstackClient ({ http }) {
152169
function logout (authtoken) {
153170
http.defaults.versioningStrategy = 'path'
154171
if (authtoken !== undefined) {
155-
return http.delete('/user-session', {
156-
headers: {
157-
authtoken: authtoken
158-
}
159-
})
172+
return http
173+
.delete('/user-session', {
174+
headers: {
175+
authtoken: authtoken
176+
}
177+
})
160178
.then((response) => {
161179
return response.data
162180
}, error)
163181
}
164-
return http.delete('/user-session')
165-
.then((response) => {
166-
if (http.defaults.headers.common) {
167-
delete http.defaults.headers.common.authtoken
168-
}
169-
delete http.defaults.headers.authtoken
170-
delete http.httpClientParams.authtoken
171-
delete http.httpClientParams.headers.authtoken
172-
return response.data
173-
}, error)
182+
return http.delete('/user-session').then((response) => {
183+
if (http.defaults.headers.common) {
184+
delete http.defaults.headers.common.authtoken
185+
}
186+
delete http.defaults.headers.authtoken
187+
delete http.httpClientParams.authtoken
188+
delete http.httpClientParams.headers.authtoken
189+
return response.data
190+
}, error)
174191
}
175192

176193
/**
@@ -201,7 +218,15 @@ export default function contentstackClient ({ http }) {
201218
const responseType = params.responseType || 'code'
202219
const scope = params.scope
203220
const clientSecret = params.clientSecret
204-
return new OAuthHandler(http, appId, clientId, redirectUri, clientSecret, responseType, scope)
221+
return new OAuthHandler(
222+
http,
223+
appId,
224+
clientId,
225+
redirectUri,
226+
clientSecret,
227+
responseType,
228+
scope
229+
)
205230
}
206231

207232
return {

lib/core/contentstackError.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export default function error (errorResponse) {
3434
errorDetails.errorCode = data.error_code || 0
3535
errorDetails.errors = data.errors || {}
3636
errorDetails.error = data.error || ''
37+
errorDetails.tfa_type = data.tfa_type
3738
}
3839

3940
var error = new Error()

package-lock.json

Lines changed: 69 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@contentstack/management",
3-
"version": "1.23.2",
3+
"version": "1.24.0",
44
"description": "The Content Management API is used to manage the content of your Contentstack account",
55
"main": "./dist/node/contentstack-management.js",
66
"browser": "./dist/web/contentstack-management.js",
@@ -58,6 +58,7 @@
5858
"form-data": "^4.0.4",
5959
"husky": "^9.1.7",
6060
"lodash": "^4.17.21",
61+
"otplib": "^12.0.1",
6162
"qs": "^6.14.0",
6263
"stream-browserify": "^3.0.0"
6364
},

sanity-report-dev11.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const fs = require("fs");
44

55
dotenv.config();
66

7-
const user1 = process.env.USER1;
87
const user2 = process.env.USER2;
98
const user3 = process.env.USER3;
109
const user4 = process.env.USER4;
@@ -35,7 +34,7 @@ const goCdServer = process.env.GOCD_SERVER;
3534
const reportUrl = `http://${goCdServer}/go/files/${pipelineName}/${pipelineCounter}/sanity/1/sanity/test-results/mochawesome-report/sanity-report.html`;
3635

3736
let tagUsers =
38-
failedTests > 0 ? `<@${user1}> <@${user2}> <@${user3}> <@${user4}>` : "";
37+
failedTests > 0 ? `<@${user2}> <@${user3}> <@${user4}>` : "";
3938

4039
const slackMessage = {
4140
text: `Dev11, SDK-JS-CMA Sanity\n*Result:* ${resultMessage}. ${durationInMinutes}m ${durationInSeconds}s\n*Failed Tests:* ${failedTests}\n<${reportUrl}|View Report>\n${tagUsers}`,

0 commit comments

Comments
 (0)