@keywaysh/cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ import {
2
+ clearAuth,
3
+ getAuthFilePath,
4
+ getStoredAuth,
5
+ saveAuthToken
6
+ } from "./chunk-F4C46224.js";
7
+ export {
8
+ clearAuth,
9
+ getAuthFilePath,
10
+ getStoredAuth,
11
+ saveAuthToken
12
+ };
@@ -0,0 +1,102 @@
1
+ // src/utils/auth.ts
2
+ import Conf from "conf";
3
+ import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
4
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync } from "fs";
5
+ import { join } from "path";
6
+ import { homedir } from "os";
7
+ var store = new Conf({
8
+ projectName: "keyway",
9
+ configName: "config",
10
+ fileMode: 384
11
+ });
12
+ var KEY_DIR = join(homedir(), ".keyway");
13
+ var KEY_FILE = join(KEY_DIR, ".key");
14
+ function getOrCreateEncryptionKey() {
15
+ if (!existsSync(KEY_DIR)) {
16
+ mkdirSync(KEY_DIR, { recursive: true, mode: 448 });
17
+ }
18
+ if (existsSync(KEY_FILE)) {
19
+ const keyHex2 = readFileSync(KEY_FILE, "utf-8").trim();
20
+ if (keyHex2.length === 64) {
21
+ return Buffer.from(keyHex2, "hex");
22
+ }
23
+ }
24
+ const key = randomBytes(32);
25
+ const keyHex = key.toString("hex");
26
+ writeFileSync(KEY_FILE, keyHex, { mode: 384 });
27
+ try {
28
+ chmodSync(KEY_FILE, 384);
29
+ } catch {
30
+ }
31
+ return key;
32
+ }
33
+ function encryptToken(token) {
34
+ const key = getOrCreateEncryptionKey();
35
+ const iv = randomBytes(16);
36
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
37
+ const encrypted = Buffer.concat([cipher.update(token, "utf8"), cipher.final()]);
38
+ const authTag = cipher.getAuthTag();
39
+ return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted.toString("hex")}`;
40
+ }
41
+ function decryptToken(encryptedData) {
42
+ const key = getOrCreateEncryptionKey();
43
+ const parts = encryptedData.split(":");
44
+ if (parts.length !== 3) {
45
+ throw new Error("Invalid encrypted token format");
46
+ }
47
+ const iv = Buffer.from(parts[0], "hex");
48
+ const authTag = Buffer.from(parts[1], "hex");
49
+ const encrypted = Buffer.from(parts[2], "hex");
50
+ const decipher = createDecipheriv("aes-256-gcm", key, iv);
51
+ decipher.setAuthTag(authTag);
52
+ const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
53
+ return decrypted.toString("utf8");
54
+ }
55
+ function isExpired(auth) {
56
+ if (!auth.expiresAt) return false;
57
+ const expires = Date.parse(auth.expiresAt);
58
+ if (Number.isNaN(expires)) return false;
59
+ return expires <= Date.now();
60
+ }
61
+ async function getStoredAuth() {
62
+ const encryptedData = store.get("auth");
63
+ if (!encryptedData) {
64
+ return null;
65
+ }
66
+ try {
67
+ const decrypted = decryptToken(encryptedData);
68
+ const auth = JSON.parse(decrypted);
69
+ if (isExpired(auth)) {
70
+ clearAuth();
71
+ return null;
72
+ }
73
+ return auth;
74
+ } catch {
75
+ console.error("Failed to decrypt stored auth, clearing...");
76
+ clearAuth();
77
+ return null;
78
+ }
79
+ }
80
+ async function saveAuthToken(token, meta) {
81
+ const auth = {
82
+ keywayToken: token,
83
+ githubLogin: meta?.githubLogin,
84
+ expiresAt: meta?.expiresAt,
85
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
86
+ };
87
+ const encrypted = encryptToken(JSON.stringify(auth));
88
+ store.set("auth", encrypted);
89
+ }
90
+ function clearAuth() {
91
+ store.delete("auth");
92
+ }
93
+ function getAuthFilePath() {
94
+ return store.path;
95
+ }
96
+
97
+ export {
98
+ getStoredAuth,
99
+ saveAuthToken,
100
+ clearAuth,
101
+ getAuthFilePath
102
+ };