refactor(certificates): move to core package (#4686)
This commit is contained in:
74
packages/core/src/infrastructure/certificates/files/index.ts
Normal file
74
packages/core/src/infrastructure/certificates/files/index.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { X509Certificate } from "node:crypto";
|
||||
import fsSync from "node:fs";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { rootCertificates } from "node:tls";
|
||||
|
||||
const getCertificateFolder = () => {
|
||||
if (process.env.NODE_ENV !== "production") return process.env.LOCAL_CERTIFICATE_PATH;
|
||||
return process.env.LOCAL_CERTIFICATE_PATH ?? path.join("/appdata", "trusted-certificates");
|
||||
};
|
||||
|
||||
export const loadCustomRootCertificatesAsync = async () => {
|
||||
const folder = getCertificateFolder();
|
||||
|
||||
if (!folder) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!fsSync.existsSync(folder)) {
|
||||
await fs.mkdir(folder, { recursive: true });
|
||||
}
|
||||
|
||||
const dirContent = await fs.readdir(folder);
|
||||
return await Promise.all(
|
||||
dirContent
|
||||
.filter((file) => file.endsWith(".crt") || file.endsWith(".pem"))
|
||||
.map(async (file) => ({
|
||||
content: await fs.readFile(path.join(folder, file), "utf8"),
|
||||
fileName: file,
|
||||
})),
|
||||
);
|
||||
};
|
||||
|
||||
export const getAllTrustedCertificatesAsync = async () => {
|
||||
const customCertificates = await loadCustomRootCertificatesAsync();
|
||||
return rootCertificates.concat(customCertificates.map((cert) => cert.content));
|
||||
};
|
||||
|
||||
export const removeCustomRootCertificateAsync = async (fileName: string) => {
|
||||
const folder = getCertificateFolder();
|
||||
if (!folder) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const existingFiles = await fs.readdir(folder, { withFileTypes: true });
|
||||
if (!existingFiles.some((file) => file.isFile() && file.name === fileName)) {
|
||||
throw new Error(`File ${fileName} does not exist`);
|
||||
}
|
||||
|
||||
const fullPath = path.join(folder, fileName);
|
||||
const content = await fs.readFile(fullPath, "utf8");
|
||||
|
||||
await fs.rm(fullPath);
|
||||
try {
|
||||
return new X509Certificate(content);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const addCustomRootCertificateAsync = async (fileName: string, content: string) => {
|
||||
const folder = getCertificateFolder();
|
||||
if (!folder) {
|
||||
throw new Error(
|
||||
"When you want to use custom certificates locally you need to set LOCAL_CERTIFICATE_PATH to an absolute path",
|
||||
);
|
||||
}
|
||||
|
||||
if (fileName.includes("/")) {
|
||||
throw new Error("Invalid file name");
|
||||
}
|
||||
|
||||
await fs.writeFile(path.join(folder, fileName), content);
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import { mysqlTable, primaryKey, text, varchar } from "drizzle-orm/mysql-core";
|
||||
|
||||
export const trustedCertificateHostnames = mysqlTable(
|
||||
"trusted_certificate_hostname",
|
||||
{
|
||||
hostname: varchar({ length: 256 }).notNull(),
|
||||
thumbprint: varchar({ length: 128 }).notNull(),
|
||||
certificate: text().notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
compoundKey: primaryKey({
|
||||
columns: [table.hostname, table.thumbprint],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,15 @@
|
||||
import { pgTable, primaryKey, text, varchar } from "drizzle-orm/pg-core";
|
||||
|
||||
export const trustedCertificateHostnames = pgTable(
|
||||
"trusted_certificate_hostname",
|
||||
{
|
||||
hostname: varchar({ length: 256 }).notNull(),
|
||||
thumbprint: varchar({ length: 128 }).notNull(),
|
||||
certificate: text().notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
compoundKey: primaryKey({
|
||||
columns: [table.hostname, table.thumbprint],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,10 @@
|
||||
import { createSchema } from "../../../db";
|
||||
import * as mysql from "./mysql";
|
||||
import * as postgresql from "./postgresql";
|
||||
import * as sqlite from "./sqlite";
|
||||
|
||||
export const schema = createSchema({
|
||||
"better-sqlite3": () => sqlite,
|
||||
mysql2: () => mysql,
|
||||
"node-postgres": () => postgresql,
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import { primaryKey, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
||||
|
||||
export const trustedCertificateHostnames = sqliteTable(
|
||||
"trusted_certificate_hostname",
|
||||
{
|
||||
hostname: text().notNull(),
|
||||
thumbprint: text().notNull(),
|
||||
certificate: text().notNull(),
|
||||
},
|
||||
(table) => ({
|
||||
compoundKey: primaryKey({
|
||||
columns: [table.hostname, table.thumbprint],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,8 @@
|
||||
import { createDb } from "../../db";
|
||||
import { schema } from "./db/schema";
|
||||
|
||||
const db = createDb(schema);
|
||||
|
||||
export const getTrustedCertificateHostnamesAsync = async () => {
|
||||
return await db.query.trustedCertificateHostnames.findMany();
|
||||
};
|
||||
7
packages/core/src/infrastructure/certificates/index.ts
Normal file
7
packages/core/src/infrastructure/certificates/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export { getTrustedCertificateHostnamesAsync } from "./hostnames";
|
||||
export {
|
||||
addCustomRootCertificateAsync,
|
||||
removeCustomRootCertificateAsync,
|
||||
getAllTrustedCertificatesAsync,
|
||||
loadCustomRootCertificatesAsync,
|
||||
} from "./files";
|
||||
Reference in New Issue
Block a user