feat(F-151): completed feature
This commit is contained in:
@@ -7,8 +7,11 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { randomUUID } = require('crypto');
|
||||
const argon2 = require('argon2');
|
||||
const { Client } = require('pg');
|
||||
|
||||
const DEFAULT_STORE_ID = '00000000-0000-0000-0000-000000000001';
|
||||
|
||||
// ── Read DATABASE_URL from .env ──────────────────────────────────────────────
|
||||
const envPath = path.join(__dirname, '..', '.env');
|
||||
if (fs.existsSync(envPath)) {
|
||||
@@ -46,6 +49,7 @@ async function seed(client) {
|
||||
console.log('Seeding database...\n');
|
||||
|
||||
// ── Clear existing seed data ──────────────────────────────────────────
|
||||
await sql(client, 'DELETE FROM inventory_movements', [], 'clear-movements');
|
||||
await sql(client, 'DELETE FROM inventory_stock', [], 'clear-stock');
|
||||
await sql(client, 'DELETE FROM pricing_variant_prices', [], 'clear-prices');
|
||||
await sql(client, 'DELETE FROM catalog_product_variants', [], 'clear-variants');
|
||||
@@ -262,8 +266,8 @@ async function seed(client) {
|
||||
);
|
||||
await sql(
|
||||
client,
|
||||
'INSERT INTO inventory_stock (variant_id, available, reserved) VALUES ($1,$2,$3) ON CONFLICT (variant_id) DO UPDATE SET available=EXCLUDED.available, reserved=EXCLUDED.reserved',
|
||||
[variantId, 25, 0],
|
||||
'INSERT INTO inventory_stock (variant_id, store_id, available, reserved) VALUES ($1,$2,$3,$4) ON CONFLICT (variant_id, store_id) DO UPDATE SET available=EXCLUDED.available, reserved=EXCLUDED.reserved',
|
||||
[variantId, DEFAULT_STORE_ID, 25, 0],
|
||||
`stock-${sku}`,
|
||||
);
|
||||
}
|
||||
@@ -291,6 +295,26 @@ async function seed(client) {
|
||||
);
|
||||
console.log('+ 1 shipping zone + 2 methods');
|
||||
|
||||
// ── 5. Backoffice admin ────────────────────────────────────────────
|
||||
const adminEmail = process.env.SEED_ADMIN_EMAIL || 'admin@mdv.local';
|
||||
const adminPassword = process.env.SEED_ADMIN_PASSWORD || 'Admin123456!';
|
||||
if (process.env.NODE_ENV === 'production' && !process.env.SEED_ADMIN_PASSWORD) {
|
||||
throw new Error('SEED_ADMIN_PASSWORD must be set when NODE_ENV=production');
|
||||
}
|
||||
const adminHash = await argon2.hash(adminPassword);
|
||||
await sql(
|
||||
client,
|
||||
`INSERT INTO backoffice_users (email, password_hash, role, mfa_enrolled)
|
||||
VALUES ($1, $2, 'admin', false)
|
||||
ON CONFLICT (email) DO UPDATE
|
||||
SET password_hash = EXCLUDED.password_hash,
|
||||
role = 'admin',
|
||||
updated_at = now()`,
|
||||
[adminEmail, adminHash],
|
||||
'backoffice-admin',
|
||||
);
|
||||
console.log(`+ backoffice admin (${adminEmail})`);
|
||||
|
||||
await client.query('COMMIT');
|
||||
console.log('\nSeed complete!');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { FastifyInstance, FastifyReply } from 'fastify';
|
||||
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
||||
import type { FastifySchema } from 'fastify';
|
||||
import type pg from 'pg';
|
||||
import { z } from 'zod';
|
||||
@@ -123,7 +123,7 @@ export async function registerBackofficeRoutes(
|
||||
const input = parseResult.data;
|
||||
try {
|
||||
const result = await login.execute(input);
|
||||
setCookie(reply, result.token, true);
|
||||
setCookie(reply, result.token, isSecureRequest(request));
|
||||
return reply
|
||||
.code(200)
|
||||
.send({ id: result.user.id, email: result.user.email, role: result.user.role });
|
||||
@@ -142,7 +142,7 @@ export async function registerBackofficeRoutes(
|
||||
app.post('/backoffice/auth/logout', { schema: logoutSchema }, async (request, reply) => {
|
||||
const token = request.cookies[BACKOFFICE_SESSION_COOKIE_NAME];
|
||||
await logout.execute(token);
|
||||
clearCookie(reply, true);
|
||||
clearCookie(reply, isSecureRequest(request));
|
||||
return reply.code(204).send();
|
||||
});
|
||||
|
||||
@@ -159,6 +159,12 @@ export async function registerBackofficeRoutes(
|
||||
});
|
||||
}
|
||||
|
||||
function isSecureRequest(request: FastifyRequest): boolean {
|
||||
const forwardedProto = request.headers['x-forwarded-proto'];
|
||||
const proto = Array.isArray(forwardedProto) ? forwardedProto[0] : forwardedProto;
|
||||
return request.protocol === 'https' || proto === 'https';
|
||||
}
|
||||
|
||||
function setCookie(reply: FastifyReply, token: string, secure: boolean): void {
|
||||
void reply.setCookie(BACKOFFICE_SESSION_COOKIE_NAME, token, {
|
||||
path: '/',
|
||||
|
||||
Reference in New Issue
Block a user