@contentstack/cli-utilities 1.7.3 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/auth-handler.js +2 -0
- package/lib/authentication-handler.d.ts +13 -0
- package/lib/authentication-handler.js +119 -0
- package/lib/helpers.js +12 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/package.json +2 -1
package/lib/auth-handler.js
CHANGED
|
@@ -4,6 +4,7 @@ const tslib_1 = require("tslib");
|
|
|
4
4
|
const cli_ux_1 = tslib_1.__importDefault(require("./cli-ux"));
|
|
5
5
|
const http_client_1 = tslib_1.__importDefault(require("./http-client"));
|
|
6
6
|
const config_handler_1 = tslib_1.__importDefault(require("./config-handler"));
|
|
7
|
+
const dotenv_1 = tslib_1.__importDefault(require("dotenv"));
|
|
7
8
|
const ContentstackManagementSDK = tslib_1.__importStar(require("@contentstack/management"));
|
|
8
9
|
const message_handler_1 = tslib_1.__importDefault(require("./message-handler"));
|
|
9
10
|
const http = require('http');
|
|
@@ -11,6 +12,7 @@ const url = require('url');
|
|
|
11
12
|
const open_1 = tslib_1.__importDefault(require("open"));
|
|
12
13
|
const logger_1 = require("./logger");
|
|
13
14
|
const crypto = require('crypto');
|
|
15
|
+
dotenv_1.default.config();
|
|
14
16
|
/**
|
|
15
17
|
* @class
|
|
16
18
|
* Auth handler
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare class AuthenticationHandler {
|
|
2
|
+
private authType;
|
|
3
|
+
private isOAuth;
|
|
4
|
+
private token;
|
|
5
|
+
constructor();
|
|
6
|
+
getAuthDetails(): Promise<void>;
|
|
7
|
+
get isOauthEnabled(): boolean;
|
|
8
|
+
get accessToken(): string;
|
|
9
|
+
refreshAccessToken(error: any, maxRetryCount?: number): Promise<void>;
|
|
10
|
+
refreshToken(hostName: string): Promise<boolean>;
|
|
11
|
+
}
|
|
12
|
+
declare const authenticationHandler: AuthenticationHandler;
|
|
13
|
+
export default authenticationHandler;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const index_1 = require("./index");
|
|
4
|
+
class AuthenticationHandler {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.token = null;
|
|
7
|
+
this.authType = index_1.configHandler.get('authorisationType');
|
|
8
|
+
this.isOAuth = this.authType === 'OAUTH';
|
|
9
|
+
}
|
|
10
|
+
async getAuthDetails() {
|
|
11
|
+
try {
|
|
12
|
+
switch (this.authType) {
|
|
13
|
+
case 'BASIC':
|
|
14
|
+
this.token = index_1.configHandler.get('authtoken');
|
|
15
|
+
break;
|
|
16
|
+
case 'OAUTH':
|
|
17
|
+
await index_1.authHandler.compareOAuthExpiry();
|
|
18
|
+
this.token = `Bearer ${index_1.configHandler.get('oauthAccessToken')}`;
|
|
19
|
+
break;
|
|
20
|
+
default:
|
|
21
|
+
const authToken = index_1.configHandler.get('authtoken');
|
|
22
|
+
if (authToken) {
|
|
23
|
+
this.token = authToken;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
index_1.cliux.print('Session timed out, please login to proceed', {
|
|
27
|
+
color: 'yellow',
|
|
28
|
+
});
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
index_1.cliux.print(`Error occurred while fetching auth details: ${error.message}`, {
|
|
36
|
+
color: 'red',
|
|
37
|
+
});
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
get isOauthEnabled() {
|
|
42
|
+
return this.isOAuth;
|
|
43
|
+
}
|
|
44
|
+
get accessToken() {
|
|
45
|
+
if (!this.token) {
|
|
46
|
+
throw new Error('Token is not available. Please authenticate first.');
|
|
47
|
+
}
|
|
48
|
+
return this.token;
|
|
49
|
+
}
|
|
50
|
+
async refreshAccessToken(error, maxRetryCount = 1) {
|
|
51
|
+
if (error.response && error.response.status) {
|
|
52
|
+
if (maxRetryCount >= 3) {
|
|
53
|
+
index_1.cliux.print('Max retry count reached, please login to proceed', {
|
|
54
|
+
color: 'yellow',
|
|
55
|
+
});
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
maxRetryCount++; // Increment for the next retry attempt
|
|
59
|
+
switch (error.response.status) {
|
|
60
|
+
case 401:
|
|
61
|
+
// NOTE: Refresh the token if the type is OAuth.
|
|
62
|
+
const region = index_1.configHandler.get('region') || {};
|
|
63
|
+
if (region === null || region === void 0 ? void 0 : region.cma) {
|
|
64
|
+
let hostName = '';
|
|
65
|
+
if (region.cma.startsWith('http')) {
|
|
66
|
+
const u = new URL(region.cma);
|
|
67
|
+
if (u.host)
|
|
68
|
+
hostName = u.host;
|
|
69
|
+
}
|
|
70
|
+
hostName = hostName || region.cma;
|
|
71
|
+
await this.refreshToken(hostName);
|
|
72
|
+
return this.refreshAccessToken(error, maxRetryCount); // Retry after refreshing the token
|
|
73
|
+
}
|
|
74
|
+
case 429:
|
|
75
|
+
case 408:
|
|
76
|
+
// These cases require a wait, adding a delay before retrying
|
|
77
|
+
await new Promise((resolve) => setTimeout(resolve, 1000)); // wait for 1 second
|
|
78
|
+
return this.refreshAccessToken(error, maxRetryCount); // Retry
|
|
79
|
+
default:
|
|
80
|
+
return; // Handle other cases if necessary
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
refreshToken(hostName) {
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
if (this.authType === 'BASIC') {
|
|
87
|
+
// NOTE Handle basic auth 401 here
|
|
88
|
+
resolve(false);
|
|
89
|
+
index_1.cliux.print('Session timed out, please login to proceed', {
|
|
90
|
+
color: 'yellow',
|
|
91
|
+
});
|
|
92
|
+
process.exit();
|
|
93
|
+
}
|
|
94
|
+
else if (this.authType === 'OAUTH') {
|
|
95
|
+
index_1.authHandler.host = hostName;
|
|
96
|
+
// NOTE Handle OAuth refresh token
|
|
97
|
+
index_1.authHandler
|
|
98
|
+
.compareOAuthExpiry(true)
|
|
99
|
+
.then(() => {
|
|
100
|
+
this.token = `Bearer ${index_1.configHandler.get('oauthAccessToken')}`;
|
|
101
|
+
resolve(true);
|
|
102
|
+
})
|
|
103
|
+
.catch((error) => {
|
|
104
|
+
console.log(error);
|
|
105
|
+
resolve(false);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
resolve(false);
|
|
110
|
+
index_1.cliux.print('You do not have the permissions to perform this action, please login to proceed', {
|
|
111
|
+
color: 'yellow',
|
|
112
|
+
});
|
|
113
|
+
process.exit();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const authenticationHandler = new AuthenticationHandler();
|
|
119
|
+
exports.default = authenticationHandler;
|
package/lib/helpers.js
CHANGED
|
@@ -90,6 +90,18 @@ const formatError = function (error) {
|
|
|
90
90
|
catch (e) {
|
|
91
91
|
parsedError = error;
|
|
92
92
|
}
|
|
93
|
+
// Check if parsedError is an empty object
|
|
94
|
+
if (parsedError && typeof parsedError === 'object' && Object.keys(parsedError).length === 0) {
|
|
95
|
+
return `An unknown error occurred. ${error}`;
|
|
96
|
+
}
|
|
97
|
+
// Check for specific SSL error
|
|
98
|
+
if ((parsedError === null || parsedError === void 0 ? void 0 : parsedError.code) === 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY') {
|
|
99
|
+
return 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY occurred during SSL certificate verification! Please check your certificate configuration.';
|
|
100
|
+
}
|
|
101
|
+
// Handle self signed certificate error
|
|
102
|
+
if ((parsedError === null || parsedError === void 0 ? void 0 : parsedError.code) === 'SELF_SIGNED_CERT_IN_CHAIN') {
|
|
103
|
+
return 'Self-signed certificate in the certificate chain! Please ensure your certificate configuration is correct and the necessary CA certificates are trusted.';
|
|
104
|
+
}
|
|
93
105
|
// Determine the error message
|
|
94
106
|
let message = parsedError.errorMessage || parsedError.error_message || parsedError.message || parsedError;
|
|
95
107
|
if (typeof message === 'object') {
|
package/lib/index.d.ts
CHANGED
|
@@ -22,3 +22,4 @@ export { Args, CommandHelp, Config, Errors, Flags, loadHelpClass, Help, HelpBase
|
|
|
22
22
|
export { FlagInput, ArgInput, FlagDefinition } from '@oclif/core/lib/interfaces/parser';
|
|
23
23
|
export { default as TablePrompt } from './inquirer-table-prompt';
|
|
24
24
|
export { Logger };
|
|
25
|
+
export { default as authenticationHandler } from './authentication-handler';
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Logger = exports.TablePrompt = exports.stdout = exports.stderr = exports.execute = exports.ux = exports.flush = exports.settings = exports.toConfiguredId = exports.toStandardizedId = exports.run = exports.Plugin = exports.Parser = exports.Interfaces = exports.HelpBase = exports.Help = exports.loadHelpClass = exports.Flags = exports.Errors = exports.Config = exports.CommandHelp = exports.Args = exports.marketplaceSDKInitiator = exports.MarketplaceSDKInitiator = exports.marketplaceSDKClient = exports.Command = exports.flags = exports.args = exports.NodeCrypto = exports.printFlagDeprecation = exports.managementSDKInitiator = exports.managementSDKClient = exports.configHandler = exports.authHandler = exports.messageHandler = exports.CLIError = exports.cliux = exports.LoggerService = void 0;
|
|
3
|
+
exports.authenticationHandler = exports.Logger = exports.TablePrompt = exports.stdout = exports.stderr = exports.execute = exports.ux = exports.flush = exports.settings = exports.toConfiguredId = exports.toStandardizedId = exports.run = exports.Plugin = exports.Parser = exports.Interfaces = exports.HelpBase = exports.Help = exports.loadHelpClass = exports.Flags = exports.Errors = exports.Config = exports.CommandHelp = exports.Args = exports.marketplaceSDKInitiator = exports.MarketplaceSDKInitiator = exports.marketplaceSDKClient = exports.Command = exports.flags = exports.args = exports.NodeCrypto = exports.printFlagDeprecation = exports.managementSDKInitiator = exports.managementSDKClient = exports.configHandler = exports.authHandler = exports.messageHandler = exports.CLIError = exports.cliux = exports.LoggerService = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const logger_1 = tslib_1.__importDefault(require("./logger"));
|
|
6
6
|
exports.Logger = logger_1.default;
|
|
@@ -62,3 +62,5 @@ Object.defineProperty(exports, "stderr", { enumerable: true, get: function () {
|
|
|
62
62
|
Object.defineProperty(exports, "stdout", { enumerable: true, get: function () { return core_1.stdout; } });
|
|
63
63
|
var inquirer_table_prompt_1 = require("./inquirer-table-prompt");
|
|
64
64
|
Object.defineProperty(exports, "TablePrompt", { enumerable: true, get: function () { return tslib_1.__importDefault(inquirer_table_prompt_1).default; } });
|
|
65
|
+
var authentication_handler_1 = require("./authentication-handler");
|
|
66
|
+
Object.defineProperty(exports, "authenticationHandler", { enumerable: true, get: function () { return tslib_1.__importDefault(authentication_handler_1).default; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-utilities",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Utilities for contentstack projects",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"cli-table": "^0.3.11",
|
|
42
42
|
"conf": "^10.2.0",
|
|
43
43
|
"debug": "^4.1.1",
|
|
44
|
+
"dotenv": "^16.4.5",
|
|
44
45
|
"figures": "^3.2.0",
|
|
45
46
|
"inquirer": "8.2.4",
|
|
46
47
|
"inquirer-search-checkbox": "^1.0.0",
|