@zuplo/cli 6.48.5 → 6.48.7

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.
@@ -1,7 +1,7 @@
1
1
  import { captureEvent } from "../common/analytics/lib.js";
2
2
  import { identify } from "../common/middleware/user-identification.js";
3
3
  import setBlocking, { printResultToConsoleAndExitGracefully, } from "../common/output.js";
4
- import { login } from "../login/handler.js";
4
+ import { login } from "../login/login.js";
5
5
  export default {
6
6
  desc: false,
7
7
  command: "login",
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/cmds/login.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,6CAA6C,CAAC;AACvE,OAAO,WAAW,EAAE,EAClB,qCAAqC,GACtC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE5C,eAAe;IAEb,IAAI,EAAE,KAAK;IAEX,OAAO,EAAE,OAAO;IAEhB,OAAO,EAAE,CAAC,KAAW,EAAiB,EAAE;QACtC,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAa,EAAE,EAAE;QAC/B,MAAM,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QACnD,MAAM,KAAK,EAAE,CAAC;QACd,MAAM,qCAAqC,CAAC,6BAA6B,CAAC,CAAC;IAC7E,CAAC;CACF,CAAC","sourcesContent":["import { Argv } from \"yargs\";\nimport { captureEvent } from \"../common/analytics/lib.js\";\nimport { identify } from \"../common/middleware/user-identification.js\";\nimport setBlocking, {\n printResultToConsoleAndExitGracefully,\n} from \"../common/output.js\";\nimport { login } from \"../login/handler.js\";\n\nexport default {\n // For now, hide this command\n desc: false,\n // desc: \"Authenticates the user\",\n command: \"login\",\n\n builder: (yargs: Argv): Argv<unknown> => {\n return yargs.middleware([setBlocking, identify]);\n },\n handler: async (argv: unknown) => {\n await captureEvent({ argv, event: \"zuplo login\" });\n await login();\n await printResultToConsoleAndExitGracefully(\"Successfully authenticated.\");\n },\n};\n"]}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/cmds/login.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,6CAA6C,CAAC;AACvE,OAAO,WAAW,EAAE,EAClB,qCAAqC,GACtC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,eAAe;IAEb,IAAI,EAAE,KAAK;IAEX,OAAO,EAAE,OAAO;IAEhB,OAAO,EAAE,CAAC,KAAW,EAAiB,EAAE;QACtC,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAa,EAAE,EAAE;QAC/B,MAAM,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QACnD,MAAM,KAAK,EAAE,CAAC;QACd,MAAM,qCAAqC,CAAC,6BAA6B,CAAC,CAAC;IAC7E,CAAC;CACF,CAAC","sourcesContent":["import { Argv } from \"yargs\";\nimport { captureEvent } from \"../common/analytics/lib.js\";\nimport { identify } from \"../common/middleware/user-identification.js\";\nimport setBlocking, {\n printResultToConsoleAndExitGracefully,\n} from \"../common/output.js\";\nimport { login } from \"../login/login.js\";\n\nexport default {\n // For now, hide this command\n desc: false,\n // desc: \"Authenticates the user\",\n command: \"login\",\n\n builder: (yargs: Argv): Argv<unknown> => {\n return yargs.middleware([setBlocking, identify]);\n },\n handler: async (argv: unknown) => {\n await captureEvent({ argv, event: \"zuplo login\" });\n await login();\n await printResultToConsoleAndExitGracefully(\"Successfully authenticated.\");\n },\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../../src/common/middleware/authentication.ts"],"names":[],"mappings":"AAqCA,wBAAsB,YAAY,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,iBA8B9D"}
1
+ {"version":3,"file":"authentication.d.ts","sourceRoot":"","sources":["../../../src/common/middleware/authentication.ts"],"names":[],"mappings":"AAWA,wBAAsB,YAAY,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,iBA8B9D"}
@@ -1,27 +1,10 @@
1
1
  import { confirm } from "@inquirer/prompts";
2
- import { decodeJwt } from "jose";
3
- import { existsSync } from "node:fs";
4
- import { readFile } from "node:fs/promises";
5
- import { join } from "node:path";
6
- import { login } from "../../login/handler.js";
7
- import { ZUPLO_AUTH_FILE_NAME } from "../constants.js";
2
+ import { login } from "../../login/login.js";
3
+ import { getAuthToken } from "../../login/tokens.js";
8
4
  import { printCriticalFailureToConsoleAndExit } from "../output.js";
9
- import { ZUPLO_XDG_STATE_HOME } from "../xdg/lib.js";
10
5
  async function fail() {
11
6
  await printCriticalFailureToConsoleAndExit(`You are not authenticated. Please run \`zuplo login\` to log in or set an api key.`);
12
7
  }
13
- async function getAuthToken() {
14
- if (!existsSync(join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME))) {
15
- return;
16
- }
17
- const rawAuth = await readFile(join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME), "utf-8");
18
- const authJson = JSON.parse(rawAuth);
19
- const jwt = decodeJwt(authJson.access_token);
20
- if (!jwt.exp || jwt.exp < Date.now() / 1000) {
21
- return;
22
- }
23
- return authJson.access_token;
24
- }
25
8
  export async function authenticate(argv) {
26
9
  if (argv["api-key"]) {
27
10
  Object.assign(argv, { authToken: argv["api-key"] });
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../../src/common/middleware/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,oCAAoC,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,KAAK,UAAU,IAAI;IACjB,MAAM,oCAAoC,CACxC,oFAAoF,CACrF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY;IAEzB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAC,EAAE,CAAC;QAClE,OAAO;IACT,CAAC;IAGD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAC5B,IAAI,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,EAChD,OAAO,CACR,CAAC;IACF,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAErC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAE7C,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;QAC5C,OAAO;IACT,CAAC;IACD,OAAO,QAAQ,CAAC,YAAY,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAA4B;IAC7D,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACpB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IAEnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;YAC3B,OAAO,EAAE,sDAAsD;SAChE,CAAC,CAAC;QAGH,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAGD,MAAM,KAAK,EAAE,CAAC;QAGd,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAGD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC","sourcesContent":["import { confirm } from \"@inquirer/prompts\";\nimport { decodeJwt } from \"jose\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { login } from \"../../login/handler.js\";\nimport { ZUPLO_AUTH_FILE_NAME } from \"../constants.js\";\nimport { printCriticalFailureToConsoleAndExit } from \"../output.js\";\nimport { ZUPLO_XDG_STATE_HOME } from \"../xdg/lib.js\";\n\nasync function fail() {\n await printCriticalFailureToConsoleAndExit(\n `You are not authenticated. Please run \\`zuplo login\\` to log in or set an api key.`\n );\n}\n\nasync function getAuthToken(): Promise<string | undefined> {\n // The auth file doesn't exist.\n if (!existsSync(join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME))) {\n return;\n }\n\n // The credentials have expired.\n const rawAuth = await readFile(\n join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME),\n \"utf-8\"\n );\n const authJson = JSON.parse(rawAuth);\n\n const jwt = decodeJwt(authJson.access_token);\n\n if (!jwt.exp || jwt.exp < Date.now() / 1000) {\n return;\n }\n return authJson.access_token;\n}\n\nexport async function authenticate(argv: { \"api-key\"?: string }) {\n if (argv[\"api-key\"]) {\n Object.assign(argv, { authToken: argv[\"api-key\"] });\n return;\n }\n\n const token = await getAuthToken();\n\n if (!token) {\n const result = await confirm({\n message: \"You are not authenticated. Would you like to log in?\",\n });\n\n // IF the user said no, then return an error\n if (!result) {\n return fail();\n }\n\n // Login\n await login();\n\n // Validate the login again\n const isValid = await getAuthToken();\n if (!isValid) {\n return fail();\n }\n }\n\n // Assign the token to the args\n Object.assign(argv, { authToken: token });\n}\n"]}
1
+ {"version":3,"file":"authentication.js","sourceRoot":"","sources":["../../../src/common/middleware/authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,oCAAoC,EAAE,MAAM,cAAc,CAAC;AAEpE,KAAK,UAAU,IAAI;IACjB,MAAM,oCAAoC,CACxC,oFAAoF,CACrF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAA4B;IAC7D,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACpB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;IAEnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;YAC3B,OAAO,EAAE,sDAAsD;SAChE,CAAC,CAAC;QAGH,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAGD,MAAM,KAAK,EAAE,CAAC;QAGd,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAGD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC","sourcesContent":["import { confirm } from \"@inquirer/prompts\";\nimport { login } from \"../../login/login.js\";\nimport { getAuthToken } from \"../../login/tokens.js\";\nimport { printCriticalFailureToConsoleAndExit } from \"../output.js\";\n\nasync function fail() {\n await printCriticalFailureToConsoleAndExit(\n `You are not authenticated. Please run \\`zuplo login\\` to log in or set an api key.`\n );\n}\n\nexport async function authenticate(argv: { \"api-key\"?: string }) {\n if (argv[\"api-key\"]) {\n Object.assign(argv, { authToken: argv[\"api-key\"] });\n return;\n }\n\n const token = await getAuthToken();\n\n if (!token) {\n const result = await confirm({\n message: \"You are not authenticated. Would you like to log in?\",\n });\n\n // IF the user said no, then return an error\n if (!result) {\n return fail();\n }\n\n // Login\n await login();\n\n // Validate the login again\n const isValid = await getAuthToken();\n if (!isValid) {\n return fail();\n }\n }\n\n // Assign the token to the args\n Object.assign(argv, { authToken: token });\n}\n"]}
@@ -2,10 +2,12 @@ export declare const AUTH_SERVER_PORT = 57801;
2
2
  export declare const CLIENT_ID = "mYLGcH7kB4P0pw0HAk6GH7raRwYhSlW4";
3
3
  export declare const CALLBACK_URL = "http://localhost:57801/";
4
4
  export declare const AUTH0_DOMAIN = "auth.zuplo.com";
5
+ export declare const OAUTH_SCOPE = "openid email offline_access";
6
+ export declare const OAUTH_AUDIENCE = "https://dev.zuplo.com/";
5
7
  export declare const encode: (value: string) => string;
6
8
  export declare const decode: (value: string) => string;
7
9
  export declare const createRandomString: () => string;
8
10
  export declare const bufferToBase64UrlEncoded: (input: number[] | Uint8Array) => string;
9
11
  export declare const sha256: (s: string) => Promise<any>;
10
12
  export declare function login(): Promise<void>;
11
- //# sourceMappingURL=handler.d.ts.map
13
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/login/login.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AACtC,eAAO,MAAM,SAAS,qCAAqC,CAAC;AAC5D,eAAO,MAAM,YAAY,4BAA0C,CAAC;AACpE,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAC7C,eAAO,MAAM,WAAW,gCAAgC,CAAC;AACzD,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAEvD,eAAO,MAAM,MAAM,UAAW,MAAM,WAAgB,CAAC;AACrD,eAAO,MAAM,MAAM,UAAW,MAAM,WAAgB,CAAC;AAErD,eAAO,MAAM,kBAAkB,cAO9B,CAAC;AAOF,eAAO,MAAM,wBAAwB,UAAW,MAAM,EAAE,GAAG,UAAU,WAGpE,CAAC;AAEF,eAAO,MAAM,MAAM,MAAa,MAAM,iBAQrC,CAAC;AAEF,wBAAsB,KAAK,kBAsC1B"}
@@ -1,14 +1,12 @@
1
1
  import crypto from "node:crypto";
2
- import { existsSync, mkdirSync } from "node:fs";
3
- import { writeFile } from "node:fs/promises";
4
- import { join } from "node:path";
5
- import { ZUPLO_AUTH_FILE_NAME } from "../common/constants.js";
6
- import { ZUPLO_XDG_STATE_HOME } from "../common/xdg/lib.js";
7
2
  import { browserAuth } from "./server.js";
3
+ import { saveAuthState } from "./tokens.js";
8
4
  export const AUTH_SERVER_PORT = 57801;
9
5
  export const CLIENT_ID = "mYLGcH7kB4P0pw0HAk6GH7raRwYhSlW4";
10
6
  export const CALLBACK_URL = `http://localhost:${AUTH_SERVER_PORT}/`;
11
7
  export const AUTH0_DOMAIN = "auth.zuplo.com";
8
+ export const OAUTH_SCOPE = "openid email offline_access";
9
+ export const OAUTH_AUDIENCE = "https://dev.zuplo.com/";
12
10
  export const encode = (value) => btoa(value);
13
11
  export const decode = (value) => atob(value);
14
12
  export const createRandomString = () => {
@@ -40,8 +38,8 @@ export async function login() {
40
38
  authUrl.searchParams.set("code_challenge_method", "S256");
41
39
  authUrl.searchParams.set("client_id", CLIENT_ID);
42
40
  authUrl.searchParams.set("redirect_uri", CALLBACK_URL);
43
- authUrl.searchParams.set("scope", "openid profile email");
44
- authUrl.searchParams.set("audience", "https://dev.zuplo.com/");
41
+ authUrl.searchParams.set("scope", OAUTH_SCOPE);
42
+ authUrl.searchParams.set("audience", OAUTH_AUDIENCE);
45
43
  const params = await browserAuth(authUrl.toString());
46
44
  const code = params.get("code");
47
45
  if (code === null) {
@@ -60,11 +58,7 @@ export async function login() {
60
58
  },
61
59
  body: tokenParams,
62
60
  });
63
- const result = (await response.json());
64
- if (!existsSync(ZUPLO_XDG_STATE_HOME)) {
65
- mkdirSync(ZUPLO_XDG_STATE_HOME, { recursive: true });
66
- }
67
- const tokenPath = join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME);
68
- await writeFile(tokenPath, JSON.stringify(result));
61
+ const result = await response.json();
62
+ await saveAuthState(result);
69
63
  }
70
- //# sourceMappingURL=handler.js.map
64
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/login/login.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\nimport { browserAuth } from \"./server.js\";\nimport { OAuthResponse, saveAuthState } from \"./tokens.js\";\n\nexport const AUTH_SERVER_PORT = 57801;\nexport const CLIENT_ID = \"mYLGcH7kB4P0pw0HAk6GH7raRwYhSlW4\";\nexport const CALLBACK_URL = `http://localhost:${AUTH_SERVER_PORT}/`;\nexport const AUTH0_DOMAIN = \"auth.zuplo.com\";\nexport const OAUTH_SCOPE = \"openid email offline_access\";\nexport const OAUTH_AUDIENCE = \"https://dev.zuplo.com/\";\n\nexport const encode = (value: string) => btoa(value);\nexport const decode = (value: string) => atob(value);\n\nexport const createRandomString = () => {\n const charset =\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.\";\n let random = \"\";\n const randomValues = Array.from(crypto.getRandomValues(new Uint8Array(43)));\n randomValues.forEach((v) => (random += charset[v % charset.length]));\n return random;\n};\n\nconst urlEncodeB64 = (input: string) => {\n const b64Chars: { [index: string]: string } = { \"+\": \"-\", \"/\": \"_\", \"=\": \"\" };\n return input.replace(/[+/=]/g, (m: string) => b64Chars[m]);\n};\n\nexport const bufferToBase64UrlEncoded = (input: number[] | Uint8Array) => {\n const ie11SafeInput = new Uint8Array(input);\n return urlEncodeB64(btoa(String.fromCharCode(...Array.from(ie11SafeInput))));\n};\n\nexport const sha256 = async (s: string) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const digestOp: any = crypto.subtle.digest(\n { name: \"SHA-256\" },\n new TextEncoder().encode(s)\n );\n\n return await digestOp;\n};\n\nexport async function login() {\n const code_verifier = createRandomString();\n const code_challengeBuffer = await sha256(code_verifier);\n const code_challenge = bufferToBase64UrlEncoded(code_challengeBuffer);\n\n const authUrl = new URL(`https://${AUTH0_DOMAIN}/authorize`);\n\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"code_challenge\", code_challenge);\n authUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authUrl.searchParams.set(\"client_id\", CLIENT_ID);\n authUrl.searchParams.set(\"redirect_uri\", CALLBACK_URL);\n authUrl.searchParams.set(\"scope\", OAUTH_SCOPE);\n authUrl.searchParams.set(\"audience\", OAUTH_AUDIENCE);\n\n const params = await browserAuth(authUrl.toString());\n const code = params.get(\"code\");\n if (code === null) {\n throw new Error(\"No code\");\n }\n\n const tokenParams = new URLSearchParams();\n tokenParams.set(\"grant_type\", \"authorization_code\");\n tokenParams.set(\"client_id\", CLIENT_ID);\n tokenParams.set(\"code_verifier\", code_verifier);\n tokenParams.set(\"code\", code);\n tokenParams.set(\"redirect_uri\", CALLBACK_URL);\n\n const response = await fetch(`https://${AUTH0_DOMAIN}/oauth/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: tokenParams,\n });\n\n const result: OAuthResponse = await response.json();\n await saveAuthState(result);\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import http from "node:http";
2
2
  import opn from "open";
3
3
  import { printCriticalFailureToConsoleAndExit } from "../common/output.js";
4
- import { AUTH_SERVER_PORT } from "./handler.js";
5
4
  import { html } from "./html.js";
5
+ import { AUTH_SERVER_PORT } from "./login.js";
6
6
  export async function browserAuth(authorizationUrl) {
7
7
  let params;
8
8
  const handler = (req, res) => {
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/login/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,GAAG,MAAM,MAAM,CAAC;AACvB,OAAO,EAAE,oCAAoC,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,gBAAwB;IACxD,IAAI,MAAmC,CAAC;IAExC,MAAM,OAAO,GAAG,CAAC,GAAyB,EAAE,GAAwB,EAAE,EAAE;QACtE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAoB,gBAAgB,EAAE,CAAC,CAAC;QAErE,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC;YAC1B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACjD,CAAC;IACH,CAAC,CAAC;IAGF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAGnE,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAE5B,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,OAAO,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,UAAU,EAAE,GAAG,GAAG,EAAE,CAAC;YACvB,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,oCAAoC,CACxC,gFAAgF,CACjF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import http from \"node:http\";\nimport opn from \"open\";\nimport { printCriticalFailureToConsoleAndExit } from \"../common/output.js\";\nimport { AUTH_SERVER_PORT } from \"./handler.js\";\nimport { html } from \"./html.js\";\n\nexport async function browserAuth(authorizationUrl: string) {\n let params: URLSearchParams | undefined;\n\n const handler = (req: http.IncomingMessage, res: http.ServerResponse) => {\n if (!req.url) {\n throw new Error(\"Bad url\");\n }\n const url = new URL(req.url, `http://localhost:${AUTH_SERVER_PORT}`);\n // In here when the server gets a request\n if (url.pathname === \"/\") {\n params = url.searchParams;\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n } else {\n res.end(\"Unsupported route for login server.\");\n }\n };\n\n // Very simple webserver, using Nodes standard http module\n const server = http.createServer(handler).listen(AUTH_SERVER_PORT); // static local port\n\n // Open authorization url in preferred browser, works cross-platform\n await opn(authorizationUrl);\n\n let iterations = 0;\n while (params === undefined) {\n if (iterations++ > 600) {\n server.close();\n await printCriticalFailureToConsoleAndExit(\n \"Timed out waiting for login in the browser. Run the zuplo login command again.\"\n );\n } else {\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n }\n\n server.close();\n return params;\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/login/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,GAAG,MAAM,MAAM,CAAC;AACvB,OAAO,EAAE,oCAAoC,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,gBAAwB;IACxD,IAAI,MAAmC,CAAC;IAExC,MAAM,OAAO,GAAG,CAAC,GAAyB,EAAE,GAAwB,EAAE,EAAE;QACtE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,oBAAoB,gBAAgB,EAAE,CAAC,CAAC;QAErE,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC;YAC1B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACjD,CAAC;IACH,CAAC,CAAC;IAGF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAGnE,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAE5B,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,OAAO,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,UAAU,EAAE,GAAG,GAAG,EAAE,CAAC;YACvB,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,oCAAoC,CACxC,gFAAgF,CACjF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAK,EAAE,CAAC;IACf,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import http from \"node:http\";\nimport opn from \"open\";\nimport { printCriticalFailureToConsoleAndExit } from \"../common/output.js\";\nimport { html } from \"./html.js\";\nimport { AUTH_SERVER_PORT } from \"./login.js\";\n\nexport async function browserAuth(authorizationUrl: string) {\n let params: URLSearchParams | undefined;\n\n const handler = (req: http.IncomingMessage, res: http.ServerResponse) => {\n if (!req.url) {\n throw new Error(\"Bad url\");\n }\n const url = new URL(req.url, `http://localhost:${AUTH_SERVER_PORT}`);\n // In here when the server gets a request\n if (url.pathname === \"/\") {\n params = url.searchParams;\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(html);\n } else {\n res.end(\"Unsupported route for login server.\");\n }\n };\n\n // Very simple webserver, using Nodes standard http module\n const server = http.createServer(handler).listen(AUTH_SERVER_PORT); // static local port\n\n // Open authorization url in preferred browser, works cross-platform\n await opn(authorizationUrl);\n\n let iterations = 0;\n while (params === undefined) {\n if (iterations++ > 600) {\n server.close();\n await printCriticalFailureToConsoleAndExit(\n \"Timed out waiting for login in the browser. Run the zuplo login command again.\"\n );\n } else {\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n }\n\n server.close();\n return params;\n}\n"]}
@@ -0,0 +1,12 @@
1
+ export interface OAuthResponse {
2
+ refresh_token?: string;
3
+ access_token: string;
4
+ id_token: string;
5
+ expires_in: number;
6
+ token_type: string;
7
+ scope: string;
8
+ }
9
+ export declare function refreshAccessToken(refreshToken: string): Promise<OAuthResponse>;
10
+ export declare function getAuthToken(): Promise<string | undefined>;
11
+ export declare function saveAuthState(result: OAuthResponse): Promise<void>;
12
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/login/tokens.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,CAAC,CAkBxB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA8BhE;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAWxE"}
@@ -0,0 +1,64 @@
1
+ import { decodeJwt } from "jose";
2
+ import { existsSync, mkdirSync } from "node:fs";
3
+ import { readFile, writeFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import { ZUPLO_AUTH_FILE_NAME } from "../common/constants.js";
6
+ import { logger } from "../common/logger.js";
7
+ import { printDiagnosticsToConsole } from "../common/output.js";
8
+ import { ZUPLO_XDG_STATE_HOME } from "../common/xdg/lib.js";
9
+ import { AUTH0_DOMAIN, CLIENT_ID } from "./login.js";
10
+ export async function refreshAccessToken(refreshToken) {
11
+ const response = await fetch(`https://${AUTH0_DOMAIN}/oauth/token`, {
12
+ method: "POST",
13
+ headers: {
14
+ "Content-Type": "application/x-www-form-urlencoded",
15
+ },
16
+ body: new URLSearchParams({
17
+ grant_type: "refresh_token",
18
+ client_id: CLIENT_ID,
19
+ refresh_token: refreshToken,
20
+ }),
21
+ });
22
+ if (!response.ok) {
23
+ throw new Error(`Failed to refresh token: ${response.statusText}`);
24
+ }
25
+ return response.json();
26
+ }
27
+ export async function getAuthToken() {
28
+ if (!existsSync(join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME))) {
29
+ return;
30
+ }
31
+ const rawAuth = await readFile(join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME), "utf-8");
32
+ const authJson = JSON.parse(rawAuth);
33
+ const jwt = decodeJwt(authJson.access_token);
34
+ if (!jwt.exp || jwt.exp < Date.now() / 1000) {
35
+ logger.debug("Access token expired, attempting to get a new one");
36
+ if (authJson.refresh_token) {
37
+ try {
38
+ const newAuth = await refreshAccessToken(authJson.refresh_token);
39
+ await saveAuthState(newAuth);
40
+ return newAuth.access_token;
41
+ }
42
+ catch (error) {
43
+ logger.error(error, `Failed to refresh access token`);
44
+ return;
45
+ }
46
+ }
47
+ return;
48
+ }
49
+ return authJson.access_token;
50
+ }
51
+ export async function saveAuthState(result) {
52
+ try {
53
+ if (!existsSync(ZUPLO_XDG_STATE_HOME)) {
54
+ mkdirSync(ZUPLO_XDG_STATE_HOME, { recursive: true });
55
+ }
56
+ const tokenPath = join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME);
57
+ await writeFile(tokenPath, JSON.stringify(result));
58
+ }
59
+ catch (error) {
60
+ logger.error(error, "Failed to save auth state");
61
+ printDiagnosticsToConsole("Failed to save authorization state.");
62
+ }
63
+ }
64
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/login/tokens.ts"],"names":[],"mappings":"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","sourcesContent":["import { decodeJwt } from \"jose\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { ZUPLO_AUTH_FILE_NAME } from \"../common/constants.js\";\nimport { logger } from \"../common/logger.js\";\nimport { printDiagnosticsToConsole } from \"../common/output.js\";\nimport { ZUPLO_XDG_STATE_HOME } from \"../common/xdg/lib.js\";\nimport { AUTH0_DOMAIN, CLIENT_ID } from \"./login.js\";\n\nexport interface OAuthResponse {\n refresh_token?: string;\n access_token: string;\n id_token: string;\n expires_in: number;\n token_type: string;\n scope: string;\n}\n\n/**\n * Refreshes the access token using the provided refresh token.\n * @param refreshToken The refresh token to use for obtaining a new access token.\n * @returns A promise resolving to the new authentication state.\n */\nexport async function refreshAccessToken(\n refreshToken: string\n): Promise<OAuthResponse> {\n const response = await fetch(`https://${AUTH0_DOMAIN}/oauth/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n client_id: CLIENT_ID,\n refresh_token: refreshToken,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to refresh token: ${response.statusText}`);\n }\n\n return response.json();\n}\n\nexport async function getAuthToken(): Promise<string | undefined> {\n // The auth file doesn't exist.\n if (!existsSync(join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME))) {\n return;\n }\n\n const rawAuth = await readFile(\n join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME),\n \"utf-8\"\n );\n const authJson = JSON.parse(rawAuth);\n const jwt = decodeJwt(authJson.access_token);\n\n // The credentials have expired\n if (!jwt.exp || jwt.exp < Date.now() / 1000) {\n logger.debug(\"Access token expired, attempting to get a new one\");\n // If we have a refresh token try to refresh\n if (authJson.refresh_token) {\n try {\n const newAuth = await refreshAccessToken(authJson.refresh_token);\n await saveAuthState(newAuth);\n return newAuth.access_token;\n } catch (error) {\n logger.error(error, `Failed to refresh access token`);\n return;\n }\n }\n return;\n }\n return authJson.access_token;\n}\n\nexport async function saveAuthState(result: OAuthResponse): Promise<void> {\n try {\n if (!existsSync(ZUPLO_XDG_STATE_HOME)) {\n mkdirSync(ZUPLO_XDG_STATE_HOME, { recursive: true });\n }\n const tokenPath = join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME);\n await writeFile(tokenPath, JSON.stringify(result));\n } catch (error) {\n logger.error(error, \"Failed to save auth state\");\n printDiagnosticsToConsole(\"Failed to save authorization state.\");\n }\n}\n"]}
@@ -1 +1 @@
1
- {"root":["../src/cli.ts","../src/types.d.ts","../src/__tests__/archive-utils.test.ts","../src/__tests__/engine.test.ts","../src/__tests__/import-openapi-utils.test.ts","../src/__tests__/import-openapi.test.ts","../src/__tests__/oas-test-data.ts","../src/__tests__/outdated.test.ts","../src/__tests__/tsconfig-upgrader.test.ts","../src/build/handler.ts","../src/cmds/build.ts","../src/cmds/compile.ts","../src/cmds/convert.ts","../src/cmds/delete.ts","../src/cmds/deploy.ts","../src/cmds/dev.ts","../src/cmds/editor.ts","../src/cmds/link.ts","../src/cmds/list.ts","../src/cmds/login.ts","../src/cmds/test.ts","../src/cmds/project/import-openapi.ts","../src/cmds/project/index.ts","../src/cmds/project/update.ts","../src/cmds/tunnel/create.ts","../src/cmds/tunnel/delete.ts","../src/cmds/tunnel/describe.ts","../src/cmds/tunnel/index.ts","../src/cmds/tunnel/list.ts","../src/cmds/tunnel/rotate-token.ts","../src/cmds/tunnel/services/describe.ts","../src/cmds/tunnel/services/index.ts","../src/cmds/tunnel/services/update.ts","../src/cmds/variable/create.ts","../src/cmds/variable/index.ts","../src/cmds/variable/update.ts","../src/common/alias.ts","../src/common/args.ts","../src/common/constants.ts","../src/common/handler.ts","../src/common/logger.ts","../src/common/models.ts","../src/common/outdated.ts","../src/common/output.ts","../src/common/settings.ts","../src/common/worker-output.ts","../src/common/analytics/lib.ts","../src/common/api/lib.ts","../src/common/machine-id/lib.ts","../src/common/middleware/authentication.ts","../src/common/middleware/user-configuration.ts","../src/common/middleware/user-identification.ts","../src/common/upgraders/lib.ts","../src/common/upgraders/package-json-upgrader.ts","../src/common/upgraders/tsconfig-upgrader.ts","../src/common/upgraders/vscode-settings-json-upgrader.ts","../src/common/utils/box.ts","../src/common/utils/ports.ts","../src/common/utils/types.ts","../src/common/utils/urls.ts","../src/common/validators/file-system-validator.ts","../src/common/validators/lib.ts","../src/common/validators/project-name-validator.ts","../src/common/xdg/lib.ts","../src/compile/handler.ts","../src/convert/engine.ts","../src/convert/handler.ts","../src/convert/routes.legacy.ts","../src/delete/handler.ts","../src/delete/poll-deployment.ts","../src/deploy/archive.ts","../src/deploy/environments.ts","../src/deploy/file-upload.ts","../src/deploy/handler.ts","../src/deploy/poll-deployment.ts","../src/dev/handler.ts","../src/editor/handler.ts","../src/editor/assets/index-03352ce7.js","../src/editor/server/cors-plugin.ts","../src/editor/server/server.ts","../src/editor/server/xfs.ts","../src/link/handler.ts","../src/link/populate.ts","../src/list/handler.ts","../src/login/handler.ts","../src/login/html.ts","../src/login/server.ts","../src/project/import-openapi/handler.ts","../src/project/import-openapi/interfaces.ts","../src/project/import-openapi/utils.ts","../src/project/update/handler.ts","../src/test/esbuild-config.ts","../src/test/handler.ts","../src/test/invoke-test.ts","../src/test/esbuild-plugins/node-test-prep-plugin.ts","../src/tunnel/models.ts","../src/tunnel/create/handler.ts","../src/tunnel/delete/handler.ts","../src/tunnel/delete/poll-teardown-operation.ts","../src/tunnel/describe/handler.ts","../src/tunnel/list/handler.ts","../src/tunnel/rotate-token/handler.ts","../src/tunnel/services/describe/handler.ts","../src/tunnel/services/update/handler.ts","../src/tunnel/services/update/poll-provisioning-operations.ts","../src/variable/models.ts","../src/variable/create/handler.ts","../src/variable/update/handler.ts"],"version":"5.7.3"}
1
+ {"root":["../src/cli.ts","../src/types.d.ts","../src/__tests__/archive-utils.test.ts","../src/__tests__/engine.test.ts","../src/__tests__/import-openapi-utils.test.ts","../src/__tests__/import-openapi.test.ts","../src/__tests__/oas-test-data.ts","../src/__tests__/outdated.test.ts","../src/__tests__/tsconfig-upgrader.test.ts","../src/build/handler.ts","../src/cmds/build.ts","../src/cmds/compile.ts","../src/cmds/convert.ts","../src/cmds/delete.ts","../src/cmds/deploy.ts","../src/cmds/dev.ts","../src/cmds/editor.ts","../src/cmds/link.ts","../src/cmds/list.ts","../src/cmds/login.ts","../src/cmds/test.ts","../src/cmds/project/import-openapi.ts","../src/cmds/project/index.ts","../src/cmds/project/update.ts","../src/cmds/tunnel/create.ts","../src/cmds/tunnel/delete.ts","../src/cmds/tunnel/describe.ts","../src/cmds/tunnel/index.ts","../src/cmds/tunnel/list.ts","../src/cmds/tunnel/rotate-token.ts","../src/cmds/tunnel/services/describe.ts","../src/cmds/tunnel/services/index.ts","../src/cmds/tunnel/services/update.ts","../src/cmds/variable/create.ts","../src/cmds/variable/index.ts","../src/cmds/variable/update.ts","../src/common/alias.ts","../src/common/args.ts","../src/common/constants.ts","../src/common/handler.ts","../src/common/logger.ts","../src/common/models.ts","../src/common/outdated.ts","../src/common/output.ts","../src/common/settings.ts","../src/common/worker-output.ts","../src/common/analytics/lib.ts","../src/common/api/lib.ts","../src/common/machine-id/lib.ts","../src/common/middleware/authentication.ts","../src/common/middleware/user-configuration.ts","../src/common/middleware/user-identification.ts","../src/common/upgraders/lib.ts","../src/common/upgraders/package-json-upgrader.ts","../src/common/upgraders/tsconfig-upgrader.ts","../src/common/upgraders/vscode-settings-json-upgrader.ts","../src/common/utils/box.ts","../src/common/utils/ports.ts","../src/common/utils/types.ts","../src/common/utils/urls.ts","../src/common/validators/file-system-validator.ts","../src/common/validators/lib.ts","../src/common/validators/project-name-validator.ts","../src/common/xdg/lib.ts","../src/compile/handler.ts","../src/convert/engine.ts","../src/convert/handler.ts","../src/convert/routes.legacy.ts","../src/delete/handler.ts","../src/delete/poll-deployment.ts","../src/deploy/archive.ts","../src/deploy/environments.ts","../src/deploy/file-upload.ts","../src/deploy/handler.ts","../src/deploy/poll-deployment.ts","../src/dev/handler.ts","../src/editor/handler.ts","../src/editor/assets/index-03352ce7.js","../src/editor/server/cors-plugin.ts","../src/editor/server/server.ts","../src/editor/server/xfs.ts","../src/link/handler.ts","../src/link/populate.ts","../src/list/handler.ts","../src/login/html.ts","../src/login/login.ts","../src/login/server.ts","../src/login/tokens.ts","../src/project/import-openapi/handler.ts","../src/project/import-openapi/interfaces.ts","../src/project/import-openapi/utils.ts","../src/project/update/handler.ts","../src/test/esbuild-config.ts","../src/test/handler.ts","../src/test/invoke-test.ts","../src/test/esbuild-plugins/node-test-prep-plugin.ts","../src/tunnel/models.ts","../src/tunnel/create/handler.ts","../src/tunnel/delete/handler.ts","../src/tunnel/delete/poll-teardown-operation.ts","../src/tunnel/describe/handler.ts","../src/tunnel/list/handler.ts","../src/tunnel/rotate-token/handler.ts","../src/tunnel/services/describe/handler.ts","../src/tunnel/services/update/handler.ts","../src/tunnel/services/update/poll-provisioning-operations.ts","../src/variable/models.ts","../src/variable/create/handler.ts","../src/variable/update/handler.ts"],"version":"5.7.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuplo/cli",
3
- "version": "6.48.5",
3
+ "version": "6.48.7",
4
4
  "repository": "https://github.com/zuplo/zuplo",
5
5
  "author": "Zuplo, Inc.",
6
6
  "type": "module",
@@ -29,9 +29,9 @@
29
29
  "@opentelemetry/api": "^1.8.0",
30
30
  "@sentry/node": "^9.10.0",
31
31
  "@swc/core": "1.10.18",
32
- "@zuplo/core": "^6.48.5",
33
- "@zuplo/openapi-tools": "^6.48.5",
34
- "@zuplo/runtime": "^6.48.5",
32
+ "@zuplo/core": "^6.48.7",
33
+ "@zuplo/openapi-tools": "^6.48.7",
34
+ "@zuplo/runtime": "^6.48.7",
35
35
  "as-table": "^1.0.55",
36
36
  "chalk": "^5.3.0",
37
37
  "chokidar": "^3.5.3",
@@ -1 +0,0 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/login/handler.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AACtC,eAAO,MAAM,SAAS,qCAAqC,CAAC;AAC5D,eAAO,MAAM,YAAY,4BAA0C,CAAC;AACpE,eAAO,MAAM,YAAY,mBAAmB,CAAC;AAE7C,eAAO,MAAM,MAAM,UAAW,MAAM,WAAgB,CAAC;AACrD,eAAO,MAAM,MAAM,UAAW,MAAM,WAAgB,CAAC;AAErD,eAAO,MAAM,kBAAkB,cAO9B,CAAC;AAOF,eAAO,MAAM,wBAAwB,UAAW,MAAM,EAAE,GAAG,UAAU,WAGpE,CAAC;AAEF,eAAO,MAAM,MAAM,MAAa,MAAM,iBAQrC,CAAC;AAEF,wBAAsB,KAAK,kBA2C1B"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/login/handler.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport { writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { ZUPLO_AUTH_FILE_NAME } from \"../common/constants.js\";\nimport { ZUPLO_XDG_STATE_HOME } from \"../common/xdg/lib.js\";\nimport { browserAuth } from \"./server.js\";\n\nexport const AUTH_SERVER_PORT = 57801;\nexport const CLIENT_ID = \"mYLGcH7kB4P0pw0HAk6GH7raRwYhSlW4\";\nexport const CALLBACK_URL = `http://localhost:${AUTH_SERVER_PORT}/`;\nexport const AUTH0_DOMAIN = \"auth.zuplo.com\";\n\nexport const encode = (value: string) => btoa(value);\nexport const decode = (value: string) => atob(value);\n\nexport const createRandomString = () => {\n const charset =\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_~.\";\n let random = \"\";\n const randomValues = Array.from(crypto.getRandomValues(new Uint8Array(43)));\n randomValues.forEach((v) => (random += charset[v % charset.length]));\n return random;\n};\n\nconst urlEncodeB64 = (input: string) => {\n const b64Chars: { [index: string]: string } = { \"+\": \"-\", \"/\": \"_\", \"=\": \"\" };\n return input.replace(/[+/=]/g, (m: string) => b64Chars[m]);\n};\n\nexport const bufferToBase64UrlEncoded = (input: number[] | Uint8Array) => {\n const ie11SafeInput = new Uint8Array(input);\n return urlEncodeB64(btoa(String.fromCharCode(...Array.from(ie11SafeInput))));\n};\n\nexport const sha256 = async (s: string) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const digestOp: any = crypto.subtle.digest(\n { name: \"SHA-256\" },\n new TextEncoder().encode(s)\n );\n\n return await digestOp;\n};\n\nexport async function login() {\n const code_verifier = createRandomString();\n const code_challengeBuffer = await sha256(code_verifier);\n const code_challenge = bufferToBase64UrlEncoded(code_challengeBuffer);\n\n const authUrl = new URL(`https://${AUTH0_DOMAIN}/authorize`);\n\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"code_challenge\", code_challenge);\n authUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n authUrl.searchParams.set(\"client_id\", CLIENT_ID);\n authUrl.searchParams.set(\"redirect_uri\", CALLBACK_URL);\n authUrl.searchParams.set(\"scope\", \"openid profile email\");\n authUrl.searchParams.set(\"audience\", \"https://dev.zuplo.com/\");\n\n const params = await browserAuth(authUrl.toString());\n const code = params.get(\"code\");\n if (code === null) {\n throw new Error(\"No code\");\n }\n\n const tokenParams = new URLSearchParams();\n tokenParams.set(\"grant_type\", \"authorization_code\");\n tokenParams.set(\"client_id\", CLIENT_ID);\n tokenParams.set(\"code_verifier\", code_verifier);\n tokenParams.set(\"code\", code);\n tokenParams.set(\"redirect_uri\", CALLBACK_URL);\n\n const response = await fetch(`https://${AUTH0_DOMAIN}/oauth/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: tokenParams,\n });\n\n const result = (await response.json()) as { access_token: string };\n\n if (!existsSync(ZUPLO_XDG_STATE_HOME)) {\n mkdirSync(ZUPLO_XDG_STATE_HOME, { recursive: true });\n }\n const tokenPath = join(ZUPLO_XDG_STATE_HOME, ZUPLO_AUTH_FILE_NAME);\n await writeFile(tokenPath, JSON.stringify(result));\n}\n"]}