Merge branch 'main' into feat/remindersImprovement

This commit is contained in:
Carlos Monastyrski
2025-07-17 17:35:41 -03:00
460 changed files with 8384 additions and 2476 deletions

View File

@@ -1,8 +1,9 @@
import crypto from "node:crypto";
import { SecretType, TSecrets } from "@app/db/schemas";
import { decryptSecret, encryptSecret, getUserPrivateKey, seedData1 } from "@app/db/seed-data";
import { decryptAsymmetric, decryptSymmetric128BitHexKeyUTF8, encryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
import { initEnvConfig } from "@app/lib/config/env";
import { SymmetricKeySize } from "@app/lib/crypto";
import { crypto } from "@app/lib/crypto/cryptography";
import { initLogger, logger } from "@app/lib/logger";
const createServiceToken = async (
scopes: { environment: string; secretPath: string }[],
@@ -26,7 +27,8 @@ const createServiceToken = async (
});
const { user: userInfo } = JSON.parse(userInfoRes.payload);
const privateKey = await getUserPrivateKey(seedData1.password, userInfo);
const projectKey = decryptAsymmetric({
const projectKey = crypto.encryption().asymmetric().decrypt({
ciphertext: projectKeyEnc.encryptedKey,
nonce: projectKeyEnc.nonce,
publicKey: projectKeyEnc.sender.publicKey,
@@ -34,7 +36,13 @@ const createServiceToken = async (
});
const randomBytes = crypto.randomBytes(16).toString("hex");
const { ciphertext, iv, tag } = encryptSymmetric128BitHexKeyUTF8(projectKey, randomBytes);
const { ciphertext, iv, tag } = crypto.encryption().symmetric().encrypt({
plaintext: projectKey,
key: randomBytes,
keySize: SymmetricKeySize.Bits128
});
const serviceTokenRes = await testServer.inject({
method: "POST",
url: "/api/v2/service-token",
@@ -137,6 +145,9 @@ describe("Service token secret ops", async () => {
let projectKey = "";
let folderId = "";
beforeAll(async () => {
initLogger();
await initEnvConfig(testSuperAdminDAL, logger);
serviceToken = await createServiceToken(
[{ secretPath: "/**", environment: seedData1.environment.slug }],
["read", "write"]
@@ -153,11 +164,13 @@ describe("Service token secret ops", async () => {
expect(serviceTokenInfoRes.statusCode).toBe(200);
const serviceTokenInfo = serviceTokenInfoRes.json();
const serviceTokenParts = serviceToken.split(".");
projectKey = decryptSymmetric128BitHexKeyUTF8({
projectKey = crypto.encryption().symmetric().decrypt({
key: serviceTokenParts[3],
tag: serviceTokenInfo.tag,
ciphertext: serviceTokenInfo.encryptedKey,
iv: serviceTokenInfo.iv
iv: serviceTokenInfo.iv,
keySize: SymmetricKeySize.Bits128
});
// create a deep folder

View File

@@ -1,6 +1,8 @@
import { SecretType, TSecrets } from "@app/db/schemas";
import { decryptSecret, encryptSecret, getUserPrivateKey, seedData1 } from "@app/db/seed-data";
import { decryptAsymmetric, encryptAsymmetric } from "@app/lib/crypto";
import { initEnvConfig } from "@app/lib/config/env";
import { crypto } from "@app/lib/crypto/cryptography";
import { initLogger, logger } from "@app/lib/logger";
import { AuthMode } from "@app/services/auth/auth-type";
const createSecret = async (dto: {
@@ -155,6 +157,9 @@ describe("Secret V3 Router", async () => {
let projectKey = "";
let folderId = "";
beforeAll(async () => {
initLogger();
await initEnvConfig(testSuperAdminDAL, logger);
const projectKeyRes = await testServer.inject({
method: "GET",
url: `/api/v2/workspace/${seedData1.project.id}/encrypted-key`,
@@ -173,7 +178,7 @@ describe("Secret V3 Router", async () => {
});
const { user: userInfo } = JSON.parse(userInfoRes.payload);
const privateKey = await getUserPrivateKey(seedData1.password, userInfo);
projectKey = decryptAsymmetric({
projectKey = crypto.encryption().asymmetric().decrypt({
ciphertext: projectKeyEncryptionDetails.encryptedKey,
nonce: projectKeyEncryptionDetails.nonce,
publicKey: projectKeyEncryptionDetails.sender.publicKey,
@@ -669,7 +674,7 @@ describe.each([{ auth: AuthMode.JWT }, { auth: AuthMode.IDENTITY_ACCESS_TOKEN }]
const { user: userInfo } = JSON.parse(userInfoRes.payload);
const privateKey = await getUserPrivateKey(seedData1.password, userInfo);
const projectKey = decryptAsymmetric({
const projectKey = crypto.encryption().asymmetric().decrypt({
ciphertext: projectKeyEnc.encryptedKey,
nonce: projectKeyEnc.nonce,
publicKey: projectKeyEnc.sender.publicKey,
@@ -685,7 +690,7 @@ describe.each([{ auth: AuthMode.JWT }, { auth: AuthMode.IDENTITY_ACCESS_TOKEN }]
});
expect(projectBotRes.statusCode).toEqual(200);
const projectBot = JSON.parse(projectBotRes.payload).bot;
const botKey = encryptAsymmetric(projectKey, projectBot.publicKey, privateKey);
const botKey = crypto.encryption().asymmetric().encrypt(projectKey, projectBot.publicKey, privateKey);
// set bot as active
const setBotActive = await testServer.inject({

View File

@@ -2,11 +2,11 @@
import "ts-node/register";
import dotenv from "dotenv";
import jwt from "jsonwebtoken";
import { crypto } from "@app/lib/crypto/cryptography";
import path from "path";
import { seedData1 } from "@app/db/seed-data";
import { initEnvConfig } from "@app/lib/config/env";
import { getDatabaseCredentials, initEnvConfig } from "@app/lib/config/env";
import { initLogger } from "@app/lib/logger";
import { main } from "@app/server/app";
import { AuthMethod, AuthTokenType } from "@app/services/auth/auth-type";
@@ -17,6 +17,7 @@ import { queueServiceFactory } from "@app/queue";
import { keyStoreFactory } from "@app/keystore/keystore";
import { initializeHsmModule } from "@app/ee/services/hsm/hsm-fns";
import { buildRedisFromConfig } from "@app/lib/config/redis";
import { superAdminDALFactory } from "@app/services/super-admin/super-admin-dal";
dotenv.config({ path: path.join(__dirname, "../../.env.test"), debug: true });
export default {
@@ -24,13 +25,17 @@ export default {
transformMode: "ssr",
async setup() {
const logger = initLogger();
const envConfig = initEnvConfig(logger);
const databaseCredentials = getDatabaseCredentials(logger);
const db = initDbConnection({
dbConnectionUri: envConfig.DB_CONNECTION_URI,
dbRootCert: envConfig.DB_ROOT_CERT
dbConnectionUri: databaseCredentials.dbConnectionUri,
dbRootCert: databaseCredentials.dbRootCert
});
const redis = buildRedisFromConfig(envConfig);
const superAdminDAL = superAdminDALFactory(db);
const envCfg = await initEnvConfig(superAdminDAL, logger);
const redis = buildRedisFromConfig(envCfg);
await redis.flushdb("SYNC");
try {
@@ -55,10 +60,10 @@ export default {
});
const smtp = mockSmtpServer();
const queue = queueServiceFactory(envConfig, { dbConnectionUrl: envConfig.DB_CONNECTION_URI });
const keyStore = keyStoreFactory(envConfig);
const queue = queueServiceFactory(envCfg, { dbConnectionUrl: envCfg.DB_CONNECTION_URI });
const keyStore = keyStoreFactory(envCfg);
const hsmModule = initializeHsmModule(envConfig);
const hsmModule = initializeHsmModule(envCfg);
hsmModule.initialize();
const server = await main({
@@ -68,14 +73,17 @@ export default {
queue,
keyStore,
hsmModule: hsmModule.getModule(),
superAdminDAL,
redis,
envConfig
envConfig: envCfg
});
// @ts-expect-error type
globalThis.testServer = server;
// @ts-expect-error type
globalThis.jwtAuthToken = jwt.sign(
globalThis.testSuperAdminDAL = superAdminDAL;
// @ts-expect-error type
globalThis.jwtAuthToken = crypto.jwt().sign(
{
authTokenType: AuthTokenType.ACCESS_TOKEN,
userId: seedData1.id,
@@ -84,8 +92,8 @@ export default {
organizationId: seedData1.organization.id,
accessVersion: 1
},
envConfig.AUTH_SECRET,
{ expiresIn: envConfig.JWT_AUTH_LIFETIME }
envCfg.AUTH_SECRET,
{ expiresIn: envCfg.JWT_AUTH_LIFETIME }
);
} catch (error) {
// eslint-disable-next-line
@@ -102,6 +110,8 @@ export default {
// @ts-expect-error type
delete globalThis.testServer;
// @ts-expect-error type
delete globalThis.testSuperAdminDAL;
// @ts-expect-error type
delete globalThis.jwtToken;
// called after all tests with this env have been run
await db.migrate.rollback(