@bragduck/cli 2.29.2 → 2.36.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 +1419 -676
- package/dist/bin/bragduck.js.map +1 -1
- package/dist/index.js +92 -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,7 +46,7 @@ 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: {
|
|
@@ -57,6 +57,13 @@ var init_constants = __esm({
|
|
|
57
57
|
TOKEN: "/v1/auth/atlassian/token",
|
|
58
58
|
REFRESH: "/v1/auth/atlassian/refresh"
|
|
59
59
|
},
|
|
60
|
+
GOOGLE: {
|
|
61
|
+
TOKEN: "/v1/auth/google/token",
|
|
62
|
+
REFRESH: "/v1/auth/google/refresh"
|
|
63
|
+
},
|
|
64
|
+
SLACK: {
|
|
65
|
+
TOKEN: "/v1/auth/slack/token"
|
|
66
|
+
},
|
|
60
67
|
BRAGS: {
|
|
61
68
|
CREATE: "/v1/brags",
|
|
62
69
|
LIST: "/v1/brags",
|
|
@@ -729,92 +736,95 @@ async function findAvailablePort() {
|
|
|
729
736
|
async function startOAuthCallbackServer(expectedState) {
|
|
730
737
|
const port = await findAvailablePort();
|
|
731
738
|
const timeout = OAUTH_CONFIG.TIMEOUT_MS;
|
|
732
|
-
|
|
739
|
+
const callbackUrl = `http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`;
|
|
740
|
+
return new Promise((resolveHandle, rejectHandle) => {
|
|
733
741
|
let server = null;
|
|
734
742
|
let timeoutId = null;
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
if (server) {
|
|
740
|
-
if (typeof server.closeAllConnections === "function") {
|
|
741
|
-
server.closeAllConnections();
|
|
743
|
+
const resultPromise = new Promise((resolveResult, rejectResult) => {
|
|
744
|
+
const cleanup = () => {
|
|
745
|
+
if (timeoutId) {
|
|
746
|
+
globalThis.clearTimeout(timeoutId);
|
|
742
747
|
}
|
|
743
|
-
server
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
logger.debug(`OAuth callback received: ${req.url}`);
|
|
752
|
-
if (parsedUrl.pathname === OAUTH_CONFIG.CALLBACK_PATH) {
|
|
753
|
-
const { code, state, error, error_description } = parsedUrl.query;
|
|
754
|
-
if (error) {
|
|
755
|
-
const errorMsg = error_description || error;
|
|
756
|
-
logger.debug(`OAuth error: ${errorMsg}`);
|
|
757
|
-
res.writeHead(400, { "Content-Type": "text/html" });
|
|
758
|
-
res.end(ERROR_HTML(String(errorMsg)));
|
|
759
|
-
cleanup();
|
|
760
|
-
reject(new OAuthError(`OAuth error: ${errorMsg}`));
|
|
761
|
-
return;
|
|
762
|
-
}
|
|
763
|
-
if (!code || !state) {
|
|
764
|
-
const errorMsg = "Missing code or state parameter";
|
|
765
|
-
logger.debug(errorMsg);
|
|
766
|
-
res.writeHead(400, { "Content-Type": "text/html" });
|
|
767
|
-
res.end(ERROR_HTML(errorMsg));
|
|
768
|
-
cleanup();
|
|
769
|
-
reject(new OAuthError(errorMsg));
|
|
770
|
-
return;
|
|
748
|
+
if (server) {
|
|
749
|
+
if (typeof server.closeAllConnections === "function") {
|
|
750
|
+
server.closeAllConnections();
|
|
751
|
+
}
|
|
752
|
+
server.close(() => {
|
|
753
|
+
logger.debug("OAuth server closed");
|
|
754
|
+
});
|
|
755
|
+
server.unref();
|
|
771
756
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
757
|
+
};
|
|
758
|
+
const handleRequest = (req, res) => {
|
|
759
|
+
const parsedUrl = parse(req.url || "", true);
|
|
760
|
+
logger.debug(`OAuth callback received: ${req.url}`);
|
|
761
|
+
if (parsedUrl.pathname === OAUTH_CONFIG.CALLBACK_PATH) {
|
|
762
|
+
const { code, state, error, error_description } = parsedUrl.query;
|
|
763
|
+
if (error) {
|
|
764
|
+
const errorMsg = error_description || error;
|
|
765
|
+
logger.debug(`OAuth error: ${errorMsg}`);
|
|
766
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
767
|
+
res.end(ERROR_HTML(String(errorMsg)));
|
|
768
|
+
cleanup();
|
|
769
|
+
rejectResult(new OAuthError(`OAuth error: ${errorMsg}`));
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
if (!code || !state) {
|
|
773
|
+
const errorMsg = "Missing code or state parameter";
|
|
774
|
+
logger.debug(errorMsg);
|
|
775
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
776
|
+
res.end(ERROR_HTML(errorMsg));
|
|
777
|
+
cleanup();
|
|
778
|
+
rejectResult(new OAuthError(errorMsg));
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
if (state !== expectedState) {
|
|
782
|
+
const errorMsg = "Invalid state parameter (possible CSRF attack)";
|
|
783
|
+
logger.debug(errorMsg);
|
|
784
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
785
|
+
res.end(ERROR_HTML(errorMsg));
|
|
786
|
+
cleanup();
|
|
787
|
+
rejectResult(new OAuthError(errorMsg));
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
791
|
+
res.end(SUCCESS_HTML);
|
|
792
|
+
globalThis.setTimeout(() => {
|
|
793
|
+
cleanup();
|
|
794
|
+
resolveResult({
|
|
795
|
+
code: String(code),
|
|
796
|
+
state: String(state),
|
|
797
|
+
port
|
|
798
|
+
});
|
|
799
|
+
}, 100);
|
|
779
800
|
return;
|
|
780
801
|
}
|
|
781
|
-
res.writeHead(
|
|
782
|
-
res.end(
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
`OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`
|
|
805
|
-
);
|
|
802
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
803
|
+
res.end("Not Found");
|
|
804
|
+
};
|
|
805
|
+
server = createServer(handleRequest);
|
|
806
|
+
server.on("error", (error) => {
|
|
807
|
+
logger.debug(`OAuth server error: ${error.message}`);
|
|
808
|
+
cleanup();
|
|
809
|
+
rejectResult(new OAuthError(`OAuth server error: ${error.message}`));
|
|
810
|
+
rejectHandle(new OAuthError(`OAuth server error: ${error.message}`));
|
|
811
|
+
});
|
|
812
|
+
server.listen(port, "127.0.0.1", () => {
|
|
813
|
+
logger.debug(
|
|
814
|
+
`OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`
|
|
815
|
+
);
|
|
816
|
+
resolveHandle({ callbackUrl, resultPromise });
|
|
817
|
+
});
|
|
818
|
+
timeoutId = globalThis.setTimeout(() => {
|
|
819
|
+
logger.debug("OAuth callback timeout");
|
|
820
|
+
cleanup();
|
|
821
|
+
rejectResult(
|
|
822
|
+
new OAuthError("Authentication timeout - no callback received within 2 minutes")
|
|
823
|
+
);
|
|
824
|
+
}, timeout);
|
|
806
825
|
});
|
|
807
|
-
timeoutId = globalThis.setTimeout(() => {
|
|
808
|
-
logger.debug("OAuth callback timeout");
|
|
809
|
-
cleanup();
|
|
810
|
-
reject(new OAuthError("Authentication timeout - no callback received within 2 minutes"));
|
|
811
|
-
}, timeout);
|
|
812
826
|
});
|
|
813
827
|
}
|
|
814
|
-
async function getCallbackUrl() {
|
|
815
|
-
const port = await findAvailablePort();
|
|
816
|
-
return `http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`;
|
|
817
|
-
}
|
|
818
828
|
var SUCCESS_HTML, ERROR_HTML;
|
|
819
829
|
var init_oauth_server = __esm({
|
|
820
830
|
"src/utils/oauth-server.ts"() {
|
|
@@ -1077,7 +1087,7 @@ var init_auth_service = __esm({
|
|
|
1077
1087
|
async login() {
|
|
1078
1088
|
logger.debug("Starting OAuth login flow");
|
|
1079
1089
|
const state = this.generateState();
|
|
1080
|
-
const callbackUrl = await
|
|
1090
|
+
const { callbackUrl, resultPromise } = await startOAuthCallbackServer(state);
|
|
1081
1091
|
storageService.setOAuthState({
|
|
1082
1092
|
state,
|
|
1083
1093
|
createdAt: Date.now()
|
|
@@ -1086,7 +1096,6 @@ var init_auth_service = __esm({
|
|
|
1086
1096
|
logger.debug(`Callback URL: ${callbackUrl}`);
|
|
1087
1097
|
const authUrl = await this.buildAuthUrl(state, callbackUrl);
|
|
1088
1098
|
logger.debug(`Authorization URL: ${authUrl}`);
|
|
1089
|
-
const serverPromise = startOAuthCallbackServer(state);
|
|
1090
1099
|
try {
|
|
1091
1100
|
await openBrowser(authUrl);
|
|
1092
1101
|
} catch {
|
|
@@ -1096,7 +1105,7 @@ var init_auth_service = __esm({
|
|
|
1096
1105
|
}
|
|
1097
1106
|
let callbackResult;
|
|
1098
1107
|
try {
|
|
1099
|
-
callbackResult = await
|
|
1108
|
+
callbackResult = await resultPromise;
|
|
1100
1109
|
} catch (error) {
|
|
1101
1110
|
storageService.deleteOAuthState();
|
|
1102
1111
|
throw error;
|