Skip to content

Commit ab1e201

Browse files
refactor: code split and cleanup
1 parent b336446 commit ab1e201

File tree

10 files changed

+524
-616
lines changed

10 files changed

+524
-616
lines changed

src/index.ts

Lines changed: 42 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
import {
2-
decryptEnvSecrets,
3-
digest,
4-
encryptEnvSecrets,
5-
reconstructPrivateKey,
6-
unwrapEnvKeys,
7-
} from "./utils/crypto";
1+
82
import axios from "axios";
93
import {
104
App,
@@ -21,8 +15,10 @@ import {
2115
normalizeKey,
2216
resolveSecretReferences,
2317
SecretFetcher,
24-
} from "./utils/secrets";
18+
} from "./utils/secretReferencing";
2519
import { LIB_VERSION } from "../version";
20+
import { reconstructPrivateKey, unwrapEnvKeys, digest, decryptEnvSecrets, encryptEnvSecrets } from "./utils/crypto";
21+
2622

2723
const DEFAULT_HOST = "https://console.phase.dev";
2824

@@ -156,128 +152,82 @@ export default class Phase {
156152
async get(options: GetSecretOptions): Promise<Secret[]> {
157153
return new Promise<Secret[]>(async (resolve, reject) => {
158154
const cache = new Map<string, string>();
159-
155+
160156
const app = this.apps.find((app) => app.id === options.appId);
161157
if (!app) {
162-
reject("Invalid app id");
163-
return;
158+
return reject("Invalid app id");
164159
}
165-
166-
const env = app?.environments.find(
167-
(env) => env.name.toLowerCase() === options.envName.toLowerCase()
160+
161+
const env = app.environments.find(
162+
(e) => e.name.toLowerCase() === options.envName.toLowerCase()
168163
);
169164
if (!env) {
170-
reject(`Invalid environment name: ${options.envName}`);
171-
return;
165+
return reject(`Invalid environment name: ${options.envName}`);
172166
}
173-
167+
174168
try {
175169
const queryHeaders = {
176170
environment: env.id,
177171
path: options.path || "/",
178-
keyDigest: null,
172+
keyDigest: options.key
173+
? await digest(options.key.toUpperCase(), env.salt)
174+
: null,
179175
};
180-
181-
if (options.key) {
182-
const keyDigest = await digest(options.key.toUpperCase(), env.salt);
183-
queryHeaders.keyDigest = keyDigest;
184-
}
185-
186-
const res = await axios({
187-
url: `${this.host}/service/secrets/`,
188-
method: "get",
189-
headers: {
190-
...queryHeaders,
191-
...this.getAuthHeaders(),
192-
},
176+
177+
const res = await axios.get(`${this.host}/service/secrets/`, {
178+
headers: { ...queryHeaders, ...this.getAuthHeaders() },
193179
});
194-
195-
let secretsToDecrypt = res.data
196-
.filter((secret: Secret) =>
197-
options.path ? secret.path === options.path : true
198-
)
199-
.filter((secret: Secret) =>
200-
options.tags
201-
? secret.tags.some((tag) => options.tags?.includes(tag))
202-
: true
203-
);
204-
205-
// Decrypt fetched secrets
180+
181+
const secretsToDecrypt = res.data.filter(
182+
(secret: Secret) =>
183+
(!options.path || secret.path === options.path) &&
184+
(!options.tags || secret.tags.some((tag) => options.tags?.includes(tag)))
185+
);
186+
206187
const secrets = await decryptEnvSecrets(secretsToDecrypt, env.keypair);
207-
188+
189+
// Create lookup map
208190
const secretLookup = new Map<string, Secret>(
209191
secrets.map((s) => [normalizeKey(env.name, s.path, s.key), s])
210192
);
211-
212-
// 🛠 Fetch local and cross-environment secrets as needed
213-
const fetcher: SecretFetcher = async (
214-
envName: string,
215-
path: string,
216-
key: string
217-
) => {
193+
194+
// Fetcher for resolving references
195+
const fetcher: SecretFetcher = async (envName, path, key) => {
218196
const cacheKey = normalizeKey(envName, path, key);
219-
197+
220198
if (cache.has(cacheKey)) {
221-
return {
222-
id: "",
223-
key,
224-
value: cache.get(cacheKey)!,
225-
comment: "",
226-
environment: envName,
227-
folder: undefined,
228-
path,
229-
tags: [],
230-
keyDigest: "",
231-
createdAt: undefined,
232-
updatedAt: new Date().toISOString(),
233-
version: 1,
234-
};
199+
return { id: "", key, value: cache.get(cacheKey)!, comment: "", environment: envName, folder: undefined, path, tags: [], keyDigest: "", createdAt: undefined, updatedAt: new Date().toISOString(), version: 1 };
235200
}
236-
201+
237202
let secret = secretLookup.get(cacheKey);
238-
239203
if (!secret) {
240-
// 🔄 Fetch cross-environment secret dynamically
241-
const crossEnvSecrets = await this.get({
242-
...options,
243-
envName,
244-
path,
245-
tags: undefined,
246-
});
247-
204+
const crossEnvSecrets = await this.get({ ...options, envName, path, tags: undefined });
248205
secret = crossEnvSecrets.find((s) => s.key === key);
249-
if (!secret)
250-
throw new Error(`Missing secret: ${envName}:${path}:${key}`);
251-
252-
// Store for future lookups
206+
if (!secret) throw new Error(`Missing secret: ${envName}:${path}:${key}`);
207+
253208
secretLookup.set(cacheKey, secret);
254209
}
255-
210+
256211
cache.set(cacheKey, secret.value);
257212
return secret;
258213
};
259-
260-
// Resolve references in secret values
214+
215+
// Resolve references
261216
const resolvedSecrets = await Promise.all(
262217
secrets.map(async (secret) => ({
263218
...secret,
264-
value: await resolveSecretReferences(
265-
secret.value,
266-
options.envName,
267-
options.path || "/",
268-
fetcher,
269-
cache
270-
),
219+
value: await resolveSecretReferences(secret.value, options.envName, options.path || "/", fetcher, cache),
271220
}))
272221
);
273-
222+
274223
resolve(resolvedSecrets);
275224
} catch (err) {
276-
console.log(`Error fetching secrets: ${err}`);
225+
console.error(`Error fetching secrets: ${err}`);
277226
reject(err);
278227
}
279228
});
280229
}
230+
281231

282232

283233

0 commit comments

Comments
 (0)