@alwaysmeticulous/client 2.253.0 → 2.254.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.
@@ -0,0 +1,12 @@
1
+ import { MeticulousClient } from "../types/client.types";
2
+ export interface WhoamiResponse {
3
+ email: string;
4
+ firstName: string;
5
+ lastName: string;
6
+ isAdmin?: boolean;
7
+ organizations: {
8
+ name: string;
9
+ id: string;
10
+ }[];
11
+ }
12
+ export declare const getWhoami: (client: MeticulousClient) => Promise<WhoamiResponse>;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getWhoami = void 0;
4
+ const getWhoami = async (client) => {
5
+ const { data } = await client.get("oauth/whoami");
6
+ return data;
7
+ };
8
+ exports.getWhoami = getWhoami;
9
+ //# sourceMappingURL=oauth.api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.api.js","sourceRoot":"","sources":["../../src/api/oauth.api.ts"],"names":[],"mappings":";;;AAUO,MAAM,SAAS,GAAG,KAAK,EAC5B,MAAwB,EACC,EAAE;IAC3B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAiB,cAAc,CAAC,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AALW,QAAA,SAAS,aAKpB"}
@@ -1 +1,21 @@
1
+ /**
2
+ * Resolves the API token to use for authentication with the Meticulous API.
3
+ *
4
+ * The resolution order is as follows:
5
+ * 1. Explicit apiToken parameter (e.g. from CLI flag)
6
+ * 2. METICULOUS_API_TOKEN environment variable
7
+ * 3. Legacy ~/.meticulous/config.json file
8
+ *
9
+ * This function does NOT check for OAuth tokens. Use getAuthToken for that functionality.
10
+ */
1
11
  export declare const getApiToken: (apiToken: string | null | undefined) => string | null;
12
+ /**
13
+ * Async version of getApiToken that also checks for OAuth tokens.
14
+ *
15
+ * Resolution order:
16
+ * 1. Explicit apiToken parameter (CLI flag)
17
+ * 2. METICULOUS_API_TOKEN env var
18
+ * 3. OAuth access token (with auto-refresh)
19
+ * 4. Legacy ~/.meticulous/config.json
20
+ */
21
+ export declare const getAuthToken: (apiToken: string | null | undefined) => Promise<string | null>;
@@ -1,28 +1,65 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getApiToken = void 0;
3
+ exports.getAuthToken = exports.getApiToken = void 0;
4
4
  const fs_1 = require("fs");
5
5
  const os_1 = require("os");
6
6
  const path_1 = require("path");
7
7
  const common_1 = require("@alwaysmeticulous/common");
8
+ const oauth_refresh_1 = require("./oauth/oauth-refresh");
8
9
  const PERSONAL_CONFIG_FILE_PATH = ".meticulous/config.json";
9
- const getApiToken = (apiToken) => {
10
- const logger = (0, common_1.initLogger)();
11
- if (apiToken) {
12
- return apiToken;
13
- }
14
- if (process.env["METICULOUS_API_TOKEN"]) {
15
- return process.env["METICULOUS_API_TOKEN"];
16
- }
10
+ const getFileBasedToken = () => {
17
11
  const personalConfigFileAbsolutePath = (0, path_1.join)((0, os_1.homedir)(), PERSONAL_CONFIG_FILE_PATH);
18
12
  if ((0, fs_1.existsSync)(personalConfigFileAbsolutePath)) {
19
13
  const config = JSON.parse((0, fs_1.readFileSync)(personalConfigFileAbsolutePath).toString("utf-8"));
20
14
  if (config.apiToken) {
15
+ const logger = (0, common_1.initLogger)();
21
16
  logger.info(`Using apiToken from ${personalConfigFileAbsolutePath}`);
22
17
  return config.apiToken;
23
18
  }
24
19
  }
25
20
  return null;
26
21
  };
22
+ /**
23
+ * Resolves the API token to use for authentication with the Meticulous API.
24
+ *
25
+ * The resolution order is as follows:
26
+ * 1. Explicit apiToken parameter (e.g. from CLI flag)
27
+ * 2. METICULOUS_API_TOKEN environment variable
28
+ * 3. Legacy ~/.meticulous/config.json file
29
+ *
30
+ * This function does NOT check for OAuth tokens. Use getAuthToken for that functionality.
31
+ */
32
+ const getApiToken = (apiToken) => {
33
+ if (apiToken) {
34
+ return apiToken;
35
+ }
36
+ if (process.env["METICULOUS_API_TOKEN"]) {
37
+ return process.env["METICULOUS_API_TOKEN"];
38
+ }
39
+ return getFileBasedToken();
40
+ };
27
41
  exports.getApiToken = getApiToken;
42
+ /**
43
+ * Async version of getApiToken that also checks for OAuth tokens.
44
+ *
45
+ * Resolution order:
46
+ * 1. Explicit apiToken parameter (CLI flag)
47
+ * 2. METICULOUS_API_TOKEN env var
48
+ * 3. OAuth access token (with auto-refresh)
49
+ * 4. Legacy ~/.meticulous/config.json
50
+ */
51
+ const getAuthToken = async (apiToken) => {
52
+ if (apiToken) {
53
+ return apiToken;
54
+ }
55
+ if (process.env["METICULOUS_API_TOKEN"]) {
56
+ return process.env["METICULOUS_API_TOKEN"];
57
+ }
58
+ const oauthToken = await (0, oauth_refresh_1.getValidAccessToken)();
59
+ if (oauthToken) {
60
+ return oauthToken;
61
+ }
62
+ return getFileBasedToken();
63
+ };
64
+ exports.getAuthToken = getAuthToken;
28
65
  //# sourceMappingURL=api-token.utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-token.utils.js","sourceRoot":"","sources":["../src/api-token.utils.ts"],"names":[],"mappings":";;;AAAA,2BAA8C;AAC9C,2BAA6B;AAC7B,+BAA4B;AAC5B,qDAAsD;AAEtD,MAAM,yBAAyB,GAAG,yBAAyB,CAAC;AAMrD,MAAM,WAAW,GAAG,CACzB,QAAmC,EACpB,EAAE;IACjB,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAE5B,IAAI,QAAQ,EAAE;QACZ,OAAO,QAAQ,CAAC;KACjB;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,EAAE;QACvC,OAAO,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;KAC5C;IAED,MAAM,8BAA8B,GAAG,IAAA,WAAI,EACzC,IAAA,YAAO,GAAE,EACT,yBAAyB,CAC1B,CAAC;IACF,IAAI,IAAA,eAAU,EAAC,8BAA8B,CAAC,EAAE;QAC9C,MAAM,MAAM,GAAmB,IAAI,CAAC,KAAK,CACvC,IAAA,iBAAY,EAAC,8BAA8B,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC/D,CAAC;QACF,IAAI,MAAM,CAAC,QAAQ,EAAE;YACnB,MAAM,CAAC,IAAI,CAAC,uBAAuB,8BAA8B,EAAE,CAAC,CAAC;YACrE,OAAO,MAAM,CAAC,QAAQ,CAAC;SACxB;KACF;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AA3BW,QAAA,WAAW,eA2BtB"}
1
+ {"version":3,"file":"api-token.utils.js","sourceRoot":"","sources":["../src/api-token.utils.ts"],"names":[],"mappings":";;;AAAA,2BAA8C;AAC9C,2BAA6B;AAC7B,+BAA4B;AAC5B,qDAAsD;AACtD,yDAA4D;AAE5D,MAAM,yBAAyB,GAAG,yBAAyB,CAAC;AAM5D,MAAM,iBAAiB,GAAG,GAAkB,EAAE;IAC5C,MAAM,8BAA8B,GAAG,IAAA,WAAI,EACzC,IAAA,YAAO,GAAE,EACT,yBAAyB,CAC1B,CAAC;IACF,IAAI,IAAA,eAAU,EAAC,8BAA8B,CAAC,EAAE;QAC9C,MAAM,MAAM,GAAmB,IAAI,CAAC,KAAK,CACvC,IAAA,iBAAY,EAAC,8BAA8B,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC/D,CAAC;QACF,IAAI,MAAM,CAAC,QAAQ,EAAE;YACnB,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,uBAAuB,8BAA8B,EAAE,CAAC,CAAC;YACrE,OAAO,MAAM,CAAC,QAAQ,CAAC;SACxB;KACF;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACI,MAAM,WAAW,GAAG,CACzB,QAAmC,EACpB,EAAE;IACjB,IAAI,QAAQ,EAAE;QACZ,OAAO,QAAQ,CAAC;KACjB;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,EAAE;QACvC,OAAO,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;KAC5C;IACD,OAAO,iBAAiB,EAAE,CAAC;AAC7B,CAAC,CAAC;AAVW,QAAA,WAAW,eAUtB;AAEF;;;;;;;;GAQG;AACI,MAAM,YAAY,GAAG,KAAK,EAC/B,QAAmC,EACX,EAAE;IAC1B,IAAI,QAAQ,EAAE;QACZ,OAAO,QAAQ,CAAC;KACjB;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,EAAE;QACvC,OAAO,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;KAC5C;IAED,MAAM,UAAU,GAAG,MAAM,IAAA,mCAAmB,GAAE,CAAC;IAC/C,IAAI,UAAU,EAAE;QACd,OAAO,UAAU,CAAC;KACnB;IAED,OAAO,iBAAiB,EAAE,CAAC;AAC7B,CAAC,CAAC;AAhBW,QAAA,YAAY,gBAgBvB"}
package/dist/client.d.ts CHANGED
@@ -13,3 +13,7 @@ export interface MakeRequestOptions {
13
13
  }
14
14
  export declare const makeRequest: <T>(requestOptions: MakeRequestOptions) => Promise<Response<T>>;
15
15
  export declare const createClient: (options: ClientOptions) => MeticulousClient;
16
+ export declare const isInteractiveContext: () => boolean;
17
+ export declare const createClientWithOAuth: (options: ClientOptions & {
18
+ enableOAuthLogin?: boolean;
19
+ }) => Promise<MeticulousClient>;
package/dist/client.js CHANGED
@@ -3,10 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createClient = exports.makeRequest = void 0;
6
+ exports.createClientWithOAuth = exports.isInteractiveContext = exports.createClient = exports.makeRequest = void 0;
7
7
  const common_1 = require("@alwaysmeticulous/common");
8
8
  const node_fetch_1 = __importDefault(require("node-fetch"));
9
9
  const api_token_utils_1 = require("./api-token.utils");
10
+ const oauth_login_1 = require("./oauth/oauth-login");
10
11
  const get_proxy_agent_1 = require("./utils/get-proxy-agent");
11
12
  const DEFAULT_TIMEOUT = 60000;
12
13
  const BASE_API_URL = "https://app.meticulous.ai/api/";
@@ -84,16 +85,10 @@ const makeRequest = async (requestOptions) => {
84
85
  });
85
86
  };
86
87
  exports.makeRequest = makeRequest;
87
- const createClient = ({ apiToken: apiToken_, }) => {
88
- const logger = (0, common_1.initLogger)();
89
- const apiToken = (0, api_token_utils_1.getApiToken)(apiToken_);
90
- if (!apiToken) {
91
- logger.error("You must provide an API token by using the --apiToken parameter");
92
- process.exit(1);
93
- }
88
+ const buildClient = (token, logger) => {
94
89
  const makeRequestWithToken = async (url, options = {}, config) => {
95
90
  const headers = {
96
- authorization: apiToken,
91
+ authorization: token,
97
92
  };
98
93
  return (0, exports.makeRequest)({
99
94
  url,
@@ -125,7 +120,36 @@ const createClient = ({ apiToken: apiToken_, }) => {
125
120
  },
126
121
  };
127
122
  };
123
+ const createClient = ({ apiToken: apiToken_, }) => {
124
+ const logger = (0, common_1.initLogger)();
125
+ const apiToken = (0, api_token_utils_1.getApiToken)(apiToken_);
126
+ if (!apiToken) {
127
+ logger.error("You must provide an API token by using the --apiToken parameter");
128
+ process.exit(1);
129
+ }
130
+ return buildClient(apiToken, logger);
131
+ };
128
132
  exports.createClient = createClient;
133
+ const isInteractiveContext = () => process.stdin.isTTY === true && !process.env["CI"];
134
+ exports.isInteractiveContext = isInteractiveContext;
135
+ const createClientWithOAuth = async (options) => {
136
+ const logger = (0, common_1.initLogger)();
137
+ let apiToken = await (0, api_token_utils_1.getAuthToken)(options.apiToken);
138
+ const isInteractive = options.enableOAuthLogin && (0, exports.isInteractiveContext)();
139
+ if (!apiToken && isInteractive) {
140
+ const tokens = await (0, oauth_login_1.performOAuthLogin)();
141
+ apiToken = tokens.accessToken;
142
+ }
143
+ if (!apiToken) {
144
+ const message = isInteractive
145
+ ? "No authentication found. Use --apiToken, set METICULOUS_API_TOKEN, or log in via browser."
146
+ : "No authentication found. Set METICULOUS_API_TOKEN or pass --apiToken.";
147
+ logger.error(message);
148
+ return process.exit(1);
149
+ }
150
+ return buildClient(apiToken, logger);
151
+ };
152
+ exports.createClientWithOAuth = createClientWithOAuth;
129
153
  const getApiUrl = () => {
130
154
  if (process.env["METICULOUS_API_URL"]) {
131
155
  return process.env["METICULOUS_API_URL"];
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;;;;AAAA,qDAIkC;AAElC,4DAAgD;AAEhD,uDAA8D;AAC9D,qDAAwD;AAMxD,6DAAwD;AAExD,MAAM,eAAe,GAAG,KAAM,CAAC;AAC/B,MAAM,YAAY,GAAG,gCAAgC,CAAC;AActD,MAAM,iBAAiB,GAAG,KAAK,EAC7B,GAAW,EACX,OAAoB,EACpB,OAAgB,EACM,EAAE;IACxB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;QAChC,UAAU,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC,EAAE,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,eAAe,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,MAAM,IAAA,oBAAK,EAAC,GAAG,EAAE;QAChC,GAAG,OAAO;QACV,MAAM,EAAE,UAAU,CAAC,MAAqB;KACzC,CAAC,CAAC;IACH,YAAY,CAAC,SAAS,CAAC,CAAC;IAExB,MAAM,eAAe,GAA2B,EAAE,CAAC;IACnD,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,GAAW,EAAE,EAAE;QACtD,eAAe,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,IAAI,IAAO,CAAC;IACZ,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACzD,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QAC3D,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;KACrC;SAAM;QACL,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;KACrC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;QAChB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1E,KAAa,CAAC,QAAQ,GAAG;YACxB,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,IAAI;YACJ,OAAO,EAAE,eAAe;SACzB,CAAC;QACD,KAAa,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;QAC5C,MAAM,KAAK,CAAC;KACb;IAED,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,OAAO,EAAE,eAAe;KACzB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,IAAY,EAAU,EAAE;IAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACpE,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,OAAO,GAAG,IAAI,IAAI,YAAY,EAAE,CAAC;AACnC,CAAC,CAAC;AAEK,MAAM,WAAW,GAAG,KAAK,EAC9B,cAAkC,EACZ,EAAE;IACxB,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC;IACtE,IAAI,QAAQ,GAAG,WAAW,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,CAAC;IAE7C,MAAM,YAAY,GAAG;QACnB,cAAc,EAAE,kBAAkB;QAClC,GAAG,OAAO;QACV,GAAG,MAAM,CAAC,OAAO;QACjB,GAAG,OAAO,CAAC,OAAO;KACnB,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,EAAE;QACjB,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YACrD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE;gBACzC,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;aACvD;QACH,CAAC,CAAC,CAAC;QACH,QAAQ,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC;KACrC;IAED,MAAM,WAAW,GAAgB;QAC/B,GAAG,OAAO;QACV,OAAO,EAAE,YAAY;QACrB,KAAK,EAAE,IAAA,+BAAa,GAAE;KACvB,CAAC;IAEF,OAAO,MAAM,IAAA,yBAAgB,EAC3B,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,EAC9D;QACE,WAAW,EAAE,2BAAkB;QAC/B,MAAM;KACP,CACF,CAAC;AACJ,CAAC,CAAC;AApCW,QAAA,WAAW,eAoCtB;AAEF,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,MAAkB,EAAoB,EAAE;IAC1E,MAAM,oBAAoB,GAAG,KAAK,EAChC,GAAW,EACX,UAAuB,EAAE,EACzB,MAA2B,EACL,EAAE;QACxB,MAAM,OAAO,GAAG;YACd,aAAa,EAAE,KAAK;SACrB,CAAC;QAEF,OAAO,IAAA,mBAAW,EAAI;YACpB,GAAG;YACH,OAAO;YACP,OAAO;YACP,MAAM,EAAE,MAAM,IAAI,EAAE;YACpB,MAAM;SACP,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO;QACL,GAAG,EAAE,CACH,GAAW,EACX,MAA2B,EACf,EAAE;YACd,OAAO,oBAAoB,CACzB,GAAG,EACH,EAAE,MAAM,EAAE,KAAK,EAAE,EACjB,MAAM,CACO,CAAC;QAClB,CAAC;QAED,IAAI,EAAE,CACJ,GAAW,EACX,IAAQ,EACR,MAA2B,EACf,EAAE;YACd,MAAM,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACnE,MAAM,cAAc,GAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YACvD,IAAI,IAAI,KAAK,SAAS,EAAE;gBACtB,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;aAC5B;YACD,OAAO,oBAAoB,CAAI,GAAG,EAAE,cAAc,EAAE,MAAM,CAAe,CAAC;QAC5E,CAAC;QAED,GAAG,EAAE,CACH,GAAW,EACX,IAAQ,EACR,MAA2B,EACf,EAAE;YACd,MAAM,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACnE,MAAM,cAAc,GAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YACtD,IAAI,IAAI,KAAK,SAAS,EAAE;gBACtB,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;aAC5B;YACD,OAAO,oBAAoB,CAAI,GAAG,EAAE,cAAc,EAAE,MAAM,CAAe,CAAC;QAC5E,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEK,MAAM,YAAY,GAAiD,CAAC,EACzE,QAAQ,EAAE,SAAS,GACpB,EAAE,EAAE;IACH,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,IAAA,6BAAW,EAAC,SAAS,CAAC,CAAC;IACxC,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,CAAC,KAAK,CACV,iEAAiE,CAClE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;IAED,OAAO,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC,CAAC;AAbW,QAAA,YAAY,gBAavB;AAEK,MAAM,oBAAoB,GAAG,GAAY,EAAE,CAChD,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AADxC,QAAA,oBAAoB,wBACoB;AAE9C,MAAM,qBAAqB,GAAG,KAAK,EACxC,OAAuD,EAC5B,EAAE;IAC7B,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAE5B,IAAI,QAAQ,GAAG,MAAM,IAAA,8BAAY,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEpD,MAAM,aAAa,GACjB,OAAO,CAAC,gBAAgB,IAAI,IAAA,4BAAoB,GAAE,CAAC;IAErD,IAAI,CAAC,QAAQ,IAAI,aAAa,EAAE;QAC9B,MAAM,MAAM,GAAG,MAAM,IAAA,+BAAiB,GAAE,CAAC;QACzC,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC;KAC/B;IAED,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,OAAO,GAAG,aAAa;YAC3B,CAAC,CAAC,2FAA2F;YAC7F,CAAC,CAAC,uEAAuE,CAAC;QAC5E,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACxB;IAED,OAAO,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC,CAAC;AAxBW,QAAA,qBAAqB,yBAwBhC;AAEF,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE;QACrC,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;KAC1C;IACD,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./api/github-cloud-replay.api";
2
+ export { WhoamiResponse, getWhoami } from "./api/oauth.api";
2
3
  export { getProject, getRepoUrl } from "./api/project.api";
3
4
  /**
4
5
  * @deprecated Use TestRunDataLocations from `@alwaysmeticulous/api` instead.
@@ -9,8 +10,11 @@ export { getRecordedSession, getRecordedSessionData, getRecordingCommandId, post
9
10
  export { ExecuteSecureTunnelTestRunOptions, executeSecureTunnelTestRun, getTestRun, getTestRunData, GetLatestTestRunOptions, getLatestTestRunResults, TestRun, emitTelemetry, } from "./api/test-run.api";
10
11
  export { GetIsLockedOptions, getIsLocked } from "./api/deployment-lock.api";
11
12
  export { IN_PROGRESS_TEST_RUN_STATUS } from "./api/test-run.constants";
12
- export { getApiToken } from "./api-token.utils";
13
- export { ClientOptions, createClient, makeRequest } from "./client";
13
+ export { getApiToken, getAuthToken } from "./api-token.utils";
14
+ export { ClientOptions, createClient, createClientWithOAuth, isInteractiveContext, makeRequest } from "./client";
15
+ export { performOAuthLogin } from "./oauth/oauth-login";
16
+ export { getValidAccessToken } from "./oauth/oauth-refresh";
17
+ export { clearOAuthTokens } from "./oauth/oauth-token-store";
14
18
  export type { MeticulousClient } from "./types/client.types";
15
19
  export { getProxyAgent } from "./utils/get-proxy-agent";
16
20
  export { RequestAssetUploadParams, RequestAssetUploadResponse, requestAssetUpload, requestMultipartAssetUpload, RequestMultipartAssetUploadResponse, RequestUploadPartParams, RequestUploadPartResponse, requestUploadPart, CompleteAssetUploadParams, CompleteAssetUploadResponse, completeAssetUpload, CompleteContainerUploadParams, CompleteContainerUploadResponse, completeContainerUpload, MultiPartUploadInfo, DownloadDeploymentResponse, downloadProjectDeployment, GetContainerDeploymentResponse, getContainerDeployment, ContainerEnvVariable, } from "./api/project-deployments.api";
package/dist/index.js CHANGED
@@ -14,8 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.isFetchError = exports.getRegistryAuth = exports.getContainerDeployment = exports.downloadProjectDeployment = exports.completeContainerUpload = exports.completeAssetUpload = exports.requestUploadPart = exports.requestMultipartAssetUpload = exports.requestAssetUpload = exports.getProxyAgent = exports.makeRequest = exports.createClient = exports.getApiToken = exports.IN_PROGRESS_TEST_RUN_STATUS = exports.getIsLocked = exports.emitTelemetry = exports.getLatestTestRunResults = exports.getTestRunData = exports.getTestRun = exports.executeSecureTunnelTestRun = exports.postSessionIdNotification = exports.getRecordingCommandId = exports.getRecordedSessionData = exports.getRecordedSession = exports.getReplayV3DownloadUrls = exports.getReplayDownloadUrl = exports.getReplay = exports.getRepoUrl = exports.getProject = void 0;
17
+ exports.isFetchError = exports.getRegistryAuth = exports.getContainerDeployment = exports.downloadProjectDeployment = exports.completeContainerUpload = exports.completeAssetUpload = exports.requestUploadPart = exports.requestMultipartAssetUpload = exports.requestAssetUpload = exports.getProxyAgent = exports.clearOAuthTokens = exports.getValidAccessToken = exports.performOAuthLogin = exports.makeRequest = exports.isInteractiveContext = exports.createClientWithOAuth = exports.createClient = exports.getAuthToken = exports.getApiToken = exports.IN_PROGRESS_TEST_RUN_STATUS = exports.getIsLocked = exports.emitTelemetry = exports.getLatestTestRunResults = exports.getTestRunData = exports.getTestRun = exports.executeSecureTunnelTestRun = exports.postSessionIdNotification = exports.getRecordingCommandId = exports.getRecordedSessionData = exports.getRecordedSession = exports.getReplayV3DownloadUrls = exports.getReplayDownloadUrl = exports.getReplay = exports.getRepoUrl = exports.getProject = exports.getWhoami = void 0;
18
18
  __exportStar(require("./api/github-cloud-replay.api"), exports);
19
+ var oauth_api_1 = require("./api/oauth.api");
20
+ Object.defineProperty(exports, "getWhoami", { enumerable: true, get: function () { return oauth_api_1.getWhoami; } });
19
21
  var project_api_1 = require("./api/project.api");
20
22
  Object.defineProperty(exports, "getProject", { enumerable: true, get: function () { return project_api_1.getProject; } });
21
23
  Object.defineProperty(exports, "getRepoUrl", { enumerable: true, get: function () { return project_api_1.getRepoUrl; } });
@@ -40,9 +42,18 @@ var test_run_constants_1 = require("./api/test-run.constants");
40
42
  Object.defineProperty(exports, "IN_PROGRESS_TEST_RUN_STATUS", { enumerable: true, get: function () { return test_run_constants_1.IN_PROGRESS_TEST_RUN_STATUS; } });
41
43
  var api_token_utils_1 = require("./api-token.utils");
42
44
  Object.defineProperty(exports, "getApiToken", { enumerable: true, get: function () { return api_token_utils_1.getApiToken; } });
45
+ Object.defineProperty(exports, "getAuthToken", { enumerable: true, get: function () { return api_token_utils_1.getAuthToken; } });
43
46
  var client_1 = require("./client");
44
47
  Object.defineProperty(exports, "createClient", { enumerable: true, get: function () { return client_1.createClient; } });
48
+ Object.defineProperty(exports, "createClientWithOAuth", { enumerable: true, get: function () { return client_1.createClientWithOAuth; } });
49
+ Object.defineProperty(exports, "isInteractiveContext", { enumerable: true, get: function () { return client_1.isInteractiveContext; } });
45
50
  Object.defineProperty(exports, "makeRequest", { enumerable: true, get: function () { return client_1.makeRequest; } });
51
+ var oauth_login_1 = require("./oauth/oauth-login");
52
+ Object.defineProperty(exports, "performOAuthLogin", { enumerable: true, get: function () { return oauth_login_1.performOAuthLogin; } });
53
+ var oauth_refresh_1 = require("./oauth/oauth-refresh");
54
+ Object.defineProperty(exports, "getValidAccessToken", { enumerable: true, get: function () { return oauth_refresh_1.getValidAccessToken; } });
55
+ var oauth_token_store_1 = require("./oauth/oauth-token-store");
56
+ Object.defineProperty(exports, "clearOAuthTokens", { enumerable: true, get: function () { return oauth_token_store_1.clearOAuthTokens; } });
46
57
  var get_proxy_agent_1 = require("./utils/get-proxy-agent");
47
58
  Object.defineProperty(exports, "getProxyAgent", { enumerable: true, get: function () { return get_proxy_agent_1.getProxyAgent; } });
48
59
  var project_deployments_api_1 = require("./api/project-deployments.api");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,gEAA8C;AAC9C,iDAA2D;AAAlD,yGAAA,UAAU,OAAA;AAAE,yGAAA,UAAU,OAAA;AAK/B,+CAK0B;AAHxB,uGAAA,SAAS,OAAA;AACT,kHAAA,oBAAoB,OAAA;AACpB,qHAAA,uBAAuB,OAAA;AAEzB,iDAK2B;AAJzB,iHAAA,kBAAkB,OAAA;AAClB,qHAAA,sBAAsB,OAAA;AACtB,oHAAA,qBAAqB,OAAA;AACrB,wHAAA,yBAAyB,OAAA;AAE3B,mDAS4B;AAP1B,0HAAA,0BAA0B,OAAA;AAC1B,0GAAA,UAAU,OAAA;AACV,8GAAA,cAAc,OAAA;AAEd,uHAAA,uBAAuB,OAAA;AAEvB,6GAAA,aAAa,OAAA;AAEf,iEAA4E;AAA/C,kHAAA,WAAW,OAAA;AACxC,+DAAuE;AAA9D,iIAAA,2BAA2B,OAAA;AACpC,qDAAgD;AAAvC,8GAAA,WAAW,OAAA;AACpB,mCAAoE;AAA5C,sGAAA,YAAY,OAAA;AAAE,qGAAA,WAAW,OAAA;AAEjD,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,yEAqBuC;AAlBrC,6HAAA,kBAAkB,OAAA;AAClB,sIAAA,2BAA2B,OAAA;AAI3B,4HAAA,iBAAiB,OAAA;AAGjB,8HAAA,mBAAmB,OAAA;AAGnB,kIAAA,uBAAuB,OAAA;AAGvB,oIAAA,yBAAyB,OAAA;AAEzB,iIAAA,sBAAsB,OAAA;AAGxB,mDAA8E;AAA5C,+GAAA,eAAe,OAAA;AACjD,mCAAwC;AAA/B,sGAAA,YAAY,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,gEAA8C;AAC9C,6CAA4D;AAAnC,sGAAA,SAAS,OAAA;AAClC,iDAA2D;AAAlD,yGAAA,UAAU,OAAA;AAAE,yGAAA,UAAU,OAAA;AAK/B,+CAK0B;AAHxB,uGAAA,SAAS,OAAA;AACT,kHAAA,oBAAoB,OAAA;AACpB,qHAAA,uBAAuB,OAAA;AAEzB,iDAK2B;AAJzB,iHAAA,kBAAkB,OAAA;AAClB,qHAAA,sBAAsB,OAAA;AACtB,oHAAA,qBAAqB,OAAA;AACrB,wHAAA,yBAAyB,OAAA;AAE3B,mDAS4B;AAP1B,0HAAA,0BAA0B,OAAA;AAC1B,0GAAA,UAAU,OAAA;AACV,8GAAA,cAAc,OAAA;AAEd,uHAAA,uBAAuB,OAAA;AAEvB,6GAAA,aAAa,OAAA;AAEf,iEAA4E;AAA/C,kHAAA,WAAW,OAAA;AACxC,+DAAuE;AAA9D,iIAAA,2BAA2B,OAAA;AACpC,qDAA8D;AAArD,8GAAA,WAAW,OAAA;AAAE,+GAAA,YAAY,OAAA;AAClC,mCAAiH;AAAzF,sGAAA,YAAY,OAAA;AAAE,+GAAA,qBAAqB,OAAA;AAAE,8GAAA,oBAAoB,OAAA;AAAE,qGAAA,WAAW,OAAA;AAC9F,mDAAwD;AAA/C,gHAAA,iBAAiB,OAAA;AAC1B,uDAA4D;AAAnD,oHAAA,mBAAmB,OAAA;AAC5B,+DAA6D;AAApD,qHAAA,gBAAgB,OAAA;AAEzB,2DAAwD;AAA/C,gHAAA,aAAa,OAAA;AACtB,yEAqBuC;AAlBrC,6HAAA,kBAAkB,OAAA;AAClB,sIAAA,2BAA2B,OAAA;AAI3B,4HAAA,iBAAiB,OAAA;AAGjB,8HAAA,mBAAmB,OAAA;AAGnB,kIAAA,uBAAuB,OAAA;AAGvB,oIAAA,yBAAyB,OAAA;AAEzB,iIAAA,sBAAsB,OAAA;AAGxB,mDAA8E;AAA5C,+GAAA,eAAe,OAAA;AACjD,mCAAwC;AAA/B,sGAAA,YAAY,OAAA"}
@@ -0,0 +1,9 @@
1
+ export interface CallbackResult {
2
+ code: string;
3
+ state: string;
4
+ }
5
+ export interface CallbackServer {
6
+ port: number;
7
+ waitForCallback: () => Promise<CallbackResult>;
8
+ }
9
+ export declare const startCallbackServer: () => Promise<CallbackServer>;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startCallbackServer = void 0;
4
+ const http_1 = require("http");
5
+ const CALLBACK_TIMEOUT_MS = 120000;
6
+ const SUCCESS_HTML = `<!DOCTYPE html>
7
+ <html>
8
+ <head>
9
+ <title>Meticulous CLI</title>
10
+ <meta charset="utf-8">
11
+ </head>
12
+ <body style="font-family: system-ui, -apple-system, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #171719; color: #fff;">
13
+ <div style="text-align: center; display: flex; flex-direction: column; align-items: center; gap: 24px;">
14
+ <img src="https://app.meticulous.ai/meticulous_logo.svg" alt="Meticulous" width="48" height="51" />
15
+ <svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
16
+ <circle cx="24" cy="24" r="24" fill="#1AC590"/>
17
+ <path d="M14 24.5L21 31.5L34 18.5" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
18
+ </svg>
19
+ <h2 style="margin: 0; font-size: 24px; font-weight: 600;">Authentication successful</h2>
20
+ <p style="margin: 0; font-size: 16px; color: #a1a1aa;">You can close this tab and return to the terminal.</p>
21
+ </div>
22
+ </body>
23
+ </html>`;
24
+ const startCallbackServer = () => {
25
+ return new Promise((resolveServer, rejectServer) => {
26
+ let callbackResolve;
27
+ let callbackReject;
28
+ const callbackPromise = new Promise((resolve, reject) => {
29
+ callbackResolve = resolve;
30
+ callbackReject = reject;
31
+ });
32
+ const server = (0, http_1.createServer)((req, res) => {
33
+ var _a;
34
+ if (!((_a = req.url) === null || _a === void 0 ? void 0 : _a.startsWith("/callback"))) {
35
+ res.writeHead(404);
36
+ res.end("Not found");
37
+ return;
38
+ }
39
+ const url = new URL(req.url, `http://127.0.0.1`);
40
+ const code = url.searchParams.get("code");
41
+ const state = url.searchParams.get("state");
42
+ const error = url.searchParams.get("error");
43
+ res.writeHead(200, { "Content-Type": "text/html" });
44
+ res.end(SUCCESS_HTML);
45
+ if (error) {
46
+ const errorDescription = url.searchParams.get("error_description") || error;
47
+ callbackReject(new Error(`OAuth error: ${errorDescription}`));
48
+ }
49
+ else if (code && state) {
50
+ callbackResolve({ code, state });
51
+ }
52
+ else {
53
+ callbackReject(new Error("Missing code or state in OAuth callback"));
54
+ }
55
+ server.close();
56
+ });
57
+ const timeout = setTimeout(() => {
58
+ server.close();
59
+ callbackReject(new Error(`OAuth login timed out after ${CALLBACK_TIMEOUT_MS / 1000} seconds. Please try again.`));
60
+ }, CALLBACK_TIMEOUT_MS);
61
+ server.listen(0, "127.0.0.1", () => {
62
+ const address = server.address();
63
+ if (!address || typeof address === "string") {
64
+ rejectServer(new Error("Failed to start callback server"));
65
+ return;
66
+ }
67
+ resolveServer({
68
+ port: address.port,
69
+ waitForCallback: async () => {
70
+ try {
71
+ return await callbackPromise;
72
+ }
73
+ finally {
74
+ clearTimeout(timeout);
75
+ }
76
+ },
77
+ });
78
+ });
79
+ server.on("error", (err) => {
80
+ clearTimeout(timeout);
81
+ rejectServer(err);
82
+ });
83
+ });
84
+ };
85
+ exports.startCallbackServer = startCallbackServer;
86
+ //# sourceMappingURL=oauth-callback-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-callback-server.js","sourceRoot":"","sources":["../../src/oauth/oauth-callback-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare const KEYCLOAK_ISSUER_URL: string;
2
+ export declare const CLI_CLIENT_ID = "meticulous-cli";
3
+ export declare const OAUTH_SCOPES = "openid email profile";
4
+ export declare const getTokenEndpoint: () => Promise<string>;
5
+ export declare const getWebappBaseUrl: () => string;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getWebappBaseUrl = exports.getTokenEndpoint = exports.OAUTH_SCOPES = exports.CLI_CLIENT_ID = exports.KEYCLOAK_ISSUER_URL = void 0;
4
+ exports.KEYCLOAK_ISSUER_URL = process.env["METICULOUS_OAUTH_ISSUER_URL"] ||
5
+ "https://app.meticulous.ai/auth/realms/meticulous";
6
+ exports.CLI_CLIENT_ID = "meticulous-cli";
7
+ exports.OAUTH_SCOPES = "openid email profile";
8
+ const WELL_KNOWN_PATH = "/.well-known/openid-configuration";
9
+ let cachedTokenEndpoint = null;
10
+ const getTokenEndpoint = async () => {
11
+ if (cachedTokenEndpoint) {
12
+ return cachedTokenEndpoint;
13
+ }
14
+ const response = await fetch(`${exports.KEYCLOAK_ISSUER_URL}${WELL_KNOWN_PATH}`);
15
+ if (!response.ok) {
16
+ throw new Error(`Failed to fetch OpenID configuration: ${response.status} ${response.statusText}`);
17
+ }
18
+ const config = (await response.json());
19
+ if (!config.token_endpoint) {
20
+ throw new Error("OpenID configuration missing token_endpoint");
21
+ }
22
+ cachedTokenEndpoint = config.token_endpoint;
23
+ return cachedTokenEndpoint;
24
+ };
25
+ exports.getTokenEndpoint = getTokenEndpoint;
26
+ const DEFAULT_WEBAPP_BASE_URL = "https://app.meticulous.ai";
27
+ const getWebappBaseUrl = () => {
28
+ const apiUrlFromEnv = process.env["METICULOUS_API_URL"];
29
+ if (apiUrlFromEnv && apiUrlFromEnv.includes("localhost")) {
30
+ return apiUrlFromEnv.replace(/\/api\/?$/, "").replace(":3000", ":3001");
31
+ }
32
+ return DEFAULT_WEBAPP_BASE_URL;
33
+ };
34
+ exports.getWebappBaseUrl = getWebappBaseUrl;
35
+ //# sourceMappingURL=oauth-constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-constants.js","sourceRoot":"","sources":["../../src/oauth/oauth-constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,mBAAmB,GAC9B,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;IAC1C,kDAAkD,CAAC;AAExC,QAAA,aAAa,GAAG,gBAAgB,CAAC;AAEjC,QAAA,YAAY,GAAG,sBAAsB,CAAC;AAEnD,MAAM,eAAe,GAAG,mCAAmC,CAAC;AAE5D,IAAI,mBAAmB,GAAkB,IAAI,CAAC;AAEvC,MAAM,gBAAgB,GAAG,KAAK,IAAqB,EAAE;IAC1D,IAAI,mBAAmB,EAAE;QACvB,OAAO,mBAAmB,CAAC;KAC5B;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,2BAAmB,GAAG,eAAe,EAAE,CAAC,CAAC;IACzE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;QAChB,MAAM,IAAI,KAAK,CACb,yCAAyC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAClF,CAAC;KACH;IAED,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA+B,CAAC;IACrE,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE;QAC1B,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;KAChE;IAED,mBAAmB,GAAG,MAAM,CAAC,cAAc,CAAC;IAC5C,OAAO,mBAAmB,CAAC;AAC7B,CAAC,CAAC;AAnBW,QAAA,gBAAgB,oBAmB3B;AAEF,MAAM,uBAAuB,GAAG,2BAA2B,CAAC;AAErD,MAAM,gBAAgB,GAAG,GAAW,EAAE;IAC3C,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAExD,IAAI,aAAa,IAAI,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE;QACxD,OAAO,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;KACzE;IAED,OAAO,uBAAuB,CAAC;AACjC,CAAC,CAAC;AARW,QAAA,gBAAgB,oBAQ3B"}
@@ -0,0 +1,2 @@
1
+ import { StoredOAuthTokens } from "./oauth-token-store";
2
+ export declare const performOAuthLogin: () => Promise<StoredOAuthTokens>;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.performOAuthLogin = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const common_1 = require("@alwaysmeticulous/common");
6
+ const oauth_callback_server_1 = require("./oauth-callback-server");
7
+ const oauth_constants_1 = require("./oauth-constants");
8
+ const oauth_pkce_1 = require("./oauth-pkce");
9
+ const oauth_token_store_1 = require("./oauth-token-store");
10
+ const performOAuthLogin = async () => {
11
+ const logger = (0, common_1.initLogger)();
12
+ const codeVerifier = (0, oauth_pkce_1.generateCodeVerifier)();
13
+ const codeChallenge = (0, oauth_pkce_1.generateCodeChallenge)(codeVerifier);
14
+ const state = (0, oauth_pkce_1.generateState)();
15
+ const callbackServer = await (0, oauth_callback_server_1.startCallbackServer)();
16
+ const redirectUri = `http://127.0.0.1:${callbackServer.port}/callback`;
17
+ const authUrl = buildAuthorizationUrl({
18
+ codeChallenge,
19
+ state,
20
+ redirectUri,
21
+ });
22
+ logger.info("Opening browser for authentication...");
23
+ logger.info(`If the browser does not open, visit: ${authUrl}`);
24
+ openBrowser(authUrl);
25
+ const { code, state: returnedState } = await callbackServer.waitForCallback();
26
+ if (returnedState !== state) {
27
+ throw new Error("OAuth state mismatch. This could indicate a CSRF attack. Please try again.");
28
+ }
29
+ const tokens = await exchangeCodeForTokens({
30
+ code,
31
+ codeVerifier,
32
+ redirectUri,
33
+ });
34
+ (0, oauth_token_store_1.storeOAuthTokens)(tokens);
35
+ logger.info("Authentication successful.");
36
+ return tokens;
37
+ };
38
+ exports.performOAuthLogin = performOAuthLogin;
39
+ const buildAuthorizationUrl = ({ codeChallenge, state, redirectUri, }) => {
40
+ const params = new URLSearchParams({
41
+ client_id: oauth_constants_1.CLI_CLIENT_ID,
42
+ response_type: "code",
43
+ scope: oauth_constants_1.OAUTH_SCOPES,
44
+ redirect_uri: redirectUri,
45
+ code_challenge: codeChallenge,
46
+ code_challenge_method: "S256",
47
+ state,
48
+ issuer: oauth_constants_1.KEYCLOAK_ISSUER_URL,
49
+ });
50
+ const webappBaseUrl = (0, oauth_constants_1.getWebappBaseUrl)();
51
+ return `${webappBaseUrl}/cli-login?${params.toString()}`;
52
+ };
53
+ const exchangeCodeForTokens = async ({ code, codeVerifier, redirectUri, }) => {
54
+ const body = new URLSearchParams({
55
+ grant_type: "authorization_code",
56
+ client_id: oauth_constants_1.CLI_CLIENT_ID,
57
+ code,
58
+ redirect_uri: redirectUri,
59
+ code_verifier: codeVerifier,
60
+ });
61
+ const tokenEndpoint = await (0, oauth_constants_1.getTokenEndpoint)();
62
+ const response = await fetch(tokenEndpoint, {
63
+ method: "POST",
64
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
65
+ body: body.toString(),
66
+ });
67
+ if (!response.ok) {
68
+ const errorText = await response.text();
69
+ throw new Error(`Token exchange failed: ${response.status} ${errorText}`);
70
+ }
71
+ const data = (await response.json());
72
+ return {
73
+ accessToken: data.access_token,
74
+ refreshToken: data.refresh_token,
75
+ expiresAt: Math.floor(Date.now() / 1000) + data.expires_in,
76
+ idToken: data.id_token,
77
+ };
78
+ };
79
+ const openBrowser = (url) => {
80
+ const command = process.platform === "darwin"
81
+ ? `open "${url}"`
82
+ : process.platform === "win32"
83
+ ? `start "" "${url}"`
84
+ : `xdg-open "${url}"`;
85
+ (0, child_process_1.exec)(command, (error) => {
86
+ if (error) {
87
+ // Browser open failure is non-fatal — the URL is logged as a fallback
88
+ }
89
+ });
90
+ };
91
+ //# sourceMappingURL=oauth-login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-login.js","sourceRoot":"","sources":["../../src/oauth/oauth-login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const generateCodeVerifier: () => string;
2
+ export declare const generateCodeChallenge: (verifier: string) => string;
3
+ export declare const generateState: () => string;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateState = exports.generateCodeChallenge = exports.generateCodeVerifier = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const generateCodeVerifier = () => {
6
+ return (0, crypto_1.randomBytes)(32).toString("base64url");
7
+ };
8
+ exports.generateCodeVerifier = generateCodeVerifier;
9
+ const generateCodeChallenge = (verifier) => {
10
+ return (0, crypto_1.createHash)("sha256").update(verifier).digest("base64url");
11
+ };
12
+ exports.generateCodeChallenge = generateCodeChallenge;
13
+ const generateState = () => {
14
+ return (0, crypto_1.randomBytes)(16).toString("base64url");
15
+ };
16
+ exports.generateState = generateState;
17
+ //# sourceMappingURL=oauth-pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-pkce.js","sourceRoot":"","sources":["../../src/oauth/oauth-pkce.ts"],"names":[],"mappings":";;;AAAA,mCAAiD;AAE1C,MAAM,oBAAoB,GAAG,GAAW,EAAE;IAC/C,OAAO,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC,CAAC;AAFW,QAAA,oBAAoB,wBAE/B;AAEK,MAAM,qBAAqB,GAAG,CAAC,QAAgB,EAAU,EAAE;IAChE,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnE,CAAC,CAAC;AAFW,QAAA,qBAAqB,yBAEhC;AAEK,MAAM,aAAa,GAAG,GAAW,EAAE;IACxC,OAAO,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC,CAAC;AAFW,QAAA,aAAa,iBAExB"}
@@ -0,0 +1 @@
1
+ export declare const getValidAccessToken: () => Promise<string | null>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getValidAccessToken = void 0;
4
+ const oauth_constants_1 = require("./oauth-constants");
5
+ const oauth_token_store_1 = require("./oauth-token-store");
6
+ const TOKEN_EXPIRY_BUFFER_SECONDS = 30;
7
+ const getValidAccessToken = async () => {
8
+ const tokens = (0, oauth_token_store_1.getStoredOAuthTokens)();
9
+ if (!tokens) {
10
+ return null;
11
+ }
12
+ const now = Math.floor(Date.now() / 1000);
13
+ if (tokens.expiresAt > now + TOKEN_EXPIRY_BUFFER_SECONDS) {
14
+ return tokens.accessToken;
15
+ }
16
+ if (!tokens.refreshToken) {
17
+ (0, oauth_token_store_1.clearOAuthTokens)();
18
+ return null;
19
+ }
20
+ try {
21
+ const body = new URLSearchParams({
22
+ grant_type: "refresh_token",
23
+ client_id: oauth_constants_1.CLI_CLIENT_ID,
24
+ refresh_token: tokens.refreshToken,
25
+ });
26
+ const tokenEndpoint = await (0, oauth_constants_1.getTokenEndpoint)();
27
+ const response = await fetch(tokenEndpoint, {
28
+ method: "POST",
29
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
30
+ body: body.toString(),
31
+ });
32
+ if (!response.ok) {
33
+ (0, oauth_token_store_1.clearOAuthTokens)();
34
+ return null;
35
+ }
36
+ const data = (await response.json());
37
+ const updatedTokens = {
38
+ accessToken: data.access_token,
39
+ refreshToken: data.refresh_token,
40
+ expiresAt: Math.floor(Date.now() / 1000) + data.expires_in,
41
+ idToken: data.id_token,
42
+ };
43
+ (0, oauth_token_store_1.storeOAuthTokens)(updatedTokens);
44
+ return updatedTokens.accessToken;
45
+ }
46
+ catch {
47
+ (0, oauth_token_store_1.clearOAuthTokens)();
48
+ return null;
49
+ }
50
+ };
51
+ exports.getValidAccessToken = getValidAccessToken;
52
+ //# sourceMappingURL=oauth-refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-refresh.js","sourceRoot":"","sources":["../../src/oauth/oauth-refresh.ts"],"names":[],"mappings":";;;AAAA,uDAAoE;AACpE,2DAI6B;AAE7B,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAEhC,MAAM,mBAAmB,GAAG,KAAK,IAA4B,EAAE;IACpE,MAAM,MAAM,GAAG,IAAA,wCAAoB,GAAE,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE;QACX,OAAO,IAAI,CAAC;KACb;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,SAAS,GAAG,GAAG,GAAG,2BAA2B,EAAE;QACxD,OAAO,MAAM,CAAC,WAAW,CAAC;KAC3B;IAED,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;QACxB,IAAA,oCAAgB,GAAE,CAAC;QACnB,OAAO,IAAI,CAAC;KACb;IAED,IAAI;QACF,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;YAC/B,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,+BAAa;YACxB,aAAa,EAAE,MAAM,CAAC,YAAY;SACnC,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,MAAM,IAAA,kCAAgB,GAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,aAAa,EAAE;YAC1C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;YAChE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;SACtB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;YAChB,IAAA,oCAAgB,GAAE,CAAC;YACnB,OAAO,IAAI,CAAC;SACb;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAKlC,CAAC;QAEF,MAAM,aAAa,GAAG;YACpB,WAAW,EAAE,IAAI,CAAC,YAAY;YAC9B,YAAY,EAAE,IAAI,CAAC,aAAa;YAChC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU;YAC1D,OAAO,EAAE,IAAI,CAAC,QAAQ;SACvB,CAAC;QAEF,IAAA,oCAAgB,EAAC,aAAa,CAAC,CAAC;QAChC,OAAO,aAAa,CAAC,WAAW,CAAC;KAClC;IAAC,MAAM;QACN,IAAA,oCAAgB,GAAE,CAAC;QACnB,OAAO,IAAI,CAAC;KACb;AACH,CAAC,CAAC;AAvDW,QAAA,mBAAmB,uBAuD9B"}
@@ -0,0 +1,9 @@
1
+ export interface StoredOAuthTokens {
2
+ accessToken: string;
3
+ refreshToken: string;
4
+ expiresAt: number;
5
+ idToken?: string | undefined;
6
+ }
7
+ export declare const getStoredOAuthTokens: () => StoredOAuthTokens | null;
8
+ export declare const storeOAuthTokens: (tokens: StoredOAuthTokens) => void;
9
+ export declare const clearOAuthTokens: () => void;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clearOAuthTokens = exports.storeOAuthTokens = exports.getStoredOAuthTokens = void 0;
4
+ const fs_1 = require("fs");
5
+ const os_1 = require("os");
6
+ const path_1 = require("path");
7
+ const METICULOUS_DIR = (0, path_1.join)((0, os_1.homedir)(), ".meticulous");
8
+ const TOKEN_FILE_PATH = (0, path_1.join)(METICULOUS_DIR, "oauth-tokens.json");
9
+ const getStoredOAuthTokens = () => {
10
+ try {
11
+ if (!(0, fs_1.existsSync)(TOKEN_FILE_PATH)) {
12
+ return null;
13
+ }
14
+ const data = (0, fs_1.readFileSync)(TOKEN_FILE_PATH, "utf-8");
15
+ return JSON.parse(data);
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ };
21
+ exports.getStoredOAuthTokens = getStoredOAuthTokens;
22
+ const storeOAuthTokens = (tokens) => {
23
+ if (!(0, fs_1.existsSync)(METICULOUS_DIR)) {
24
+ (0, fs_1.mkdirSync)(METICULOUS_DIR, { recursive: true });
25
+ }
26
+ (0, fs_1.writeFileSync)(TOKEN_FILE_PATH, JSON.stringify(tokens, null, 2), {
27
+ mode: 0o600,
28
+ });
29
+ };
30
+ exports.storeOAuthTokens = storeOAuthTokens;
31
+ const clearOAuthTokens = () => {
32
+ try {
33
+ if ((0, fs_1.existsSync)(TOKEN_FILE_PATH)) {
34
+ (0, fs_1.unlinkSync)(TOKEN_FILE_PATH);
35
+ }
36
+ }
37
+ catch {
38
+ // Ignore errors during cleanup
39
+ }
40
+ };
41
+ exports.clearOAuthTokens = clearOAuthTokens;
42
+ //# sourceMappingURL=oauth-token-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-store.js","sourceRoot":"","sources":["../../src/oauth/oauth-token-store.ts"],"names":[],"mappings":";;;AAAA,2BAMY;AACZ,2BAA6B;AAC7B,+BAA4B;AAS5B,MAAM,cAAc,GAAG,IAAA,WAAI,EAAC,IAAA,YAAO,GAAE,EAAE,aAAa,CAAC,CAAC;AACtD,MAAM,eAAe,GAAG,IAAA,WAAI,EAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;AAE3D,MAAM,oBAAoB,GAAG,GAA6B,EAAE;IACjE,IAAI;QACF,IAAI,CAAC,IAAA,eAAU,EAAC,eAAe,CAAC,EAAE;YAChC,OAAO,IAAI,CAAC;SACb;QACD,MAAM,IAAI,GAAG,IAAA,iBAAY,EAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAsB,CAAC;KAC9C;IAAC,MAAM;QACN,OAAO,IAAI,CAAC;KACb;AACH,CAAC,CAAC;AAVW,QAAA,oBAAoB,wBAU/B;AAEK,MAAM,gBAAgB,GAAG,CAAC,MAAyB,EAAQ,EAAE;IAClE,IAAI,CAAC,IAAA,eAAU,EAAC,cAAc,CAAC,EAAE;QAC/B,IAAA,cAAS,EAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;KAChD;IACD,IAAA,kBAAa,EAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAC9D,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC,CAAC;AAPW,QAAA,gBAAgB,oBAO3B;AAEK,MAAM,gBAAgB,GAAG,GAAS,EAAE;IACzC,IAAI;QACF,IAAI,IAAA,eAAU,EAAC,eAAe,CAAC,EAAE;YAC/B,IAAA,eAAU,EAAC,eAAe,CAAC,CAAC;SAC7B;KACF;IAAC,MAAM;QACN,+BAA+B;KAChC;AACH,CAAC,CAAC;AARW,QAAA,gBAAgB,oBAQ3B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwaysmeticulous/client",
3
- "version": "2.253.0",
3
+ "version": "2.254.0",
4
4
  "description": "Helper methods for using the Meticulous backend API",
5
5
  "license": "ISC",
6
6
  "main": "dist/index.js",
@@ -45,5 +45,5 @@
45
45
  "devDependencies": {
46
46
  "@types/node-fetch": "^2.6.13"
47
47
  },
48
- "gitHead": "662d6b2fe7852366cce91ce93a3d2801cbb59c78"
48
+ "gitHead": "35ec0177b88e0ba98cc559590576f1265a0f7375"
49
49
  }