neonctl 0.5.3 → 0.6.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/package.json +2 -3
- package/src/api/operations.js +30 -0
- package/src/api/roles.js +20 -0
- package/src/auth.js +8 -7
- package/src/commands/roles.js +18 -0
- package/src/index.js +24 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neonctl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "CLI tool for NeonDB Cloud management",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "NeonDB",
|
|
@@ -39,8 +39,7 @@
|
|
|
39
39
|
"build": "npm run clean && tsc && cp src/*.html dist/src/",
|
|
40
40
|
"clean": "rm -rf dist",
|
|
41
41
|
"start": "node index.js",
|
|
42
|
-
"publizh": "npm run build && npm publish ./dist
|
|
43
|
-
"postinstall": "husky install"
|
|
42
|
+
"publizh": "npm run build && npm publish --ignore-scripts ./dist"
|
|
44
43
|
},
|
|
45
44
|
"lint-staged": {
|
|
46
45
|
"*.ts": [
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getOperation = exports.waitOperationFinalState = void 0;
|
|
13
|
+
const gateway_1 = require("./gateway");
|
|
14
|
+
function sleep(ms) {
|
|
15
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
16
|
+
}
|
|
17
|
+
// wait 20 sec max.
|
|
18
|
+
const waitOperationFinalState = (props) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
for (let i = 0; i < 100; i++) {
|
|
20
|
+
const operation = yield (0, exports.getOperation)(Object.assign({}, props));
|
|
21
|
+
if (operation.status == 'finished') {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
yield sleep(200);
|
|
25
|
+
}
|
|
26
|
+
throw Error(`timeout while waiting for operation ${props.operation_id}`);
|
|
27
|
+
});
|
|
28
|
+
exports.waitOperationFinalState = waitOperationFinalState;
|
|
29
|
+
const getOperation = (props) => (0, gateway_1.apiCall)(Object.assign(Object.assign({}, props), { path: `projects/${props.project_id}/operations/${props.operation_id}`, method: 'GET' }));
|
|
30
|
+
exports.getOperation = getOperation;
|
package/src/api/roles.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.resetPassword = void 0;
|
|
13
|
+
const gateway_1 = require("./gateway");
|
|
14
|
+
const operations_1 = require("./operations");
|
|
15
|
+
const resetPassword = (props) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
const response = yield (0, gateway_1.apiCall)(Object.assign(Object.assign({}, props), { path: `projects/${props.project_id}/roles/${props.role_name}/reset_password`, method: 'POST' }));
|
|
17
|
+
yield (0, operations_1.waitOperationFinalState)(Object.assign(Object.assign({}, props), response));
|
|
18
|
+
return response;
|
|
19
|
+
});
|
|
20
|
+
exports.resetPassword = resetPassword;
|
package/src/auth.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.auth = exports.refreshToken = void 0;
|
|
15
|
+
exports.auth = exports.refreshToken = exports.defaultClientID = void 0;
|
|
16
16
|
const openid_client_1 = require("openid-client");
|
|
17
17
|
const node_http_1 = require("node:http");
|
|
18
18
|
const node_fs_1 = require("node:fs");
|
|
@@ -24,15 +24,15 @@ const SERVER_TIMEOUT = 10000;
|
|
|
24
24
|
// where to wait for incoming redirect request from oauth server to arrive
|
|
25
25
|
const REDIRECT_URI = (port) => `http://127.0.0.1:${port}/callback`;
|
|
26
26
|
// These scopes cannot be cancelled, they are always needed.
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
'offline_access',
|
|
27
|
+
const ALWAYS_PRESENT_SCOPES = ['openid', 'offline', 'offline_access'];
|
|
28
|
+
const NEONCTL_SCOPES = [
|
|
29
|
+
...ALWAYS_PRESENT_SCOPES,
|
|
31
30
|
'urn:neoncloud:projects:create',
|
|
32
31
|
'urn:neoncloud:projects:read',
|
|
33
|
-
'urn:neoncloud:projects:
|
|
32
|
+
'urn:neoncloud:projects:update',
|
|
34
33
|
'urn:neoncloud:projects:delete',
|
|
35
34
|
];
|
|
35
|
+
exports.defaultClientID = 'neonctl';
|
|
36
36
|
openid_client_1.custom.setHttpOptionsDefaults({
|
|
37
37
|
timeout: SERVER_TIMEOUT,
|
|
38
38
|
});
|
|
@@ -94,8 +94,9 @@ const auth = ({ oauthHost, clientId }) => __awaiter(void 0, void 0, void 0, func
|
|
|
94
94
|
//
|
|
95
95
|
// Open browser to let user authenticate
|
|
96
96
|
//
|
|
97
|
+
const scopes = clientId == exports.defaultClientID ? NEONCTL_SCOPES : ALWAYS_PRESENT_SCOPES;
|
|
97
98
|
const authUrl = neonOAuthClient.authorizationUrl({
|
|
98
|
-
scope:
|
|
99
|
+
scope: scopes.join(' '),
|
|
99
100
|
state,
|
|
100
101
|
code_challenge: codeChallenge,
|
|
101
102
|
code_challenge_method: 'S256',
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.resetPwd = void 0;
|
|
13
|
+
const writer_1 = require("../writer");
|
|
14
|
+
const roles_1 = require("../api/roles");
|
|
15
|
+
const resetPwd = (props) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
(0, writer_1.writeOut)(props)(yield (0, roles_1.resetPassword)(props), { fields: [] });
|
|
17
|
+
});
|
|
18
|
+
exports.resetPwd = resetPwd;
|
package/src/index.js
CHANGED
|
@@ -41,6 +41,7 @@ const gateway_1 = require("./api/gateway");
|
|
|
41
41
|
const auth_1 = require("./commands/auth");
|
|
42
42
|
const config_1 = require("./config");
|
|
43
43
|
const log_1 = require("./log");
|
|
44
|
+
const auth_2 = require("./auth");
|
|
44
45
|
const showHelpMiddleware = (argv) => {
|
|
45
46
|
if (argv._.length === 1) {
|
|
46
47
|
yargs.showHelp();
|
|
@@ -74,7 +75,7 @@ const builder = yargs
|
|
|
74
75
|
.option('client-id', {
|
|
75
76
|
description: 'OAuth client id',
|
|
76
77
|
type: 'string',
|
|
77
|
-
default:
|
|
78
|
+
default: auth_2.defaultClientID,
|
|
78
79
|
})
|
|
79
80
|
.command('auth', 'Authenticate user', (yargs) => yargs, (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
80
81
|
(yield Promise.resolve().then(() => __importStar(require('./commands/auth')))).authFlow(args);
|
|
@@ -87,18 +88,32 @@ const builder = yargs
|
|
|
87
88
|
})
|
|
88
89
|
.command('me', 'Get user info', (yargs) => yargs.middleware(auth_1.ensureAuth), (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
89
90
|
yield (yield Promise.resolve().then(() => __importStar(require('./commands/users')))).me(args);
|
|
91
|
+
}))
|
|
92
|
+
.command('roles', 'Manage roles', (yargs) => __awaiter(void 0, void 0, void 0, function* () {
|
|
93
|
+
yargs
|
|
94
|
+
.usage('usage: $0 roles <cmd> [args]')
|
|
95
|
+
.command('resetpassword', 'Reset password for a role', (yargs) => yargs
|
|
96
|
+
.option('project-id', {
|
|
97
|
+
describe: 'Project ID',
|
|
98
|
+
type: 'string',
|
|
99
|
+
demandOption: true,
|
|
100
|
+
})
|
|
101
|
+
.option('role-name', {
|
|
102
|
+
describe: 'Role name',
|
|
103
|
+
type: 'string',
|
|
104
|
+
demandOption: true,
|
|
105
|
+
}), (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
106
|
+
yield (yield Promise.resolve().then(() => __importStar(require('./commands/roles')))).resetPwd(Object.assign(Object.assign({}, args), { role_name: args['role-name'], project_id: args['project-id'] }));
|
|
107
|
+
}))
|
|
108
|
+
.middleware(showHelpMiddleware)
|
|
109
|
+
.middleware(auth_1.ensureAuth);
|
|
90
110
|
}))
|
|
91
111
|
.command('projects', 'Manage projects', (yargs) => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
112
|
yargs
|
|
93
113
|
.usage('usage: $0 projects <cmd> [args]')
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// (yargs) => yargs,
|
|
98
|
-
// async (args) => {
|
|
99
|
-
// await (await import('./commands/projects')).list(args);
|
|
100
|
-
// }
|
|
101
|
-
// )
|
|
114
|
+
.command('list', 'List projects', (yargs) => yargs, (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
115
|
+
yield (yield Promise.resolve().then(() => __importStar(require('./commands/projects')))).list(args);
|
|
116
|
+
}))
|
|
102
117
|
.command('create', 'Create a project', (yargs) => yargs.option('name', {
|
|
103
118
|
describe: 'Project name',
|
|
104
119
|
type: 'string',
|