Add backend unit/integration tests, Playwright e2e tests, README, cookie Secure fix
SonarQube Analysis / sonarqube (push) Successful in 4m20s
SonarQube Analysis / sonarqube (push) Successful in 4m20s
This commit is contained in:
@@ -4,17 +4,16 @@ import crypto from 'node:crypto';
|
||||
import { pool } from '../db';
|
||||
import { requireCustomer } from '../middleware/customerAuth';
|
||||
import { sendMail } from '../mailer';
|
||||
import { MARKETING_CONSENT_TEXT, isValidEmail } from '../utils';
|
||||
|
||||
const router = Router();
|
||||
|
||||
const SESSION_DAYS = 30;
|
||||
const MARKETING_CONSENT_TEXT =
|
||||
'I want to receive occasional emails about new one-of-a-kind items from Redefined Designs. I can unsubscribe at any time.';
|
||||
|
||||
function setSessionCookie(res: Response, token: string) {
|
||||
res.cookie('rd_session', token, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
secure: process.env.NODE_ENV === 'production',
|
||||
sameSite: 'lax',
|
||||
maxAge: SESSION_DAYS * 24 * 60 * 60 * 1000
|
||||
});
|
||||
@@ -43,7 +42,7 @@ function publicCustomer(c: any) {
|
||||
|
||||
router.post('/register', async (req: Request, res: Response) => {
|
||||
const { email, password, name, marketingConsent } = req.body;
|
||||
if (!email || !password || String(password).length < 8) {
|
||||
if (!email || !isValidEmail(String(email)) || !password || String(password).length < 8) {
|
||||
return res.status(400).json({ error: 'valid email and password (min 8 chars) required' });
|
||||
}
|
||||
const normalizedEmail = String(email).toLowerCase().trim();
|
||||
@@ -143,7 +142,6 @@ router.post('/change-password', requireCustomer, async (req: Request, res: Respo
|
||||
res.status(204).end();
|
||||
});
|
||||
|
||||
// Explicit, revocable marketing consent (GDPR Art. 7 / ePrivacy)
|
||||
router.post('/me/consent', requireCustomer, async (req: Request, res: Response) => {
|
||||
const consent = !!req.body.marketingConsent;
|
||||
await pool.query(
|
||||
@@ -163,7 +161,6 @@ router.get('/me/orders', requireCustomer, async (req: Request, res: Response) =>
|
||||
res.json(rows);
|
||||
});
|
||||
|
||||
// GDPR right to access / data portability
|
||||
router.get('/me/export', requireCustomer, async (req: Request, res: Response) => {
|
||||
const { rows: customerRows } = await pool.query(`SELECT * FROM customers WHERE id = $1`, [req.customerId]);
|
||||
const { rows: orderRows } = await pool.query(`SELECT * FROM orders WHERE customer_id = $1`, [req.customerId]);
|
||||
@@ -175,7 +172,6 @@ router.get('/me/export', requireCustomer, async (req: Request, res: Response) =>
|
||||
});
|
||||
});
|
||||
|
||||
// GDPR right to erasure — order records kept for accounting but stripped of the customer link
|
||||
router.delete('/me', requireCustomer, async (req: Request, res: Response) => {
|
||||
await pool.query(`UPDATE orders SET customer_id = NULL WHERE customer_id = $1`, [req.customerId]);
|
||||
await pool.query(`DELETE FROM customers WHERE id = $1`, [req.customerId]);
|
||||
|
||||
Reference in New Issue
Block a user