Spaces:
Running
Running
Download src/config/env.js from AndreaNotes1/auth-app-api: direct link, hf CLI and curl.
- Browser
- Download file 4.41 kB
-
https://huggingface.co/spaces/AndreaNotes1/auth-app-api/resolve/main/src/config/env.js
- Command line
-
hf download hf://spaces/AndreaNotes1/auth-app-api/src/config/env.js
-
curl -L -o env.js https://huggingface.co/spaces/AndreaNotes1/auth-app-api/resolve/main/src/config/env.js
4.41 kB
| require("dotenv").config(); | |
| // Fail fast if critical secrets are missing or left as placeholders — this | |
| // is a cheap, high-value guard against accidentally deploying with | |
| // insecure defaults. | |
| const REQUIRED_IN_PRODUCTION = [ | |
| "MONGODB_URI", | |
| "JWT_ACCESS_SECRET", | |
| "JWT_REFRESH_SECRET", | |
| "FIELD_ENCRYPTION_KEY", | |
| "SMTP_HOST", | |
| "SMTP_USER", | |
| "SMTP_PASS", | |
| "CLOUDINARY_CLOUD_NAME", | |
| "CLOUDINARY_API_KEY", | |
| "CLOUDINARY_API_SECRET", | |
| ]; | |
| const env = { | |
| nodeEnv: process.env.NODE_ENV || "development", | |
| port: parseInt(process.env.PORT, 10) || 5000, | |
| clientOrigins: (process.env.CLIENT_ORIGINS || "http://localhost:5173") | |
| .split(",") | |
| .map((s) => s.trim()) | |
| .filter(Boolean), | |
| // Base URL used to build absolute redirect links (e.g. Payoneer | |
| // Checkout success/cancel URLs) sent to third-party APIs — falls | |
| // back to the first allowed CORS origin if not set explicitly. | |
| frontendUrl: process.env.FRONTEND_URL || (process.env.CLIENT_ORIGINS || "http://localhost:5173").split(",")[0].trim(), | |
| mongoUri: process.env.MONGODB_URI, | |
| jwtAccessSecret: process.env.JWT_ACCESS_SECRET, | |
| jwtRefreshSecret: process.env.JWT_REFRESH_SECRET, | |
| jwtAccessExpiresIn: process.env.JWT_ACCESS_EXPIRES_IN || "15m", | |
| jwtRefreshExpiresIn: process.env.JWT_REFRESH_EXPIRES_IN || "7d", | |
| fieldEncryptionKey: process.env.FIELD_ENCRYPTION_KEY, | |
| smtp: { | |
| host: process.env.SMTP_HOST, | |
| port: parseInt(process.env.SMTP_PORT, 10) || 587, | |
| secure: process.env.SMTP_SECURE === "true", | |
| user: process.env.SMTP_USER, | |
| pass: process.env.SMTP_PASS, | |
| }, | |
| emailFrom: process.env.EMAIL_FROM || "Aynwerd Academy <no-reply@aynwerd.com>", | |
| adminNotifyEmail: process.env.ADMIN_NOTIFY_EMAIL, | |
| bank: { | |
| name: process.env.BANK_NAME || "", | |
| accountName: process.env.BANK_ACCOUNT_NAME || "", | |
| accountNumber: process.env.BANK_ACCOUNT_NUMBER || "", | |
| routingNumber: process.env.BANK_ROUTING_NUMBER || "", | |
| swiftBic: process.env.BANK_SWIFT_BIC || "", | |
| iban: process.env.BANK_IBAN || "", | |
| address: process.env.BANK_ADDRESS || "", | |
| }, | |
| payoneer: { | |
| paymentUrl: process.env.PAYONEER_PAYMENT_URL || "https://www.payoneer.com/", | |
| accountEmail: process.env.PAYONEER_ACCOUNT_EMAIL || "", | |
| }, | |
| // Payoneer Checkout (automated card/wallet checkout) — separate from | |
| // the manual "payoneer" bank-style transfer above. These credentials | |
| // are issued directly by Payoneer only after your business is | |
| // approved as a Payoneer Checkout merchant; see | |
| // utils/payoneerCheckout.js for what's still a placeholder pending | |
| // that approval and your integration-specific API docs from them. | |
| payoneerCheckout: { | |
| apiBase: process.env.PAYONEER_CHECKOUT_API_BASE || "", | |
| apiKey: process.env.PAYONEER_CHECKOUT_API_KEY || "", | |
| apiSecret: process.env.PAYONEER_CHECKOUT_API_SECRET || "", | |
| webhookSecret: process.env.PAYONEER_CHECKOUT_WEBHOOK_SECRET || "", | |
| }, | |
| seedAdmin: { | |
| name: process.env.SEED_ADMIN_NAME || "Site Admin", | |
| email: process.env.SEED_ADMIN_EMAIL, | |
| password: process.env.SEED_ADMIN_PASSWORD, | |
| }, | |
| // Cloudinary: free-tier media storage used exclusively for admin-uploaded | |
| // course videos/documents. Files are uploaded with delivery type | |
| // "authenticated" so nothing is reachable without a freshly signed, | |
| // short-lived URL minted server-side for a verified, paying learner. | |
| cloudinary: { | |
| cloudName: process.env.CLOUDINARY_CLOUD_NAME, | |
| apiKey: process.env.CLOUDINARY_API_KEY, | |
| apiSecret: process.env.CLOUDINARY_API_SECRET, | |
| }, | |
| }; | |
| function assertProductionSafety() { | |
| if (env.nodeEnv !== "production") return; | |
| const missing = REQUIRED_IN_PRODUCTION.filter((key) => { | |
| const value = process.env[key]; | |
| return !value || value.startsWith("replace_with_") || value.includes("<"); | |
| }); | |
| if (missing.length > 0) { | |
| // eslint-disable-next-line no-console | |
| console.error( | |
| `FATAL: refusing to start in production with missing/placeholder env vars: ${missing.join(", ")}` | |
| ); | |
| process.exit(1); | |
| } | |
| if (Buffer.from(env.fieldEncryptionKey || "", "hex").length !== 32) { | |
| // eslint-disable-next-line no-console | |
| console.error("FATAL: FIELD_ENCRYPTION_KEY must be a 32-byte (64 hex character) value."); | |
| process.exit(1); | |
| } | |
| } | |
| module.exports = { env, assertProductionSafety }; | |