@p0security/cli 0.27.1 → 0.27.4

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.
Files changed (55) hide show
  1. package/build/dist/commands/aws/rds.js +12 -8
  2. package/build/dist/commands/aws/rds.js.map +1 -1
  3. package/build/dist/commands/aws/util.js +6 -4
  4. package/build/dist/commands/aws/util.js.map +1 -1
  5. package/build/dist/commands/claude/mcp.js +24 -13
  6. package/build/dist/commands/claude/mcp.js.map +1 -1
  7. package/build/dist/commands/file-transfer.js +59 -7
  8. package/build/dist/commands/file-transfer.js.map +1 -1
  9. package/build/dist/commands/login.js +2 -3
  10. package/build/dist/commands/login.js.map +1 -1
  11. package/build/dist/commands/logout.js +4 -3
  12. package/build/dist/commands/logout.js.map +1 -1
  13. package/build/dist/drivers/auth/index.d.ts +1 -3
  14. package/build/dist/drivers/auth/index.js +2 -44
  15. package/build/dist/drivers/auth/index.js.map +1 -1
  16. package/build/dist/plugins/aws/assumeRole.js +7 -0
  17. package/build/dist/plugins/aws/assumeRole.js.map +1 -1
  18. package/build/dist/plugins/aws/ssh.js +2 -3
  19. package/build/dist/plugins/aws/ssh.js.map +1 -1
  20. package/build/dist/plugins/aws/types.d.ts +4 -1
  21. package/build/dist/plugins/file-transfer/index.d.ts +26 -10
  22. package/build/dist/plugins/file-transfer/index.js +54 -30
  23. package/build/dist/plugins/file-transfer/index.js.map +1 -1
  24. package/build/dist/plugins/file-transfer/types.d.ts +3 -5
  25. package/build/dist/plugins/google/connection-error.d.ts +39 -0
  26. package/build/dist/plugins/google/connection-error.js +43 -0
  27. package/build/dist/plugins/google/connection-error.js.map +1 -0
  28. package/build/dist/plugins/google/install.d.ts +15 -0
  29. package/build/dist/plugins/google/install.js +4 -4
  30. package/build/dist/plugins/google/install.js.map +1 -1
  31. package/build/dist/plugins/google/ssh.js +2 -0
  32. package/build/dist/plugins/google/ssh.js.map +1 -1
  33. package/build/dist/plugins/login.d.ts +1 -3
  34. package/build/dist/plugins/login.js +2 -2
  35. package/build/dist/plugins/login.js.map +1 -1
  36. package/build/dist/plugins/okta/login.d.ts +2 -10
  37. package/build/dist/plugins/okta/login.js +12 -38
  38. package/build/dist/plugins/okta/login.js.map +1 -1
  39. package/build/dist/plugins/ssh/index.js +36 -5
  40. package/build/dist/plugins/ssh/index.js.map +1 -1
  41. package/build/dist/testing/authn.d.ts +13 -0
  42. package/build/dist/testing/authn.js +37 -0
  43. package/build/dist/testing/authn.js.map +1 -0
  44. package/build/dist/types/ssh.d.ts +6 -0
  45. package/build/dist/util.d.ts +28 -0
  46. package/build/dist/util.js +31 -1
  47. package/build/dist/util.js.map +1 -1
  48. package/build/tsconfig.build.tsbuildinfo +1 -1
  49. package/package.json +1 -3
  50. package/build/dist/drivers/auth/lock.d.ts +0 -11
  51. package/build/dist/drivers/auth/lock.js +0 -70
  52. package/build/dist/drivers/auth/lock.js.map +0 -1
  53. package/build/dist/drivers/auth/refresh.d.ts +0 -31
  54. package/build/dist/drivers/auth/refresh.js +0 -130
  55. package/build/dist/drivers/auth/refresh.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@p0security/cli",
3
- "version": "0.27.1",
3
+ "version": "0.27.4",
4
4
  "description": "Execute infra CLI commands with P0 grants",
5
5
  "main": "index.ts",
6
6
  "repository": {
@@ -46,7 +46,6 @@
46
46
  "open": "^8.4.0",
47
47
  "pkce-challenge": "^5.0.0",
48
48
  "pluralize": "^8.0.0",
49
- "proper-lockfile": "^4.1.2",
50
49
  "semver": "^7.6.0",
51
50
  "tmp-promise": "^3.0.3",
52
51
  "typescript": "^4.8.4",
@@ -62,7 +61,6 @@
62
61
  "@types/lodash": "^4.14.202",
63
62
  "@types/node": "^20.17.46",
64
63
  "@types/pluralize": "^0.0.33",
65
- "@types/proper-lockfile": "^4.1.4",
66
64
  "@types/which": "^3.0.3",
67
65
  "@types/yargs": "^17.0.13",
68
66
  "@typescript-eslint/eslint-plugin": "^6.4.0",
@@ -1,11 +0,0 @@
1
- /**
2
- * Serialize critical sections that read-modify-write the identity file.
3
- *
4
- * Acquires an exclusive `proper-lockfile` on identity.json (creates an
5
- * adjacent `.lock` directory) and releases it after `fn` resolves or rejects.
6
- * The caller is expected to re-read the identity inside `fn` because a peer
7
- * may have updated it while we were waiting on the lock.
8
- *
9
- * Requires identity.json to exist — caller's responsibility.
10
- */
11
- export declare const withIdentityLock: <T>(fn: () => Promise<T>) => Promise<T>;
@@ -1,70 +0,0 @@
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
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.withIdentityLock = void 0;
16
- /** Copyright © 2024-present P0 Security
17
-
18
- This file is part of @p0security/cli
19
-
20
- @p0security/cli is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.
21
-
22
- @p0security/cli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
23
-
24
- You should have received a copy of the GNU General Public License along with @p0security/cli. If not, see <https://www.gnu.org/licenses/>.
25
- **/
26
- const path_1 = require("./path");
27
- const proper_lockfile_1 = __importDefault(require("proper-lockfile"));
28
- // If a lock holder dies without releasing, the lock file's mtime stops
29
- // updating; after STALE_LOCK_MS another process is allowed to steal it.
30
- const STALE_LOCK_MS = 30000;
31
- // Bound the *total* wait so a hung peer process can't make this CLI invocation
32
- // appear to hang. The retry backoff below sums to ~20s in the worst case, then
33
- // proper-lockfile gives up and we let the caller fall through to device flow.
34
- const LOCK_RETRY_OPTIONS = {
35
- retries: 8,
36
- factor: 1.5,
37
- minTimeout: 100,
38
- maxTimeout: 4000,
39
- };
40
- /**
41
- * Serialize critical sections that read-modify-write the identity file.
42
- *
43
- * Acquires an exclusive `proper-lockfile` on identity.json (creates an
44
- * adjacent `.lock` directory) and releases it after `fn` resolves or rejects.
45
- * The caller is expected to re-read the identity inside `fn` because a peer
46
- * may have updated it while we were waiting on the lock.
47
- *
48
- * Requires identity.json to exist — caller's responsibility.
49
- */
50
- const withIdentityLock = (fn) => __awaiter(void 0, void 0, void 0, function* () {
51
- const release = yield proper_lockfile_1.default.lock((0, path_1.getIdentityFilePath)(), {
52
- stale: STALE_LOCK_MS,
53
- retries: LOCK_RETRY_OPTIONS,
54
- });
55
- try {
56
- return yield fn();
57
- }
58
- finally {
59
- try {
60
- yield release();
61
- }
62
- catch (_a) {
63
- // release() may throw if the lock was stolen (we exceeded stale time)
64
- // or already released. The on-disk state is still consistent because
65
- // writeIdentity is atomic; nothing useful to do here.
66
- }
67
- }
68
- });
69
- exports.withIdentityLock = withIdentityLock;
70
- //# sourceMappingURL=lock.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../../../src/drivers/auth/lock.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA;;;;;;;;;GASG;AACH,iCAA6C;AAC7C,sEAAuC;AAEvC,uEAAuE;AACvE,wEAAwE;AACxE,MAAM,aAAa,GAAG,KAAM,CAAC;AAE7B,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,MAAM,kBAAkB,GAAG;IACzB,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,GAAG;IACX,UAAU,EAAE,GAAG;IACf,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF;;;;;;;;;GASG;AACI,MAAM,gBAAgB,GAAG,CAAU,EAAoB,EAAc,EAAE;IAC5E,MAAM,OAAO,GAAG,MAAM,yBAAQ,CAAC,IAAI,CAAC,IAAA,0BAAmB,GAAE,EAAE;QACzD,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,kBAAkB;KAC5B,CAAC,CAAC;IACH,IAAI;QACF,OAAO,MAAM,EAAE,EAAE,CAAC;KACnB;YAAS;QACR,IAAI;YACF,MAAM,OAAO,EAAE,CAAC;SACjB;QAAC,WAAM;YACN,sEAAsE;YACtE,qEAAqE;YACrE,sDAAsD;SACvD;KACF;AACH,CAAC,CAAA,CAAC;AAhBW,QAAA,gBAAgB,oBAgB3B"}
@@ -1,31 +0,0 @@
1
- import { Identity } from "../../types/identity";
2
- import { TokenResponse } from "../../types/oidc";
3
- export declare const REFRESH_FAILED: "REFRESH_FAILED";
4
- export type RefreshError = {
5
- code: typeof REFRESH_FAILED;
6
- reason: "http_error" | "missing_id_token" | "missing_provider_config" | "network_error" | "no_refresh_token";
7
- cause?: unknown;
8
- detail?: string;
9
- };
10
- /**
11
- * Merge a newly-issued credential from the refresh-token grant with the
12
- * previously-stored credential. Note, not all fields are included in the
13
- * refreshed token, and thus must be carried forward from the previous/original token.
14
- **/
15
- export declare const mergeRefreshedCredential: (previous: TokenResponse, refreshed: TokenResponse) => TokenResponse;
16
- /**
17
- * Exchange the stored refresh_token for a new access/id token pair against
18
- * Okta's /oauth2/v1/token endpoint.
19
- *
20
- * On any failure, throws a RefreshError. Callers are expected to
21
- * catch this and fall through to the device-flow path.
22
- */
23
- export declare const refreshOktaTokens: (identity: Identity, options?: {
24
- debug?: boolean;
25
- }) => Promise<TokenResponse>;
26
- /**
27
- * Best-effort revoke of the stored refresh_token at Okta's /oauth2/v1/revoke.
28
- */
29
- export declare const revokeOktaRefreshToken: (identity: Identity, options?: {
30
- debug?: boolean;
31
- }) => Promise<void>;
@@ -1,130 +0,0 @@
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.revokeOktaRefreshToken = exports.refreshOktaTokens = exports.mergeRefreshedCredential = exports.REFRESH_FAILED = void 0;
13
- /** Copyright © 2024-present P0 Security
14
-
15
- This file is part of @p0security/cli
16
-
17
- @p0security/cli is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License.
18
-
19
- @p0security/cli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
-
21
- You should have received a copy of the GNU General Public License along with @p0security/cli. If not, see <https://www.gnu.org/licenses/>.
22
- **/
23
- const oidc_1 = require("../../common/auth/oidc");
24
- const fetch_1 = require("../../common/fetch");
25
- const authUtils_1 = require("../../types/authUtils");
26
- const stdio_1 = require("../stdio");
27
- exports.REFRESH_FAILED = "REFRESH_FAILED";
28
- const refreshError = (reason, extra) => (Object.assign({ code: exports.REFRESH_FAILED, reason }, extra));
29
- /**
30
- * Merge a newly-issued credential from the refresh-token grant with the
31
- * previously-stored credential. Note, not all fields are included in the
32
- * refreshed token, and thus must be carried forward from the previous/original token.
33
- **/
34
- const mergeRefreshedCredential = (previous, refreshed) => {
35
- var _a, _b, _c;
36
- return (Object.assign(Object.assign(Object.assign({}, previous), refreshed), { refresh_token: (_a = refreshed.refresh_token) !== null && _a !== void 0 ? _a : previous.refresh_token, device_secret: previous.device_secret,
37
- // RFC 6749 §6: omitted scope on refresh means "identical to original grant"
38
- scope: (_b = refreshed.scope) !== null && _b !== void 0 ? _b : previous.scope, token_type: (_c = refreshed.token_type) !== null && _c !== void 0 ? _c : previous.token_type }));
39
- };
40
- exports.mergeRefreshedCredential = mergeRefreshedCredential;
41
- /**
42
- * Exchange the stored refresh_token for a new access/id token pair against
43
- * Okta's /oauth2/v1/token endpoint.
44
- *
45
- * On any failure, throws a RefreshError. Callers are expected to
46
- * catch this and fall through to the device-flow path.
47
- */
48
- const refreshOktaTokens = (identity, options) => __awaiter(void 0, void 0, void 0, function* () {
49
- const refresh_token = identity.credential.refresh_token;
50
- if (!refresh_token)
51
- throw refreshError("no_refresh_token");
52
- const providerDomain = (0, authUtils_1.getProviderDomain)(identity.org);
53
- const clientId = (0, authUtils_1.getClientId)(identity.org);
54
- if (!providerDomain || !clientId) {
55
- throw refreshError("missing_provider_config");
56
- }
57
- const url = `https://${providerDomain}/oauth2/v1/token`;
58
- const init = {
59
- method: "POST",
60
- headers: oidc_1.OIDC_HEADERS,
61
- body: (0, fetch_1.urlEncode)({
62
- grant_type: "refresh_token",
63
- client_id: clientId,
64
- refresh_token,
65
- }),
66
- };
67
- let response;
68
- try {
69
- response = yield fetch(url, init);
70
- }
71
- catch (e) {
72
- throw refreshError("network_error", { cause: e });
73
- }
74
- if (!response.ok) {
75
- if (options === null || options === void 0 ? void 0 : options.debug) {
76
- const detail = yield response.text().catch(() => undefined);
77
- (0, stdio_1.print2)(`Okta refresh-token grant failed: ${response.status} ${response.statusText} ${detail !== null && detail !== void 0 ? detail : ""}`);
78
- }
79
- throw refreshError("http_error", {
80
- detail: `${response.status} ${response.statusText}`,
81
- });
82
- }
83
- const refreshed = (yield response.json());
84
- if (!refreshed.id_token) {
85
- if (options === null || options === void 0 ? void 0 : options.debug) {
86
- (0, stdio_1.print2)("Okta refresh response omitted id_token; falling back to device flow.");
87
- }
88
- throw refreshError("missing_id_token");
89
- }
90
- return (0, exports.mergeRefreshedCredential)(identity.credential, refreshed);
91
- });
92
- exports.refreshOktaTokens = refreshOktaTokens;
93
- /**
94
- * Best-effort revoke of the stored refresh_token at Okta's /oauth2/v1/revoke.
95
- */
96
- const revokeOktaRefreshToken = (identity, options) => __awaiter(void 0, void 0, void 0, function* () {
97
- const refresh_token = identity.credential.refresh_token;
98
- if (!refresh_token)
99
- return;
100
- const providerDomain = (0, authUtils_1.getProviderDomain)(identity.org);
101
- const clientId = (0, authUtils_1.getClientId)(identity.org);
102
- if (!providerDomain || !clientId) {
103
- if (options === null || options === void 0 ? void 0 : options.debug) {
104
- (0, stdio_1.print2)("Skipping refresh-token revoke: missing provider domain or client id.");
105
- }
106
- return;
107
- }
108
- try {
109
- const response = yield fetch(`https://${providerDomain}/oauth2/v1/revoke`, {
110
- method: "POST",
111
- headers: oidc_1.OIDC_HEADERS,
112
- body: (0, fetch_1.urlEncode)({
113
- client_id: clientId,
114
- token: refresh_token,
115
- token_type_hint: "refresh_token",
116
- }),
117
- });
118
- if (!response.ok && (options === null || options === void 0 ? void 0 : options.debug)) {
119
- (0, stdio_1.print2)(`Refresh-token revoke returned ${response.status} ${response.statusText}; proceeding with logout.`);
120
- }
121
- }
122
- catch (e) {
123
- if (options === null || options === void 0 ? void 0 : options.debug) {
124
- const detail = e instanceof Error ? e.message : String(e);
125
- (0, stdio_1.print2)(`Refresh-token revoke failed (${detail}); proceeding with logout.`);
126
- }
127
- }
128
- });
129
- exports.revokeOktaRefreshToken = revokeOktaRefreshToken;
130
- //# sourceMappingURL=refresh.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../../../src/drivers/auth/refresh.ts"],"names":[],"mappings":"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"}