archetecture security fix
This commit is contained in:
+145
@@ -0,0 +1,145 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.signup = signup;
|
||||
exports.completeSignupDisabled = completeSignupDisabled;
|
||||
exports.verifyEmailDisabled = verifyEmailDisabled;
|
||||
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
||||
const errors_1 = require("../../http/errors");
|
||||
const prisma_1 = require("../../lib/prisma");
|
||||
const notificationService_1 = require("../../services/notificationService");
|
||||
const notificationLocalizationService_1 = require("../../services/notificationLocalizationService");
|
||||
const auth_presenter_1 = require("./auth.presenter");
|
||||
const repo = __importStar(require("./auth.company.repo"));
|
||||
const TRIAL_PERIOD_DAYS = 90;
|
||||
function slugify(value) {
|
||||
return value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 50) || 'company';
|
||||
}
|
||||
async function generateUniqueSlug(baseName) {
|
||||
const base = slugify(baseName);
|
||||
for (let attempt = 0; attempt < 25; attempt++) {
|
||||
const slug = attempt === 0 ? base : `${base}-${attempt + 1}`;
|
||||
const existing = await repo.findCompanyBySlug(slug);
|
||||
if (!existing)
|
||||
return slug;
|
||||
}
|
||||
return `${base}-${Date.now().toString(36)}`;
|
||||
}
|
||||
async function signup(body) {
|
||||
if (await repo.findCompanyByEmail(body.companyEmail)) {
|
||||
throw new errors_1.AppError('A company account with this contact email already exists', 409, 'company_email_taken');
|
||||
}
|
||||
if (await repo.findEmployeeByEmail(body.email)) {
|
||||
throw new errors_1.AppError('An employee account with this owner email already exists', 409, 'owner_email_taken');
|
||||
}
|
||||
const slug = await generateUniqueSlug(body.companyName);
|
||||
const now = new Date();
|
||||
const trialEndAt = new Date(now.getTime() + TRIAL_PERIOD_DAYS * 24 * 60 * 60 * 1000);
|
||||
const passwordHash = await bcryptjs_1.default.hash(body.password, 12);
|
||||
const result = await prisma_1.prisma.$transaction((tx) => repo.createCompanySignup(tx, {
|
||||
companyName: body.companyName,
|
||||
legalName: body.legalName,
|
||||
slug,
|
||||
ownerEmail: body.email,
|
||||
companyEmail: body.companyEmail,
|
||||
companyPhone: body.companyPhone,
|
||||
streetAddress: body.streetAddress,
|
||||
city: body.city,
|
||||
country: body.country,
|
||||
zipCode: body.zipCode,
|
||||
legalForm: body.legalForm,
|
||||
managerName: `${body.firstName} ${body.lastName}`.trim(),
|
||||
iceNumber: body.iceNumber,
|
||||
taxId: body.taxId,
|
||||
operatingLicenseNumber: body.operatingLicenseNumber,
|
||||
operatingLicenseIssuedAt: body.operatingLicenseIssuedAt,
|
||||
operatingLicenseIssuedBy: body.operatingLicenseIssuedBy,
|
||||
fax: body.fax,
|
||||
yearsActive: body.yearsActive,
|
||||
representativeName: body.representativeName,
|
||||
representativeTitle: body.representativeTitle,
|
||||
responsibleName: body.responsibleName,
|
||||
responsibleRole: body.responsibleRole,
|
||||
responsibleIdentityNumber: body.responsibleIdentityNumber,
|
||||
responsibleQualification: body.responsibleQualification,
|
||||
responsiblePhone: body.responsiblePhone,
|
||||
responsibleEmail: body.responsibleEmail,
|
||||
currency: body.currency,
|
||||
registrationNumber: body.registrationNumber,
|
||||
plan: body.plan,
|
||||
billingPeriod: body.billingPeriod,
|
||||
preferredLanguage: body.preferredLanguage,
|
||||
firstName: body.firstName,
|
||||
lastName: body.lastName,
|
||||
passwordHash,
|
||||
now,
|
||||
trialEndAt,
|
||||
}));
|
||||
const lang = (0, notificationLocalizationService_1.coerceNotificationLocale)(body.preferredLanguage);
|
||||
const emailResult = await (0, notificationService_1.sendNotification)({
|
||||
type: 'ACCOUNT_CREATED',
|
||||
companyId: result.company.id,
|
||||
employeeId: result.employee.id,
|
||||
email: body.email,
|
||||
channels: ['EMAIL', 'IN_APP'],
|
||||
locale: lang,
|
||||
templateKey: 'account.created',
|
||||
templateVariables: {
|
||||
firstName: body.firstName,
|
||||
companyName: body.companyName,
|
||||
planName: (0, notificationLocalizationService_1.localizePlanName)(body.plan, lang),
|
||||
billingPeriodLabel: (0, notificationLocalizationService_1.localizeBillingPeriod)(body.billingPeriod, lang),
|
||||
currency: body.currency,
|
||||
paymentProvider: body.paymentProvider,
|
||||
trialEndDate: trialEndAt,
|
||||
},
|
||||
}).catch(() => []);
|
||||
const emailDelivery = emailResult.find((entry) => entry.channel === 'EMAIL');
|
||||
return (0, auth_presenter_1.presentCompanySignup)({
|
||||
company: result.company,
|
||||
trialEndAt,
|
||||
emailDelivery,
|
||||
});
|
||||
}
|
||||
function completeSignupDisabled() {
|
||||
throw new errors_1.AppError('Clerk-based signup has been removed. Use /auth/company/signup instead.', 410, 'disabled');
|
||||
}
|
||||
function verifyEmailDisabled() {
|
||||
throw new errors_1.AppError('Email verification resend via Clerk has been removed from this project.', 410, 'disabled');
|
||||
}
|
||||
//# sourceMappingURL=auth.company.service.js.map
|
||||
Reference in New Issue
Block a user