feat: add CPF to user registration and update seed users
Build and Deploy (Gitea) / build-and-deploy (push) Successful in 45s Details

This commit is contained in:
Sidney Gomes 2026-07-21 19:43:45 -03:00
parent 5be0eda2a2
commit f495d94019
4 changed files with 53 additions and 32 deletions

View File

@ -56,9 +56,9 @@ function requireAdmin(req: AuthenticatedRequest, res: Response, next: NextFuncti
// 1. Auth: Register
app.post('/api/auth/register', async (req: Request, res: Response) => {
const { name, email, password, birthDate, whatsapp } = req.body;
const { name, email, password, cpf, birthDate, whatsapp } = req.body;
if (!name || !email || !password || !birthDate || !whatsapp) {
if (!name || !email || !password || !cpf || !birthDate || !whatsapp) {
res.status(400).json({ error: 'Preencha todos os campos obrigatórios' });
return;
}
@ -71,33 +71,34 @@ app.post('/api/auth/register', async (req: Request, res: Response) => {
return;
}
try {
// Generate Asaas Customer ID (Real call if configured, or simulated)
const asaasCustomerId = await AsaasService.createCustomer(name, email);
const salt = bcrypt.genSaltSync(10);
const passwordHash = bcrypt.hashSync(password, salt);
const createdAt = new Date();
// Calculate trial ends at
const trialDays = db.settings?.trialDurationDays || 7;
const trialEndsAt = new Date(createdAt);
trialEndsAt.setDate(trialEndsAt.getDate() + trialDays);
const newUser: User = {
id: `usr_${Math.random().toString(36).substring(2, 9)}`,
name,
email: email.toLowerCase(),
password: passwordHash,
role: 'student',
subscriptionStatus: 'TRIAL', // Defaults to trial
asaasCustomerId,
birthDate,
whatsapp,
trialEndsAt: trialEndsAt.toISOString(),
createdAt: createdAt.toISOString()
};
try {
// Generate Asaas Customer ID (Real call if configured, or simulated)
const asaasCustomerId = await AsaasService.createCustomer(name, email, cpf);
const salt = bcrypt.genSaltSync(10);
const passwordHash = bcrypt.hashSync(password, salt);
const createdAt = new Date();
// Calculate trial ends at
const trialDays = db.settings?.trialDurationDays || 7;
const trialEndsAt = new Date(createdAt);
trialEndsAt.setDate(trialEndsAt.getDate() + trialDays);
const newUser: User = {
id: `usr_${Math.random().toString(36).substring(2, 9)}`,
name,
email: email.toLowerCase(),
password: passwordHash,
role: 'student',
subscriptionStatus: 'TRIAL', // Defaults to trial
asaasCustomerId,
cpf,
birthDate,
whatsapp,
trialEndsAt: trialEndsAt.toISOString(),
createdAt: createdAt.toISOString()
};
db.users.push(newUser);
saveDb(db);
@ -336,7 +337,7 @@ app.post('/api/courses/:id/unlock', authenticateToken, checkoutRateLimiter, asyn
customerId = null;
}
if (!customerId) {
customerId = await AsaasService.createCustomer(user.name, user.email);
customerId = await AsaasService.createCustomer(user.name, user.email, user.cpf);
user.asaasCustomerId = customerId;
}
@ -520,7 +521,7 @@ app.post('/api/subscription/subscribe', authenticateToken, async (req: Authentic
customerId = null;
}
if (!customerId) {
customerId = await AsaasService.createCustomer(user.name, user.email);
customerId = await AsaasService.createCustomer(user.name, user.email, user.cpf);
user.asaasCustomerId = customerId;
}

View File

@ -35,6 +35,7 @@ export default function App() {
const [regName, setRegName] = useState('');
const [regEmail, setRegEmail] = useState('');
const [regPassword, setRegPassword] = useState('');
const [regCpf, setRegCpf] = useState('');
const [regBirthDate, setRegBirthDate] = useState('');
const [regWhatsapp, setRegWhatsapp] = useState('');
const [authError, setAuthError] = useState<string | null>(null);
@ -134,7 +135,7 @@ export default function App() {
const res = await fetch('/api/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: regName, email: regEmail, password: regPassword, birthDate: regBirthDate, whatsapp: regWhatsapp })
body: JSON.stringify({ name: regName, email: regEmail, password: regPassword, cpf: regCpf, birthDate: regBirthDate, whatsapp: regWhatsapp })
});
const data = await res.json();
@ -355,6 +356,18 @@ export default function App() {
/>
</div>
<div className="space-y-1">
<label className="text-[10px] text-zinc-400 font-bold uppercase tracking-wider">CPF</label>
<input
type="text"
required
value={regCpf}
onChange={(e) => setRegCpf(e.target.value)}
placeholder="000.000.000-00"
className="w-full glass-input rounded-lg p-3 text-xs text-white focus:outline-none"
/>
</div>
<div className="space-y-1">
<label className="text-[10px] text-zinc-400 font-bold uppercase tracking-wider">Data de Nascimento</label>
<input

View File

@ -86,6 +86,7 @@ function createInitialDb(): DatabaseSchema {
role: 'admin',
subscriptionStatus: 'ACTIVE',
asaasCustomerId: null,
cpf: '111.111.111-11',
unlockedCourses: [],
createdAt: now
},
@ -97,6 +98,7 @@ function createInitialDb(): DatabaseSchema {
role: 'student',
subscriptionStatus: 'ACTIVE',
asaasCustomerId: 'cus_00001',
cpf: '111.111.111-11',
unlockedCourses: ['crs_excel'], // Excel starts unlocked for Joao
createdAt: new Date(Date.now() - 30 * 24 * 3600 * 1000).toISOString()
},
@ -108,6 +110,7 @@ function createInitialDb(): DatabaseSchema {
role: 'student',
subscriptionStatus: 'ACTIVE',
asaasCustomerId: 'cus_00002',
cpf: '111.111.111-11',
unlockedCourses: [],
createdAt: new Date(Date.now() - 15 * 24 * 3600 * 1000).toISOString()
},
@ -119,6 +122,7 @@ function createInitialDb(): DatabaseSchema {
role: 'student',
subscriptionStatus: 'OVERDUE',
asaasCustomerId: 'cus_00003',
cpf: '111.111.111-11',
unlockedCourses: [],
createdAt: new Date(Date.now() - 45 * 24 * 3600 * 1000).toISOString()
},
@ -130,6 +134,7 @@ function createInitialDb(): DatabaseSchema {
role: 'student',
subscriptionStatus: 'CANCELED',
asaasCustomerId: 'cus_00004',
cpf: '111.111.111-11',
unlockedCourses: [],
createdAt: new Date(Date.now() - 60 * 24 * 3600 * 1000).toISOString()
},
@ -141,6 +146,7 @@ function createInitialDb(): DatabaseSchema {
role: 'student',
subscriptionStatus: 'ACTIVE',
asaasCustomerId: 'cus_test',
cpf: '111.111.111-11',
unlockedCourses: [], // Starts with only the free courses unlocked
createdAt: now
}

View File

@ -10,6 +10,7 @@ export interface User {
subscriptionStatus: SubscriptionStatus;
asaasCustomerId: string | null;
unlockedCourses?: string[]; // IDs of courses unlocked individually
cpf?: string;
birthDate?: string;
whatsapp?: string;
trialEndsAt?: string | null;