archetecture security fix
This commit is contained in:
+38
@@ -0,0 +1,38 @@
|
||||
export declare function createCompanyWithEmployee(overrides?: {
|
||||
role?: 'OWNER' | 'MANAGER' | 'AGENT';
|
||||
companyStatus?: 'ACTIVE' | 'TRIALING' | 'PAST_DUE' | 'SUSPENDED' | 'PENDING';
|
||||
}): Promise<{
|
||||
company: any;
|
||||
employee: any;
|
||||
}>;
|
||||
export declare function createVehicle(companyId: string, overrides?: Record<string, unknown>): Promise<any>;
|
||||
export declare function createCustomer(companyId: string, overrides?: Record<string, unknown>): Promise<any>;
|
||||
export declare function createRenter(overrides?: {
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
email?: string;
|
||||
password?: string;
|
||||
isActive?: boolean;
|
||||
}): Promise<any>;
|
||||
export declare function createAdminUser(overrides?: {
|
||||
email?: string;
|
||||
firstName?: string;
|
||||
lastName?: string;
|
||||
password?: string;
|
||||
role?: 'SUPER_ADMIN' | 'ADMIN' | 'SUPPORT' | 'FINANCE' | 'VIEWER';
|
||||
isActive?: boolean;
|
||||
totpEnabled?: boolean;
|
||||
totpSecret?: string | null;
|
||||
}): Promise<any>;
|
||||
export declare function createReservation(companyId: string, vehicleId: string, customerId: string, overrides?: Record<string, unknown>): Promise<any>;
|
||||
export declare function createRentalPayment(companyId: string, reservationId: string, overrides?: Record<string, unknown>): Promise<any>;
|
||||
export declare function createSubscriptionInvoice(companyId: string, subscriptionId: string, overrides?: Record<string, unknown>): Promise<any>;
|
||||
export declare function createCompanyNotification(companyId: string, employeeId?: string, overrides?: Record<string, unknown>): Promise<any>;
|
||||
export declare function createRenterNotification(renterId: string, overrides?: Record<string, unknown>): Promise<any>;
|
||||
export declare function signEmployeeToken(employeeId: string, _companyId: string, _role?: string): string;
|
||||
export declare function signAdminToken(adminId: string): string;
|
||||
export declare function signRenterToken(renterId: string): string;
|
||||
export declare function authHeader(token: string): {
|
||||
Authorization: string;
|
||||
};
|
||||
//# sourceMappingURL=fixtures.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../../src/tests/helpers/fixtures.ts"],"names":[],"mappings":"AASA,wBAAsB,yBAAyB,CAAC,SAAS,GAAE;IACzD,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAAA;IACpC,aAAa,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAA;CACxE;;;GA0BL;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,gBAkB7F;AAED,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,gBAU9F;AAED,wBAAsB,YAAY,CAAC,SAAS,GAAE;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACd,gBAUL;AAED,wBAAsB,eAAe,CAAC,SAAS,GAAE;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB,gBAaL;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,gBAmBxC;AAED,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,gBAgBxC;AAED,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,gBAcxC;AAED,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,gBAcxC;AAED,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,gBAaxC;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,MAAgB,UAEhG;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,UAE7C;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,UAE/C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM;;EAEvC"}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createCompanyWithEmployee = createCompanyWithEmployee;
|
||||
exports.createVehicle = createVehicle;
|
||||
exports.createCustomer = createCustomer;
|
||||
exports.createRenter = createRenter;
|
||||
exports.createAdminUser = createAdminUser;
|
||||
exports.createReservation = createReservation;
|
||||
exports.createRentalPayment = createRentalPayment;
|
||||
exports.createSubscriptionInvoice = createSubscriptionInvoice;
|
||||
exports.createCompanyNotification = createCompanyNotification;
|
||||
exports.createRenterNotification = createRenterNotification;
|
||||
exports.signEmployeeToken = signEmployeeToken;
|
||||
exports.signAdminToken = signAdminToken;
|
||||
exports.signRenterToken = signRenterToken;
|
||||
exports.authHeader = authHeader;
|
||||
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
||||
const prisma_1 = require("../../lib/prisma");
|
||||
const tokens_1 = require("../../security/tokens");
|
||||
let counter = 0;
|
||||
function uid() {
|
||||
return `${Date.now()}-${++counter}-${Math.random().toString(36).slice(2, 7)}`;
|
||||
}
|
||||
async function createCompanyWithEmployee(overrides = {}) {
|
||||
const slug = `test-${uid()}`;
|
||||
const company = await prisma_1.prisma.company.create({
|
||||
data: {
|
||||
name: `Test Company ${slug}`,
|
||||
slug,
|
||||
email: `company-${slug}@test.com`,
|
||||
status: (overrides.companyStatus ?? 'ACTIVE'),
|
||||
subscription: {
|
||||
create: { status: 'TRIALING', plan: 'STARTER' },
|
||||
},
|
||||
},
|
||||
});
|
||||
const employee = await prisma_1.prisma.employee.create({
|
||||
data: {
|
||||
companyId: company.id,
|
||||
clerkUserId: `clerk_${uid()}`,
|
||||
firstName: 'Test',
|
||||
lastName: 'User',
|
||||
email: `employee-${uid()}@test.com`,
|
||||
role: overrides.role ?? 'OWNER',
|
||||
},
|
||||
});
|
||||
return { company, employee };
|
||||
}
|
||||
async function createVehicle(companyId, overrides = {}) {
|
||||
return prisma_1.prisma.vehicle.create({
|
||||
data: {
|
||||
companyId,
|
||||
make: 'Toyota',
|
||||
model: 'Corolla',
|
||||
year: 2022,
|
||||
color: 'White',
|
||||
licensePlate: `PL-${uid()}`,
|
||||
dailyRate: 500,
|
||||
status: 'AVAILABLE',
|
||||
isPublished: true,
|
||||
pickupLocations: ['Casablanca'],
|
||||
allowDifferentDropoff: false,
|
||||
dropoffLocations: [],
|
||||
...overrides,
|
||||
},
|
||||
});
|
||||
}
|
||||
async function createCustomer(companyId, overrides = {}) {
|
||||
return prisma_1.prisma.customer.create({
|
||||
data: {
|
||||
companyId,
|
||||
firstName: 'Jane',
|
||||
lastName: 'Doe',
|
||||
email: `customer-${uid()}@test.com`,
|
||||
...overrides,
|
||||
},
|
||||
});
|
||||
}
|
||||
async function createRenter(overrides = {}) {
|
||||
return prisma_1.prisma.renter.create({
|
||||
data: {
|
||||
firstName: overrides.firstName ?? 'Renter',
|
||||
lastName: overrides.lastName ?? 'User',
|
||||
email: overrides.email ?? `renter-${uid()}@test.com`,
|
||||
passwordHash: await bcryptjs_1.default.hash(overrides.password ?? 'RenterPass123!', 10),
|
||||
isActive: overrides.isActive ?? true,
|
||||
},
|
||||
});
|
||||
}
|
||||
async function createAdminUser(overrides = {}) {
|
||||
return prisma_1.prisma.adminUser.create({
|
||||
data: {
|
||||
email: overrides.email ?? `admin-${uid()}@test.com`,
|
||||
firstName: overrides.firstName ?? 'Admin',
|
||||
lastName: overrides.lastName ?? 'User',
|
||||
passwordHash: await bcryptjs_1.default.hash(overrides.password ?? 'AdminPass123!', 10),
|
||||
role: (overrides.role ?? 'ADMIN'),
|
||||
isActive: overrides.isActive ?? true,
|
||||
totpEnabled: overrides.totpEnabled ?? false,
|
||||
totpSecret: overrides.totpSecret ?? null,
|
||||
},
|
||||
});
|
||||
}
|
||||
async function createReservation(companyId, vehicleId, customerId, overrides = {}) {
|
||||
return prisma_1.prisma.reservation.create({
|
||||
data: {
|
||||
companyId,
|
||||
vehicleId,
|
||||
customerId,
|
||||
startDate: new Date(Date.now() + 24 * 60 * 60 * 1000),
|
||||
endDate: new Date(Date.now() + 4 * 24 * 60 * 60 * 1000),
|
||||
dailyRate: 500,
|
||||
totalDays: 3,
|
||||
totalAmount: 1500,
|
||||
depositAmount: 300,
|
||||
status: 'CONFIRMED',
|
||||
paymentStatus: 'UNPAID',
|
||||
paidAmount: 0,
|
||||
...overrides,
|
||||
},
|
||||
});
|
||||
}
|
||||
async function createRentalPayment(companyId, reservationId, overrides = {}) {
|
||||
return prisma_1.prisma.rentalPayment.create({
|
||||
data: {
|
||||
companyId,
|
||||
reservationId,
|
||||
amount: 500,
|
||||
currency: 'MAD',
|
||||
status: 'SUCCEEDED',
|
||||
type: 'CHARGE',
|
||||
paymentProvider: 'AMANPAY',
|
||||
amanpayTransactionId: `aman-${uid()}`,
|
||||
paidAt: new Date(),
|
||||
...overrides,
|
||||
},
|
||||
});
|
||||
}
|
||||
async function createSubscriptionInvoice(companyId, subscriptionId, overrides = {}) {
|
||||
return prisma_1.prisma.subscriptionInvoice.create({
|
||||
data: {
|
||||
companyId,
|
||||
subscriptionId,
|
||||
amount: 2990,
|
||||
currency: 'MAD',
|
||||
status: 'PENDING',
|
||||
paymentProvider: 'AMANPAY',
|
||||
amanpayTransactionId: `sub-${uid()}`,
|
||||
...overrides,
|
||||
},
|
||||
});
|
||||
}
|
||||
async function createCompanyNotification(companyId, employeeId, overrides = {}) {
|
||||
return prisma_1.prisma.notification.create({
|
||||
data: {
|
||||
companyId,
|
||||
employeeId,
|
||||
type: 'PAYMENT_RECEIVED',
|
||||
title: 'Payment received',
|
||||
body: 'A payment was recorded.',
|
||||
channel: 'IN_APP',
|
||||
status: 'PENDING',
|
||||
...overrides,
|
||||
},
|
||||
});
|
||||
}
|
||||
async function createRenterNotification(renterId, overrides = {}) {
|
||||
return prisma_1.prisma.notification.create({
|
||||
data: {
|
||||
renterId,
|
||||
type: 'BOOKING_CONFIRMED',
|
||||
title: 'Booking confirmed',
|
||||
body: 'Your booking is confirmed.',
|
||||
channel: 'IN_APP',
|
||||
status: 'PENDING',
|
||||
...overrides,
|
||||
},
|
||||
});
|
||||
}
|
||||
function signEmployeeToken(employeeId, _companyId, _role = 'OWNER') {
|
||||
return (0, tokens_1.signActorToken)(employeeId, 'employee', { expiresIn: '1h' });
|
||||
}
|
||||
function signAdminToken(adminId) {
|
||||
return (0, tokens_1.signActorToken)(adminId, 'admin', { expiresIn: '1h', last2faAt: Date.now() });
|
||||
}
|
||||
function signRenterToken(renterId) {
|
||||
return (0, tokens_1.signActorToken)(renterId, 'renter', { expiresIn: '1h' });
|
||||
}
|
||||
function authHeader(token) {
|
||||
return { Authorization: `Bearer ${token}` };
|
||||
}
|
||||
//# sourceMappingURL=fixtures.js.map
|
||||
+1
File diff suppressed because one or more lines are too long
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=setup.d.ts.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/tests/setup.ts"],"names":[],"mappings":""}
|
||||
Vendored
+64
@@ -0,0 +1,64 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const vitest_1 = require("vitest");
|
||||
const prisma_1 = require("../lib/prisma");
|
||||
const delegates = [
|
||||
'billingEvent',
|
||||
'billingRefund',
|
||||
'billingCreditNote',
|
||||
'billingCreditLedgerEntry',
|
||||
'billingCreditBalance',
|
||||
'billingPaymentAttempt',
|
||||
'billingPaymentIntent',
|
||||
'billingInvoiceLineItem',
|
||||
'billingInvoice',
|
||||
'billingPaymentMethod',
|
||||
'billingAccount',
|
||||
'auditLog',
|
||||
'adminPermission',
|
||||
'adminUser',
|
||||
'damagePoint',
|
||||
'damageInspection',
|
||||
'damageReport',
|
||||
'additionalDriver',
|
||||
'reservationInsurance',
|
||||
'notificationPreference',
|
||||
'notification',
|
||||
'review',
|
||||
'rentalPayment',
|
||||
'reservation',
|
||||
'customer',
|
||||
'renterSavedCompany',
|
||||
'renter',
|
||||
'offerVehicle',
|
||||
'offer',
|
||||
'vehicleCalendarBlock',
|
||||
'vehiclePriceHistory',
|
||||
'vehiclePricingRule',
|
||||
'vehiclePricingConfiguration',
|
||||
'maintenanceLog',
|
||||
'vehicle',
|
||||
'employee',
|
||||
'pricingRule',
|
||||
'insurancePolicy',
|
||||
'accountingSettings',
|
||||
'contractSettings',
|
||||
'brandSettings',
|
||||
'subscriptionInvoice',
|
||||
'subscription',
|
||||
'company',
|
||||
];
|
||||
// Wipe all data between test files in a safe order that respects FK constraints.
|
||||
async function cleanDatabase() {
|
||||
for (const delegate of delegates) {
|
||||
await prisma_1.prisma[delegate].deleteMany({});
|
||||
}
|
||||
}
|
||||
(0, vitest_1.beforeAll)(async () => {
|
||||
await cleanDatabase();
|
||||
});
|
||||
(0, vitest_1.afterAll)(async () => {
|
||||
await cleanDatabase();
|
||||
await prisma_1.prisma.$disconnect();
|
||||
});
|
||||
//# sourceMappingURL=setup.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/tests/setup.ts"],"names":[],"mappings":";;AAAA,mCAA4C;AAC5C,0CAAsC;AAEtC,MAAM,SAAS,GAAG;IAChB,cAAc;IACd,eAAe;IACf,mBAAmB;IACnB,0BAA0B;IAC1B,sBAAsB;IACtB,uBAAuB;IACvB,sBAAsB;IACtB,wBAAwB;IACxB,gBAAgB;IAChB,sBAAsB;IACtB,gBAAgB;IAChB,UAAU;IACV,iBAAiB;IACjB,WAAW;IACX,aAAa;IACb,kBAAkB;IAClB,cAAc;IACd,kBAAkB;IAClB,sBAAsB;IACtB,wBAAwB;IACxB,cAAc;IACd,QAAQ;IACR,eAAe;IACf,aAAa;IACb,UAAU;IACV,oBAAoB;IACpB,QAAQ;IACR,cAAc;IACd,OAAO;IACP,sBAAsB;IACtB,qBAAqB;IACrB,oBAAoB;IACpB,6BAA6B;IAC7B,gBAAgB;IAChB,SAAS;IACT,UAAU;IACV,aAAa;IACb,iBAAiB;IACjB,oBAAoB;IACpB,kBAAkB;IAClB,eAAe;IACf,qBAAqB;IACrB,cAAc;IACd,SAAS;CACD,CAAA;AAEV,iFAAiF;AACjF,KAAK,UAAU,aAAa;IAC1B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAO,eAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAChD,CAAC;AACH,CAAC;AAED,IAAA,kBAAS,EAAC,KAAK,IAAI,EAAE;IACnB,MAAM,aAAa,EAAE,CAAA;AACvB,CAAC,CAAC,CAAA;AAEF,IAAA,iBAAQ,EAAC,KAAK,IAAI,EAAE;IAClB,MAAM,aAAa,EAAE,CAAA;IACrB,MAAM,eAAM,CAAC,WAAW,EAAE,CAAA;AAC5B,CAAC,CAAC,CAAA"}
|
||||
Reference in New Issue
Block a user