feat: added logged in based testing by injecting jwt token logic

This commit is contained in:
Akhil Mohan
2024-01-14 15:07:05 +05:30
parent dd7c449483
commit 0506389ada
10 changed files with 125 additions and 28 deletions

View File

@@ -1,11 +1,11 @@
import { testUser } from "@app/db/seeds/1-user";
import { seedData1 } from "@app/db/seed-data";
import jsrp from "jsrp";
describe("Login V1 Router", async () => {
// eslint-disable-next-line
const client = new jsrp.client();
await new Promise((resolve) => {
client.init({ username: testUser.email, password: testUser.password }, () => resolve(null));
client.init({ username: seedData1.email, password: seedData1.password }, () => resolve(null));
});
let clientProof: string;
@@ -32,7 +32,7 @@ describe("Login V1 Router", async () => {
method: "POST",
url: "/api/v3/auth/login2",
body: {
email: testUser.email,
email: seedData1.email,
clientProof
}
});

View File

@@ -0,0 +1,19 @@
import { seedData1 } from "@app/db/seed-data";
describe("Org V1 Router", async () => {
test("GET Org list", async () => {
const res = await testServer.inject({
method: "GET",
url: "/api/v1/organization",
headers: {
authorization: `Bearer ${jwtAuthToken}`
}
});
expect(res.statusCode).toBe(200);
const payload = JSON.parse(res.payload);
expect(payload).toHaveProperty("organizations");
expect(payload).toEqual({
organizations: [expect.objectContaining({ name: seedData1.organization.name })]
});
});
});

View File

@@ -1,9 +0,0 @@
describe("Status V1 Router", async () => {
test("Simple check", async () => {
const res = await testServer.inject({
method: "GET",
url: "/api/status"
});
expect(res.statusCode).toBe(200);
});
});

View File

@@ -5,10 +5,13 @@ import knex from "knex";
import path from "path";
import { mockSmtpServer } from "./mocks/smtp";
import { initLogger } from "@app/lib/logger";
import jwt from "jsonwebtoken";
import "ts-node/register";
import { main } from "@app/server/app";
import { mockQueue } from "./mocks/queue";
import { AuthTokenType } from "@app/services/auth/auth-type";
import { seedData1 } from "@app/db/seed-data";
dotenv.config({ path: path.join(__dirname, "../.env.test") });
export default {
@@ -35,10 +38,21 @@ export default {
const smtp = mockSmtpServer();
const queue = mockQueue();
const logger = await initLogger();
initEnvConfig(logger);
const cfg = initEnvConfig(logger);
const server = await main({ db, smtp, logger, queue });
// @ts-expect-error type
globalThis.testServer = server;
// @ts-expect-error type
globalThis.jwtAuthToken = jwt.sign(
{
authTokenType: AuthTokenType.ACCESS_TOKEN,
userId: seedData1.id,
tokenVersionId: seedData1.token.id,
accessVersion: 1
},
cfg.JWT_AUTH_SECRET,
{ expiresIn: cfg.JWT_AUTH_LIFETIME }
);
} catch (error) {
await db.destroy();
throw error;
@@ -50,6 +64,8 @@ export default {
await globalThis.testServer.close();
// @ts-expect-error type
delete globalThis.testServer;
// @ts-expect-error type
delete globalThis.jwtToken;
// called after all tests with this env have been run
await db.migrate.rollback({}, true);
await db.destroy();

View File

@@ -19,4 +19,5 @@ declare global {
// used only for testing
const testServer: FastifyZodProvider;
const jwtAuthToken: string;
}

View File

@@ -0,0 +1,16 @@
export const seedData1 = {
id: "3dafd81d-4388-432b-a4c5-f735616868c1",
email: "test@localhost.local",
password: process.env.TEST_USER_PASSWORD || "testInfisical@1",
organization: {
id: "180870b7-f464-4740-8ffe-9d11c9245ea7",
name: "infisical"
},
project: {
id: "77fa7aed-9288-401e-a4c9-3a9430be62a0",
name: "first project"
},
token: {
id: "a9dfafba-a3b7-42e3-8618-91abb702fd36"
}
};

View File

@@ -1,17 +1,16 @@
import { Knex } from "knex";
import crypto from "node:crypto";
import argon2, { argon2id } from "argon2";
import jsrp from "jsrp";
import { Knex } from "knex";
import nacl from "tweetnacl";
import { encodeBase64 } from "tweetnacl-util";
import argon2, { argon2id } from "argon2";
import { AuthMethod } from "../../services/auth/auth-type";
import { TableName } from "../schemas";
import crypto from "node:crypto";
import { encryptSymmetric } from "@app/lib/crypto";
export const testUser = {
email: "test@localhost.local",
password: process.env.TEST_USER_PASSWORD || "testInfisical@1"
};
import { AuthMethod } from "../../services/auth/auth-type";
import { TableName } from "../schemas";
import { seedData1 } from "../seed-data";
export const generateUserSrpKeys = async (password: string) => {
const pair = nacl.box.keyPair();
@@ -23,7 +22,7 @@ export const generateUserSrpKeys = async (password: string) => {
// eslint-disable-next-line
const client = new jsrp.client();
await new Promise((resolve) => {
client.init({ username: testUser.email, password: testUser.password }, () => resolve(null));
client.init({ username: seedData1.email, password: seedData1.password }, () => resolve(null));
});
const { salt, verifier } = await new Promise<{ salt: string; verifier: string }>(
(resolve, reject) => {
@@ -85,7 +84,9 @@ export async function seed(knex: Knex): Promise<void> {
const [user] = await knex(TableName.Users)
.insert([
{
email: testUser.email,
// @ts-ignore to calculate predefined
id: seedData1.id,
email: seedData1.email,
superAdmin: true,
firstName: "test",
lastName: "",
@@ -98,7 +99,7 @@ export async function seed(knex: Knex): Promise<void> {
])
.returning("*");
const encKeys = await generateUserSrpKeys(testUser.password);
const encKeys = await generateUserSrpKeys(seedData1.password);
// password: testInfisical@1
await knex(TableName.UserEncryptionKey).insert([
{
@@ -115,4 +116,16 @@ export async function seed(knex: Knex): Promise<void> {
userId: user.id
}
]);
await knex(TableName.AuthTokenSession).insert({
// @ts-ignore
id: seedData1.token.id,
userId: seedData1.id,
ip: "151.196.220.213",
userAgent:
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 RuxitSynthetic/1.0 v3690753611340580436 t8052286838287810618",
accessVersion: 1,
refreshVersion: 1,
lastUsed: new Date()
});
}

View File

@@ -1,19 +1,21 @@
import { Knex } from "knex";
import { OrgMembershipRole, OrgMembershipStatus, TableName } from "../schemas";
import { testUser } from "./1-user";
import { seedData1 } from "../seed-data";
export async function seed(knex: Knex): Promise<void> {
// Deletes ALL existing entries
await knex(TableName.Organization).del();
await knex(TableName.OrgMembership).del();
const user = await knex(TableName.Users).where({ email: testUser.email }).first();
const user = await knex(TableName.Users).where({ email: seedData1.email }).first();
if (!user) throw new Error("User not found");
// Inserts seed entries
const [org] = await knex(TableName.Organization)
.insert([
{
// @ts-ignore because we need that id for api calls
id: seedData1.organization.id,
name: "infisical",
customerId: null
}

View File

@@ -0,0 +1,39 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { seedData1 } from "../seed-data";
export const DEFAULT_PROJECT_ENVS = [
{ name: "Development", slug: "dev" },
{ name: "Staging", slug: "staging" },
{ name: "Production", slug: "prod" }
];
export async function seed(knex: Knex): Promise<void> {
// Deletes ALL existing entries
await knex(TableName.Project).del();
await knex(TableName.Environment).del();
await knex(TableName.SecretFolder).del();
const [project] = await knex(TableName.Project)
.insert({
name: seedData1.project.name,
orgId: seedData1.organization.id,
// @ts-ignore pre calc id
id: seedData1.project.id
})
.returning("*");
const envs = await knex(TableName.Environment)
.insert(
DEFAULT_PROJECT_ENVS.map(({ name, slug }, index) => ({
name,
slug,
projectId: project.id,
position: index + 1
}))
)
.returning("*");
await knex(TableName.SecretFolder).insert(
envs.map(({ id }) => ({ name: "root", envId: id, parentId: null }))
);
}

View File

@@ -22,7 +22,7 @@ import { ROOT_FOLDER_NAME, TSecretFolderDalFactory } from "../secret-folder/secr
import { TProjectDalFactory } from "./project-dal";
import { TCreateProjectDTO, TDeleteProjectDTO, TGetProjectDTO } from "./project-types";
const DEFAULT_PROJECT_ENVS = [
export const DEFAULT_PROJECT_ENVS = [
{ name: "Development", slug: "dev" },
{ name: "Staging", slug: "staging" },
{ name: "Production", slug: "prod" }