@bragduck/cli 2.28.1 → 2.30.2
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/README.md +138 -300
- package/dist/bin/bragduck.js +611 -705
- package/dist/bin/bragduck.js.map +1 -1
- package/dist/index.js +89 -83
- package/dist/index.js.map +1 -1
- package/package.json +3 -12
package/dist/index.js
CHANGED
|
@@ -9,11 +9,11 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
// node_modules/tsup/assets/esm_shims.js
|
|
12
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/esm_shims.js
|
|
13
13
|
import path from "path";
|
|
14
14
|
import { fileURLToPath } from "url";
|
|
15
15
|
var init_esm_shims = __esm({
|
|
16
|
-
"node_modules/tsup/assets/esm_shims.js"() {
|
|
16
|
+
"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/esm_shims.js"() {
|
|
17
17
|
"use strict";
|
|
18
18
|
}
|
|
19
19
|
});
|
|
@@ -46,13 +46,17 @@ var init_constants = __esm({
|
|
|
46
46
|
TIMEOUT_MS: 12e4,
|
|
47
47
|
// 2 minutes
|
|
48
48
|
MIN_PORT: 8e3,
|
|
49
|
-
MAX_PORT:
|
|
49
|
+
MAX_PORT: 8004
|
|
50
50
|
};
|
|
51
51
|
API_ENDPOINTS = {
|
|
52
52
|
AUTH: {
|
|
53
53
|
INITIATE: "/v1/auth/cli/initiate",
|
|
54
54
|
TOKEN: "/v1/auth/cli/token"
|
|
55
55
|
},
|
|
56
|
+
ATLASSIAN: {
|
|
57
|
+
TOKEN: "/v1/auth/atlassian/token",
|
|
58
|
+
REFRESH: "/v1/auth/atlassian/refresh"
|
|
59
|
+
},
|
|
56
60
|
BRAGS: {
|
|
57
61
|
CREATE: "/v1/brags",
|
|
58
62
|
LIST: "/v1/brags",
|
|
@@ -725,92 +729,95 @@ async function findAvailablePort() {
|
|
|
725
729
|
async function startOAuthCallbackServer(expectedState) {
|
|
726
730
|
const port = await findAvailablePort();
|
|
727
731
|
const timeout = OAUTH_CONFIG.TIMEOUT_MS;
|
|
728
|
-
|
|
732
|
+
const callbackUrl = `http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`;
|
|
733
|
+
return new Promise((resolveHandle, rejectHandle) => {
|
|
729
734
|
let server = null;
|
|
730
735
|
let timeoutId = null;
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
if (server) {
|
|
736
|
-
if (typeof server.closeAllConnections === "function") {
|
|
737
|
-
server.closeAllConnections();
|
|
738
|
-
}
|
|
739
|
-
server.close(() => {
|
|
740
|
-
logger.debug("OAuth server closed");
|
|
741
|
-
});
|
|
742
|
-
server.unref();
|
|
743
|
-
}
|
|
744
|
-
};
|
|
745
|
-
const handleRequest = (req, res) => {
|
|
746
|
-
const parsedUrl = parse(req.url || "", true);
|
|
747
|
-
logger.debug(`OAuth callback received: ${req.url}`);
|
|
748
|
-
if (parsedUrl.pathname === OAUTH_CONFIG.CALLBACK_PATH) {
|
|
749
|
-
const { code, state, error, error_description } = parsedUrl.query;
|
|
750
|
-
if (error) {
|
|
751
|
-
const errorMsg = error_description || error;
|
|
752
|
-
logger.debug(`OAuth error: ${errorMsg}`);
|
|
753
|
-
res.writeHead(400, { "Content-Type": "text/html" });
|
|
754
|
-
res.end(ERROR_HTML(String(errorMsg)));
|
|
755
|
-
cleanup();
|
|
756
|
-
reject(new OAuthError(`OAuth error: ${errorMsg}`));
|
|
757
|
-
return;
|
|
736
|
+
const resultPromise = new Promise((resolveResult, rejectResult) => {
|
|
737
|
+
const cleanup = () => {
|
|
738
|
+
if (timeoutId) {
|
|
739
|
+
globalThis.clearTimeout(timeoutId);
|
|
758
740
|
}
|
|
759
|
-
if (
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
741
|
+
if (server) {
|
|
742
|
+
if (typeof server.closeAllConnections === "function") {
|
|
743
|
+
server.closeAllConnections();
|
|
744
|
+
}
|
|
745
|
+
server.close(() => {
|
|
746
|
+
logger.debug("OAuth server closed");
|
|
747
|
+
});
|
|
748
|
+
server.unref();
|
|
767
749
|
}
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
750
|
+
};
|
|
751
|
+
const handleRequest = (req, res) => {
|
|
752
|
+
const parsedUrl = parse(req.url || "", true);
|
|
753
|
+
logger.debug(`OAuth callback received: ${req.url}`);
|
|
754
|
+
if (parsedUrl.pathname === OAUTH_CONFIG.CALLBACK_PATH) {
|
|
755
|
+
const { code, state, error, error_description } = parsedUrl.query;
|
|
756
|
+
if (error) {
|
|
757
|
+
const errorMsg = error_description || error;
|
|
758
|
+
logger.debug(`OAuth error: ${errorMsg}`);
|
|
759
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
760
|
+
res.end(ERROR_HTML(String(errorMsg)));
|
|
761
|
+
cleanup();
|
|
762
|
+
rejectResult(new OAuthError(`OAuth error: ${errorMsg}`));
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
if (!code || !state) {
|
|
766
|
+
const errorMsg = "Missing code or state parameter";
|
|
767
|
+
logger.debug(errorMsg);
|
|
768
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
769
|
+
res.end(ERROR_HTML(errorMsg));
|
|
770
|
+
cleanup();
|
|
771
|
+
rejectResult(new OAuthError(errorMsg));
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
if (state !== expectedState) {
|
|
775
|
+
const errorMsg = "Invalid state parameter (possible CSRF attack)";
|
|
776
|
+
logger.debug(errorMsg);
|
|
777
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
778
|
+
res.end(ERROR_HTML(errorMsg));
|
|
779
|
+
cleanup();
|
|
780
|
+
rejectResult(new OAuthError(errorMsg));
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
784
|
+
res.end(SUCCESS_HTML);
|
|
785
|
+
globalThis.setTimeout(() => {
|
|
786
|
+
cleanup();
|
|
787
|
+
resolveResult({
|
|
788
|
+
code: String(code),
|
|
789
|
+
state: String(state),
|
|
790
|
+
port
|
|
791
|
+
});
|
|
792
|
+
}, 100);
|
|
775
793
|
return;
|
|
776
794
|
}
|
|
777
|
-
res.writeHead(
|
|
778
|
-
res.end(
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
`OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`
|
|
801
|
-
);
|
|
795
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
796
|
+
res.end("Not Found");
|
|
797
|
+
};
|
|
798
|
+
server = createServer(handleRequest);
|
|
799
|
+
server.on("error", (error) => {
|
|
800
|
+
logger.debug(`OAuth server error: ${error.message}`);
|
|
801
|
+
cleanup();
|
|
802
|
+
rejectResult(new OAuthError(`OAuth server error: ${error.message}`));
|
|
803
|
+
rejectHandle(new OAuthError(`OAuth server error: ${error.message}`));
|
|
804
|
+
});
|
|
805
|
+
server.listen(port, "127.0.0.1", () => {
|
|
806
|
+
logger.debug(
|
|
807
|
+
`OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`
|
|
808
|
+
);
|
|
809
|
+
resolveHandle({ callbackUrl, resultPromise });
|
|
810
|
+
});
|
|
811
|
+
timeoutId = globalThis.setTimeout(() => {
|
|
812
|
+
logger.debug("OAuth callback timeout");
|
|
813
|
+
cleanup();
|
|
814
|
+
rejectResult(
|
|
815
|
+
new OAuthError("Authentication timeout - no callback received within 2 minutes")
|
|
816
|
+
);
|
|
817
|
+
}, timeout);
|
|
802
818
|
});
|
|
803
|
-
timeoutId = globalThis.setTimeout(() => {
|
|
804
|
-
logger.debug("OAuth callback timeout");
|
|
805
|
-
cleanup();
|
|
806
|
-
reject(new OAuthError("Authentication timeout - no callback received within 2 minutes"));
|
|
807
|
-
}, timeout);
|
|
808
819
|
});
|
|
809
820
|
}
|
|
810
|
-
async function getCallbackUrl() {
|
|
811
|
-
const port = await findAvailablePort();
|
|
812
|
-
return `http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`;
|
|
813
|
-
}
|
|
814
821
|
var SUCCESS_HTML, ERROR_HTML;
|
|
815
822
|
var init_oauth_server = __esm({
|
|
816
823
|
"src/utils/oauth-server.ts"() {
|
|
@@ -1073,7 +1080,7 @@ var init_auth_service = __esm({
|
|
|
1073
1080
|
async login() {
|
|
1074
1081
|
logger.debug("Starting OAuth login flow");
|
|
1075
1082
|
const state = this.generateState();
|
|
1076
|
-
const callbackUrl = await
|
|
1083
|
+
const { callbackUrl, resultPromise } = await startOAuthCallbackServer(state);
|
|
1077
1084
|
storageService.setOAuthState({
|
|
1078
1085
|
state,
|
|
1079
1086
|
createdAt: Date.now()
|
|
@@ -1082,7 +1089,6 @@ var init_auth_service = __esm({
|
|
|
1082
1089
|
logger.debug(`Callback URL: ${callbackUrl}`);
|
|
1083
1090
|
const authUrl = await this.buildAuthUrl(state, callbackUrl);
|
|
1084
1091
|
logger.debug(`Authorization URL: ${authUrl}`);
|
|
1085
|
-
const serverPromise = startOAuthCallbackServer(state);
|
|
1086
1092
|
try {
|
|
1087
1093
|
await openBrowser(authUrl);
|
|
1088
1094
|
} catch {
|
|
@@ -1092,7 +1098,7 @@ var init_auth_service = __esm({
|
|
|
1092
1098
|
}
|
|
1093
1099
|
let callbackResult;
|
|
1094
1100
|
try {
|
|
1095
|
-
callbackResult = await
|
|
1101
|
+
callbackResult = await resultPromise;
|
|
1096
1102
|
} catch (error) {
|
|
1097
1103
|
storageService.deleteOAuthState();
|
|
1098
1104
|
throw error;
|