@supernovaio/cli-next 2.0.11 → 2.0.12

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,4 +1,4 @@
1
- import { Hook } from '@oclif/core';
2
- declare const hook: Hook<'prerun'>;
1
+ import { Hook } from "@oclif/core";
2
+ declare const hook: Hook<"prerun">;
3
3
  export default hook;
4
4
  //# sourceMappingURL=sentry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sentry.d.ts","sourceRoot":"","sources":["../../../src/hooks/prerun/sentry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAC,MAAM,aAAa,CAAA;AAMhC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,QAAQ,CAYxB,CAAA;AAED,eAAe,IAAI,CAAA"}
1
+ {"version":3,"file":"sentry.d.ts","sourceRoot":"","sources":["../../../src/hooks/prerun/sentry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAMlC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,QAAQ,CAYxB,CAAA;AAED,eAAe,IAAI,CAAA"}
@@ -1,15 +1,15 @@
1
- import * as Sentry from '@sentry/node';
2
- import { VaultService } from '../../services/index.js';
1
+ import * as Sentry from "@sentry/node";
2
+ import { VaultService } from "../../services/index.js";
3
3
  const hook = async function (opts) {
4
4
  const span = Sentry.getActiveSpan();
5
5
  if (span) {
6
- span.setAttribute('command', opts.Command.id);
6
+ span.setAttribute("command", opts.Command.id);
7
7
  span.updateName(opts.Command.id);
8
8
  const vaultService = new VaultService();
9
9
  const user = await vaultService.getLoggedInUser(process.env.SUPERNOVA_ENV);
10
10
  if (user) {
11
11
  Sentry.setUser({ id: user });
12
- span.setAttribute('user', user);
12
+ span.setAttribute("user", user);
13
13
  }
14
14
  }
15
15
  };
@@ -1 +1 @@
1
- {"version":3,"file":"sentry.js","sourceRoot":"","sources":["../../../src/hooks/prerun/sentry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAC,YAAY,EAAC,MAAM,yBAAyB,CAAA;AAGpD,MAAM,IAAI,GAAmB,KAAK,WAAW,IAAI;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,EAAE,CAAA;IACnC,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC7C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAChC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAA;QACvC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,aAA0B,CAAC,CAAA;QACvF,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,CAAC,OAAO,CAAC,EAAC,EAAE,EAAE,IAAI,EAAC,CAAC,CAAA;YAC1B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED,eAAe,IAAI,CAAA","sourcesContent":["import {Hook} from '@oclif/core'\nimport * as Sentry from '@sentry/node'\n\nimport {VaultService} from '../../services/index.js'\nimport {TargetEnv} from '../../types/index.js'\n\nconst hook: Hook<'prerun'> = async function (opts) {\n const span = Sentry.getActiveSpan()\n if (span) {\n span.setAttribute('command', opts.Command.id)\n span.updateName(opts.Command.id)\n const vaultService = new VaultService()\n const user = await vaultService.getLoggedInUser(process.env.SUPERNOVA_ENV as TargetEnv)\n if (user) {\n Sentry.setUser({id: user})\n span.setAttribute('user', user)\n }\n }\n}\n\nexport default hook\n"]}
1
+ {"version":3,"file":"sentry.js","sourceRoot":"","sources":["../../../src/hooks/prerun/sentry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAGtD,MAAM,IAAI,GAAmB,KAAK,WAAW,IAAI;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,EAAE,CAAA;IACnC,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC7C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAChC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAA;QACvC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,aAA0B,CAAC,CAAA;QACvF,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;YAC5B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED,eAAe,IAAI,CAAA","sourcesContent":["import { Hook } from \"@oclif/core\"\nimport * as Sentry from \"@sentry/node\"\n\nimport { VaultService } from \"../../services/index.js\"\nimport { TargetEnv } from \"../../types/index.js\"\n\nconst hook: Hook<\"prerun\"> = async function (opts) {\n const span = Sentry.getActiveSpan()\n if (span) {\n span.setAttribute(\"command\", opts.Command.id)\n span.updateName(opts.Command.id)\n const vaultService = new VaultService()\n const user = await vaultService.getLoggedInUser(process.env.SUPERNOVA_ENV as TargetEnv)\n if (user) {\n Sentry.setUser({ id: user })\n span.setAttribute(\"user\", user)\n }\n }\n}\n\nexport default hook\n"]}
@@ -9,7 +9,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  };
10
10
  import { SentryTraced } from "@sentry/nestjs";
11
11
  import { jwtDecode } from "jwt-decode";
12
- import * as keytar from "keytar";
12
+ import keytar from "keytar";
13
13
  import * as fs from "node:fs";
14
14
  import * as os from "node:os";
15
15
  import path from "node:path";
@@ -1 +1 @@
1
- {"version":3,"file":"vault.service.js","sourceRoot":"","sources":["../../src/services/vault.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { SentryTraced } from \"@sentry/nestjs\"\nimport { jwtDecode } from \"jwt-decode\"\nimport * as keytar from \"keytar\"\nimport * as fs from \"node:fs\"\nimport * as os from \"node:os\"\nimport path from \"node:path\"\n\nimport { EnvTokens, EnvTokensSchema, TargetEnv, Tokens } from \"../types/login.js\"\nimport { NotAuthorizedError } from \"../types/not-authorized.error.js\"\nimport { AuthService } from \"./auth.service.js\"\n\nexport interface IVault {\n deletePassword: (serviceName: string, account: string) => Promise<void>\n getPassword: (serviceName: string, account: string) => Promise<null | string>\n setPassword: (serviceName: string, account: string, password: string) => Promise<void>\n}\n\nexport class KeytarVault implements IVault {\n async deletePassword(serviceName: string, account: string): Promise<void> {\n await keytar.deletePassword(serviceName, account)\n }\n\n async getPassword(serviceName: string, account: string): Promise<null | string> {\n return keytar.getPassword(serviceName, account)\n }\n\n async setPassword(serviceName: string, account: string, password: string): Promise<void> {\n await keytar.setPassword(serviceName, account, password)\n }\n}\n\nexport class VaultService {\n private readonly serviceName = \"Supernova\"\n\n constructor(\n private readonly authService: AuthService = new AuthService(),\n private readonly vault: IVault = new KeytarVault(),\n ) {}\n\n @SentryTraced()\n public async deleteTokensFromVault(env: TargetEnv) {\n try {\n await this.vault.deletePassword(this.serviceName, `${env}_access_token`)\n await this.vault.deletePassword(this.serviceName, `${env}_refresh_token`)\n } catch {\n this.storeTokensInFile(env, null)\n }\n }\n\n @SentryTraced()\n public async getLoggedInUser(env: TargetEnv): Promise<string | undefined> {\n try {\n const tokens = await this.getTokensFromVault(env)\n const decoded = jwtDecode<{ sub?: string }>(tokens.accessToken)\n return decoded.sub\n } catch {\n return undefined\n }\n }\n\n @SentryTraced()\n public getTokensFromFile(env: TargetEnv): Tokens | undefined {\n const filePath = this.tokensFilePath()\n\n if (!fs.existsSync(filePath)) {\n return undefined\n }\n\n const fileContent = fs.readFileSync(filePath, \"utf8\")\n const data = JSON.parse(fileContent)\n return data[env] ?? {}\n }\n\n @SentryTraced()\n public async getTokensFromVault(env: TargetEnv): Promise<Tokens> {\n if (process.env.SUPERNOVA_TOKEN) {\n return { accessToken: process.env.SUPERNOVA_TOKEN }\n }\n\n let accessToken: string | undefined\n let refreshToken: string | undefined\n try {\n accessToken = (await this.vault.getPassword(this.serviceName, `${env}_access_token`)) ?? undefined\n refreshToken = (await this.vault.getPassword(this.serviceName, `${env}_refresh_token`)) ?? undefined\n } catch {\n console.log(\"Error, fall back to file storage\")\n const tokens = this.getTokensFromFile(env)\n if (tokens) {\n accessToken = tokens.accessToken\n refreshToken = tokens.refreshToken\n }\n }\n\n if (!accessToken) {\n throw new NotAuthorizedError()\n }\n\n const freshTokens = refreshToken ? await this.refreshTokens(env, accessToken, refreshToken) : undefined\n if (freshTokens) {\n return freshTokens\n }\n\n return { accessToken, refreshToken }\n }\n\n @SentryTraced()\n public async refreshTokens(env: TargetEnv, accessToken: string, refreshToken: string): Promise<Tokens | undefined> {\n const decoded = jwtDecode<{ exp?: number }>(accessToken)\n const currentTime = Math.floor(Date.now() / 1000)\n if (decoded.exp && decoded.exp < currentTime + 300) {\n const freshTokens = await this.authService.refreshToken(env, refreshToken)\n if (!freshTokens) {\n await this.deleteTokensFromVault(env)\n throw new NotAuthorizedError()\n }\n\n await this.storeTokensToVault(freshTokens, env)\n return freshTokens\n }\n\n return undefined\n }\n\n @SentryTraced()\n public storeTokensInFile(env: TargetEnv, tokens: null | Tokens) {\n const supernovaDir = this.supernovaDir()\n const filePath = path.join(supernovaDir, \"tokens.json\")\n\n if (!fs.existsSync(supernovaDir)) {\n fs.mkdirSync(supernovaDir, { recursive: true })\n }\n\n let data: EnvTokens = {} as EnvTokens\n if (fs.existsSync(filePath)) {\n const fileContent = fs.readFileSync(filePath, \"utf8\")\n data = EnvTokensSchema.parse(JSON.parse(fileContent))\n }\n\n if (tokens) data[env] = tokens\n else delete data[env]\n\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), \"utf8\")\n }\n\n @SentryTraced()\n public async storeTokensToVault({ accessToken, refreshToken }: Tokens, env: TargetEnv) {\n try {\n await this.vault.setPassword(this.serviceName, `${env}_access_token`, accessToken)\n if (refreshToken) {\n await this.vault.setPassword(this.serviceName, `${env}_refresh_token`, refreshToken)\n }\n } catch {\n this.storeTokensInFile(env, { accessToken, refreshToken })\n }\n }\n\n public supernovaDir(): string {\n const homeDir = os.homedir()\n return path.join(homeDir, \".supernova\")\n }\n\n public tokensFilePath(): string {\n const homeDir = this.supernovaDir()\n return path.join(homeDir, \"tokens.json\")\n }\n}\n"]}
1
+ {"version":3,"file":"vault.service.js","sourceRoot":"","sources":["../../src/services/vault.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAa,eAAe,EAAqB,MAAM,mBAAmB,CAAA;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAQ/C,MAAM,OAAO,WAAW;IACtB,KAAK,CAAC,cAAc,CAAC,WAAmB,EAAE,OAAe;QACvD,MAAM,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;IACnD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,WAAmB,EAAE,OAAe;QACpD,OAAO,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;IACjD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,WAAmB,EAAE,OAAe,EAAE,QAAgB;QACtE,MAAM,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;IAC1D,CAAC;CACF;AAED,MAAM,OAAO,YAAY;IAIJ;IACA;IAJF,WAAW,GAAG,WAAW,CAAA;IAE1C,YACmB,cAA2B,IAAI,WAAW,EAAE,EAC5C,QAAgB,IAAI,WAAW,EAAE;QADjC,gBAAW,GAAX,WAAW,CAAiC;QAC5C,UAAK,GAAL,KAAK,CAA4B;IACjD,CAAC;IAGS,AAAN,KAAK,CAAC,qBAAqB,CAAC,GAAc;QAC/C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,eAAe,CAAC,CAAA;YACxE,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,gBAAgB,CAAC,CAAA;QAC3E,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAGY,AAAN,KAAK,CAAC,eAAe,CAAC,GAAc;QACzC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAA;YACjD,MAAM,OAAO,GAAG,SAAS,CAAmB,MAAM,CAAC,WAAW,CAAC,CAAA;YAC/D,OAAO,OAAO,CAAC,GAAG,CAAA;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IAGM,iBAAiB,CAAC,GAAc;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAA;QAEtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QACpC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;IACxB,CAAC;IAGY,AAAN,KAAK,CAAC,kBAAkB,CAAC,GAAc;QAC5C,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;YAChC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAA;QACrD,CAAC;QAED,IAAI,WAA+B,CAAA;QACnC,IAAI,YAAgC,CAAA;QACpC,IAAI,CAAC;YACH,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,eAAe,CAAC,CAAC,IAAI,SAAS,CAAA;YAClG,YAAY,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,gBAAgB,CAAC,CAAC,IAAI,SAAS,CAAA;QACtG,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAA;YAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAA;YAC1C,IAAI,MAAM,EAAE,CAAC;gBACX,WAAW,GAAG,MAAM,CAAC,WAAW,CAAA;gBAChC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAA;YACpC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,kBAAkB,EAAE,CAAA;QAChC,CAAC;QAED,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACvG,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,WAAW,CAAA;QACpB,CAAC;QAED,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAA;IACtC,CAAC;IAGY,AAAN,KAAK,CAAC,aAAa,CAAC,GAAc,EAAE,WAAmB,EAAE,YAAoB;QAClF,MAAM,OAAO,GAAG,SAAS,CAAmB,WAAW,CAAC,CAAA;QACxD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;QACjD,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,GAAG,WAAW,GAAG,GAAG,EAAE,CAAC;YACnD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;YAC1E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAA;gBACrC,MAAM,IAAI,kBAAkB,EAAE,CAAA;YAChC,CAAC;YAED,MAAM,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAA;YAC/C,OAAO,WAAW,CAAA;QACpB,CAAC;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;IAGM,iBAAiB,CAAC,GAAc,EAAE,MAAqB;QAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,CAAA;QAEvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACjD,CAAC;QAED,IAAI,IAAI,GAAc,EAAe,CAAA;QACrC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YACrD,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAA;QACvD,CAAC;QAED,IAAI,MAAM;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAA;;YACzB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;QAErB,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;IACnE,CAAC;IAGY,AAAN,KAAK,CAAC,kBAAkB,CAAC,EAAE,WAAW,EAAE,YAAY,EAAU,EAAE,GAAc;QACnF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,eAAe,EAAE,WAAW,CAAC,CAAA;YAClF,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,GAAG,gBAAgB,EAAE,YAAY,CAAC,CAAA;YACtF,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC;IAEM,YAAY;QACjB,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;QAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IACzC,CAAC;IAEM,cAAc;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;QACnC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;IAC1C,CAAC;CACF;AA7Hc;IADZ,YAAY,EAAE;;;;yDAQd;AAGY;IADZ,YAAY,EAAE;;;;mDASd;AAGM;IADN,YAAY,EAAE;;;;qDAWd;AAGY;IADZ,YAAY,EAAE;;;;sDA8Bd;AAGY;IADZ,YAAY,EAAE;;;;iDAgBd;AAGM;IADN,YAAY,EAAE;;;;qDAmBd;AAGY;IADZ,YAAY,EAAE;;;;sDAUd","sourcesContent":["import { SentryTraced } from \"@sentry/nestjs\"\nimport { jwtDecode } from \"jwt-decode\"\nimport keytar from \"keytar\"\nimport * as fs from \"node:fs\"\nimport * as os from \"node:os\"\nimport path from \"node:path\"\n\nimport { EnvTokens, EnvTokensSchema, TargetEnv, Tokens } from \"../types/login.js\"\nimport { NotAuthorizedError } from \"../types/not-authorized.error.js\"\nimport { AuthService } from \"./auth.service.js\"\n\nexport interface IVault {\n deletePassword: (serviceName: string, account: string) => Promise<void>\n getPassword: (serviceName: string, account: string) => Promise<null | string>\n setPassword: (serviceName: string, account: string, password: string) => Promise<void>\n}\n\nexport class KeytarVault implements IVault {\n async deletePassword(serviceName: string, account: string): Promise<void> {\n await keytar.deletePassword(serviceName, account)\n }\n\n async getPassword(serviceName: string, account: string): Promise<null | string> {\n return keytar.getPassword(serviceName, account)\n }\n\n async setPassword(serviceName: string, account: string, password: string): Promise<void> {\n await keytar.setPassword(serviceName, account, password)\n }\n}\n\nexport class VaultService {\n private readonly serviceName = \"Supernova\"\n\n constructor(\n private readonly authService: AuthService = new AuthService(),\n private readonly vault: IVault = new KeytarVault(),\n ) {}\n\n @SentryTraced()\n public async deleteTokensFromVault(env: TargetEnv) {\n try {\n await this.vault.deletePassword(this.serviceName, `${env}_access_token`)\n await this.vault.deletePassword(this.serviceName, `${env}_refresh_token`)\n } catch {\n this.storeTokensInFile(env, null)\n }\n }\n\n @SentryTraced()\n public async getLoggedInUser(env: TargetEnv): Promise<string | undefined> {\n try {\n const tokens = await this.getTokensFromVault(env)\n const decoded = jwtDecode<{ sub?: string }>(tokens.accessToken)\n return decoded.sub\n } catch {\n return undefined\n }\n }\n\n @SentryTraced()\n public getTokensFromFile(env: TargetEnv): Tokens | undefined {\n const filePath = this.tokensFilePath()\n\n if (!fs.existsSync(filePath)) {\n return undefined\n }\n\n const fileContent = fs.readFileSync(filePath, \"utf8\")\n const data = JSON.parse(fileContent)\n return data[env] ?? {}\n }\n\n @SentryTraced()\n public async getTokensFromVault(env: TargetEnv): Promise<Tokens> {\n if (process.env.SUPERNOVA_TOKEN) {\n return { accessToken: process.env.SUPERNOVA_TOKEN }\n }\n\n let accessToken: string | undefined\n let refreshToken: string | undefined\n try {\n accessToken = (await this.vault.getPassword(this.serviceName, `${env}_access_token`)) ?? undefined\n refreshToken = (await this.vault.getPassword(this.serviceName, `${env}_refresh_token`)) ?? undefined\n } catch {\n console.log(\"Error, fall back to file storage\")\n const tokens = this.getTokensFromFile(env)\n if (tokens) {\n accessToken = tokens.accessToken\n refreshToken = tokens.refreshToken\n }\n }\n\n if (!accessToken) {\n throw new NotAuthorizedError()\n }\n\n const freshTokens = refreshToken ? await this.refreshTokens(env, accessToken, refreshToken) : undefined\n if (freshTokens) {\n return freshTokens\n }\n\n return { accessToken, refreshToken }\n }\n\n @SentryTraced()\n public async refreshTokens(env: TargetEnv, accessToken: string, refreshToken: string): Promise<Tokens | undefined> {\n const decoded = jwtDecode<{ exp?: number }>(accessToken)\n const currentTime = Math.floor(Date.now() / 1000)\n if (decoded.exp && decoded.exp < currentTime + 300) {\n const freshTokens = await this.authService.refreshToken(env, refreshToken)\n if (!freshTokens) {\n await this.deleteTokensFromVault(env)\n throw new NotAuthorizedError()\n }\n\n await this.storeTokensToVault(freshTokens, env)\n return freshTokens\n }\n\n return undefined\n }\n\n @SentryTraced()\n public storeTokensInFile(env: TargetEnv, tokens: null | Tokens) {\n const supernovaDir = this.supernovaDir()\n const filePath = path.join(supernovaDir, \"tokens.json\")\n\n if (!fs.existsSync(supernovaDir)) {\n fs.mkdirSync(supernovaDir, { recursive: true })\n }\n\n let data: EnvTokens = {} as EnvTokens\n if (fs.existsSync(filePath)) {\n const fileContent = fs.readFileSync(filePath, \"utf8\")\n data = EnvTokensSchema.parse(JSON.parse(fileContent))\n }\n\n if (tokens) data[env] = tokens\n else delete data[env]\n\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), \"utf8\")\n }\n\n @SentryTraced()\n public async storeTokensToVault({ accessToken, refreshToken }: Tokens, env: TargetEnv) {\n try {\n await this.vault.setPassword(this.serviceName, `${env}_access_token`, accessToken)\n if (refreshToken) {\n await this.vault.setPassword(this.serviceName, `${env}_refresh_token`, refreshToken)\n }\n } catch {\n this.storeTokensInFile(env, { accessToken, refreshToken })\n }\n }\n\n public supernovaDir(): string {\n const homeDir = os.homedir()\n return path.join(homeDir, \".supernova\")\n }\n\n public tokensFilePath(): string {\n const homeDir = this.supernovaDir()\n return path.join(homeDir, \"tokens.json\")\n }\n}\n"]}
@@ -530,5 +530,5 @@
530
530
  ]
531
531
  }
532
532
  },
533
- "version": "2.0.10"
533
+ "version": "2.0.12"
534
534
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@supernovaio/cli-next",
3
3
  "description": "Supernova.io Command Line Interface",
4
- "version": "2.0.11",
4
+ "version": "2.0.12",
5
5
  "author": "Supernova.io",
6
6
  "bin": {
7
7
  "supernova-next": "./bin/run"