mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Replaces the mailto: link with a server-side send, so the message carries the store's signature and logo instead of depending on each workstation's Outlook. Store record (groups): - address, phone and logo (data URI, 200 KB cap) feed the mail signature - per-store SMTP settings: host, port, SSL/STARTTLS, credentials, sender address and display name, with an enable switch - "test connection" button verifies the server without sending anything - the empty-form literal, previously repeated five times, becomes one constant Sending: - nodemailer transport built per store from its own settings - multipart mail: plain-text alternative plus HTML whose signature embeds the logo as an inline CID attachment, which Outlook renders without the remote image blocking that a data: URI would hit - delivery details are HTML-escaped - Reply-To set to the store address; the row shows a spinner and refuses a second click while a send is in flight Credentials: - the SMTP password is never returned to the client; a response-layer sanitizer strips it from every /api payload and replaces it with a smtpPasswordSet flag, covering the ten-plus queries that join full group rows into deliveries, orders and user relations - an empty password field on save keeps the stored one rather than clearing it Verified end-to-end against a local SMTP server: transport, auth, From/Reply-To, multipart structure and the inline logo attachment. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FHdE9nEh8zHhQNGpCgrtYe
137 lines
4.3 KiB
JSON
137 lines
4.3 KiB
JSON
{
|
|
"name": "rest-express",
|
|
"version": "1.0.0",
|
|
"type": "module",
|
|
"license": "MIT",
|
|
"scripts": {
|
|
"dev": "NODE_ENV=development tsx server/index.ts",
|
|
"build": "vite build && tsc --project tsconfig.server.json",
|
|
"start": "NODE_ENV=production node dist/server/index.js",
|
|
"check": "tsc",
|
|
"db:push": "drizzle-kit push"
|
|
},
|
|
"dependencies": {
|
|
"@hookform/resolvers": "^3.10.0",
|
|
"@jridgewell/trace-mapping": "^0.3.25",
|
|
"@neondatabase/serverless": "^0.10.4",
|
|
"@radix-ui/react-accordion": "^1.2.4",
|
|
"@radix-ui/react-alert-dialog": "^1.1.7",
|
|
"@radix-ui/react-aspect-ratio": "^1.1.3",
|
|
"@radix-ui/react-avatar": "^1.1.4",
|
|
"@radix-ui/react-checkbox": "^1.1.5",
|
|
"@radix-ui/react-collapsible": "^1.1.4",
|
|
"@radix-ui/react-context-menu": "^2.2.7",
|
|
"@radix-ui/react-dialog": "^1.1.7",
|
|
"@radix-ui/react-dropdown-menu": "^2.1.7",
|
|
"@radix-ui/react-hover-card": "^1.1.7",
|
|
"@radix-ui/react-label": "^2.1.3",
|
|
"@radix-ui/react-menubar": "^1.1.7",
|
|
"@radix-ui/react-navigation-menu": "^1.2.6",
|
|
"@radix-ui/react-popover": "^1.1.7",
|
|
"@radix-ui/react-progress": "^1.1.3",
|
|
"@radix-ui/react-radio-group": "^1.2.4",
|
|
"@radix-ui/react-scroll-area": "^1.2.4",
|
|
"@radix-ui/react-select": "^2.1.7",
|
|
"@radix-ui/react-separator": "^1.1.3",
|
|
"@radix-ui/react-slider": "^1.2.4",
|
|
"@radix-ui/react-slot": "^1.2.0",
|
|
"@radix-ui/react-switch": "^1.1.4",
|
|
"@radix-ui/react-tabs": "^1.1.4",
|
|
"@radix-ui/react-toast": "^1.2.7",
|
|
"@radix-ui/react-toggle": "^1.1.3",
|
|
"@radix-ui/react-toggle-group": "^1.1.3",
|
|
"@radix-ui/react-tooltip": "^1.2.0",
|
|
"@tanstack/react-query": "^5.60.5",
|
|
"@types/bcrypt": "^6.0.0",
|
|
"@types/busboy": "^1.5.4",
|
|
"@types/cookie-parser": "^1.4.10",
|
|
"@types/form-data": "^2.2.1",
|
|
"@types/memoizee": "^0.4.12",
|
|
"@types/multer": "^2.0.0",
|
|
"@types/pg": "^8.15.4",
|
|
"@types/validator": "^13.15.10",
|
|
"bcrypt": "^6.0.0",
|
|
"busboy": "^1.6.0",
|
|
"caniuse-lite": "^1.0.30001727",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"cmdk": "^1.1.1",
|
|
"connect-pg-simple": "^10.0.0",
|
|
"cookie-parser": "^1.4.7",
|
|
"csrf-csrf": "^4.0.3",
|
|
"date-fns": "^3.6.0",
|
|
"drizzle-orm": "^0.39.1",
|
|
"drizzle-zod": "^0.7.0",
|
|
"embla-carousel-react": "^8.6.0",
|
|
"encoding": "^0.1.13",
|
|
"express": "^4.21.2",
|
|
"express-rate-limit": "^7.5.1",
|
|
"express-session": "^1.18.1",
|
|
"form-data": "^4.0.4",
|
|
"framer-motion": "^11.13.1",
|
|
"iconv-lite": "^0.6.3",
|
|
"input-otp": "^1.4.2",
|
|
"jsbarcode": "^3.12.1",
|
|
"lucide-react": "^0.453.0",
|
|
"memoizee": "^0.4.17",
|
|
"memorystore": "^1.6.7",
|
|
"multer": "^2.0.2",
|
|
"nanoid": "^5.1.5",
|
|
"next-themes": "^0.4.6",
|
|
"node-cron": "^4.2.1",
|
|
"node-fetch": "^3.3.2",
|
|
"nodemailer": "^9.0.5",
|
|
"openid-client": "^6.7.1",
|
|
"passport": "^0.7.0",
|
|
"passport-local": "^1.0.0",
|
|
"pg": "^8.16.3",
|
|
"react": "^18.3.1",
|
|
"react-day-picker": "^8.10.1",
|
|
"react-dom": "^18.3.1",
|
|
"react-hook-form": "^7.55.0",
|
|
"react-icons": "^5.4.0",
|
|
"react-resizable-panels": "^2.1.7",
|
|
"recharts": "^2.15.2",
|
|
"tailwind-merge": "^2.6.0",
|
|
"tailwindcss-animate": "^1.0.7",
|
|
"tw-animate-css": "^1.2.5",
|
|
"validator": "^13.15.26",
|
|
"vaul": "^1.1.2",
|
|
"wouter": "^3.3.5",
|
|
"ws": "^8.18.0",
|
|
"xlsx": "^0.18.5",
|
|
"zod": "^3.24.2",
|
|
"zod-validation-error": "^3.4.0"
|
|
},
|
|
"devDependencies": {
|
|
"@replit/vite-plugin-cartographer": "^0.2.7",
|
|
"@replit/vite-plugin-runtime-error-modal": "^0.0.3",
|
|
"@tailwindcss/typography": "^0.5.15",
|
|
"@tailwindcss/vite": "^4.1.3",
|
|
"@types/connect-pg-simple": "^7.0.3",
|
|
"@types/date-fns": "^2.5.3",
|
|
"@types/express": "^4.17.21",
|
|
"@types/express-session": "^1.18.0",
|
|
"@types/node": "^20.16.11",
|
|
"@types/node-fetch": "^2.6.13",
|
|
"@types/nodemailer": "^8.0.1",
|
|
"@types/passport": "^1.0.16",
|
|
"@types/passport-local": "^1.0.38",
|
|
"@types/react": "^18.3.27",
|
|
"@types/react-dom": "^18.3.7",
|
|
"@types/ws": "^8.5.13",
|
|
"@vitejs/plugin-react": "^4.3.2",
|
|
"autoprefixer": "^10.4.20",
|
|
"drizzle-kit": "^0.30.4",
|
|
"esbuild": "^0.25.0",
|
|
"postcss": "^8.4.47",
|
|
"tailwindcss": "^3.4.17",
|
|
"tsx": "^4.19.1",
|
|
"typescript": "5.6.3",
|
|
"vite": "^5.4.19"
|
|
},
|
|
"optionalDependencies": {
|
|
"bufferutil": "^4.0.8"
|
|
}
|
|
}
|