245 lines
8.9 KiB
TypeScript
245 lines
8.9 KiB
TypeScript
import {
|
|
AppConfig,
|
|
CoingeckoConfig,
|
|
EncryptionConfig,
|
|
InvoiceConfig,
|
|
JwtConfig,
|
|
CoinPaprikaConfig,
|
|
MulterConfig,
|
|
OrderConfig,
|
|
PostgresConfig,
|
|
ShopSettingsConfig
|
|
} from '../types/Config';
|
|
import { ElectrumNetwork } from '../types/ElectrumNetwork';
|
|
import { ElectrumWalletConfig } from '../types/ElectrumWalletConfig';
|
|
import { MoneroNetwork } from '../types/MoneroNetwork';
|
|
import { MoneroWalletConfig } from '../types/MoneroWalletConfig';
|
|
import { ConfirmationTier } from '../types/ConfirmationTier';
|
|
import { NodeEnv } from '../types/NodeEnv';
|
|
import { ShopFiatCurrency } from '../types/ShopFiatCurrency';
|
|
import { PaymentMethod } from '../modules/payment/types/PaymentMethod';
|
|
import { SimplexConfig } from '../types/SimplexConfig';
|
|
import { parseEnabledPaymentMethods } from '../utils/payment/parseEnabledPaymentMethods';
|
|
|
|
const env = (key: string): string => process.env[key] || '';
|
|
|
|
const envInt = (key: string): number => parseInt(env(key), 10);
|
|
|
|
const isEnabled = (key: string): boolean => env(key) === 'true';
|
|
|
|
export const getPostgresConfig = (): PostgresConfig => {
|
|
return {
|
|
type: 'postgres',
|
|
url: `postgres://${env('POSTGRES_USER')}:${env('POSTGRES_PASSWORD')}@${env('POSTGRES_HOST')}:${env('POSTGRES_PORT')}/${env('POSTGRES_DB')}`,
|
|
host: env('POSTGRES_HOST'),
|
|
username: env('POSTGRES_USER'),
|
|
password: env('POSTGRES_PASSWORD'),
|
|
port: envInt('POSTGRES_PORT'),
|
|
database: env('POSTGRES_DB'),
|
|
entities: [__dirname + '/../modules/**/entities/*{.ts,.js}'],
|
|
migrations: [__dirname + '/../database/migrations/*{.ts,.js}'],
|
|
migrationsRun: isEnabled('POSTGRES_MIGRATIONS_RUN')
|
|
};
|
|
};
|
|
|
|
export const getAppConfig = (): AppConfig => {
|
|
const rawOrigins = env('CORS_ORIGINS');
|
|
|
|
return {
|
|
port: envInt('BACKEND_PORT'),
|
|
nodeEnv: env('NODE_ENV') as NodeEnv,
|
|
corsOrigins: rawOrigins
|
|
.split(',')
|
|
.map(o => o.trim())
|
|
.filter(Boolean),
|
|
cmsPassword: env('CMS_PASSWORD'),
|
|
captcha: {
|
|
length: envInt('CAPTCHA_LENGTH')
|
|
},
|
|
throttle: {
|
|
ttlMs: envInt('THROTTLE_TTL_MS'),
|
|
limit: envInt('THROTTLE_LIMIT')
|
|
},
|
|
signedCookie: {
|
|
jwtSecret: env('SIGNED_COOKIE_JWT_SECRET'),
|
|
feedback: {
|
|
cookieName: env('SIGNED_COOKIE_FEEDBACK_NAME'),
|
|
expiresInMs: envInt('SIGNED_COOKIE_FEEDBACK_EXPIRES_IN_MS')
|
|
},
|
|
cart: {
|
|
cookieName: env('SIGNED_COOKIE_CART_NAME'),
|
|
expiresInMs: envInt('SIGNED_COOKIE_CART_EXPIRES_IN_MS')
|
|
},
|
|
captcha: {
|
|
cookieName: env('SIGNED_COOKIE_CAPTCHA_NAME'),
|
|
expiresInMs: envInt('SIGNED_COOKIE_CAPTCHA_EXPIRES_IN_MS')
|
|
},
|
|
discount: {
|
|
cookieName: env('SIGNED_COOKIE_DISCOUNT_NAME'),
|
|
expiresInMs: envInt('SIGNED_COOKIE_DISCOUNT_EXPIRES_IN_MS')
|
|
},
|
|
error: {
|
|
cookieName: env('SIGNED_COOKIE_ERROR_NAME'),
|
|
expiresInMs: envInt('SIGNED_COOKIE_ERROR_EXPIRES_IN_MS')
|
|
},
|
|
checkoutSession: {
|
|
cookieName: env('SIGNED_COOKIE_CHECKOUT_SESSION_NAME'),
|
|
expiresInMs: envInt('ORDER_CHECKOUT_VALIDITY_MS')
|
|
},
|
|
orderAuth: {
|
|
cookieName: env('SIGNED_COOKIE_ORDER_AUTH_NAME'),
|
|
expiresInMs: envInt('SIGNED_COOKIE_ORDER_AUTH_EXPIRES_IN_MS')
|
|
},
|
|
theme: {
|
|
cookieName: env('SIGNED_COOKIE_THEME_NAME'),
|
|
expiresInMs: envInt('SIGNED_COOKIE_THEME_EXPIRES_IN_MS')
|
|
}
|
|
},
|
|
validation: {
|
|
productTitleMaxLength: envInt('VALIDATION_PRODUCT_TITLE_MAX_LENGTH'),
|
|
categoryNameMaxLength: envInt('VALIDATION_CATEGORY_NAME_MAX_LENGTH'),
|
|
discountCodeMaxLength: envInt('VALIDATION_DISCOUNT_CODE_MAX_LENGTH'),
|
|
variantImagesMax: envInt('VALIDATION_VARIANT_IMAGES_MAX'),
|
|
digitalStockAttachmentsMax: envInt('VALIDATION_DIGITAL_STOCK_ATTACHMENTS_MAX'),
|
|
shippingNoteMinLength: envInt('VALIDATION_SHIPPING_NOTE_MIN_LENGTH'),
|
|
shippingNoteMaxLength: envInt('VALIDATION_SHIPPING_NOTE_MAX_LENGTH'),
|
|
orderMessageMaxLength: envInt('VALIDATION_ORDER_MESSAGE_MAX_LENGTH'),
|
|
bitcoinWithdrawMaxFeeRateSatVbyte: envInt('VALIDATION_BITCOIN_WITHDRAW_MAX_FEE_RATE_SAT_VBYTE')
|
|
}
|
|
};
|
|
};
|
|
|
|
export const getJwtConfig = (): JwtConfig => {
|
|
return {
|
|
secret: env('JWT_SECRET'),
|
|
expiresInMs: envInt('JWT_EXPIRES_IN_MS')
|
|
};
|
|
};
|
|
|
|
export const getProductThumbMulterConfig = (): MulterConfig => {
|
|
const allowedMimes = env('MULTER_PRODUCT_THUMB_ALLOWED_MIMES')
|
|
.split(',')
|
|
.map(v => v.trim())
|
|
.filter(Boolean);
|
|
|
|
const maxFileBytes = envInt('MULTER_PRODUCT_THUMB_MAX_FILE_BYTES');
|
|
|
|
return { allowedMimes, maxFileBytes };
|
|
};
|
|
|
|
export const getShopLogoMulterConfig = (): MulterConfig => {
|
|
const allowedMimes = env('MULTER_SHOP_LOGO_ALLOWED_MIMES')
|
|
.split(',')
|
|
.map(v => v.trim())
|
|
.filter(Boolean);
|
|
|
|
const maxFileBytes = envInt('MULTER_SHOP_LOGO_MAX_FILE_BYTES');
|
|
|
|
return { allowedMimes, maxFileBytes };
|
|
};
|
|
|
|
export const getShopFaviconMulterConfig = (): MulterConfig => {
|
|
const allowedMimes = env('MULTER_SHOP_FAVICON_ALLOWED_MIMES')
|
|
.split(',')
|
|
.map(v => v.trim())
|
|
.filter(Boolean);
|
|
|
|
const maxFileBytes = envInt('MULTER_SHOP_FAVICON_MAX_FILE_BYTES');
|
|
|
|
return { allowedMimes, maxFileBytes };
|
|
};
|
|
|
|
export const getDigitalStockAttachmentMulterConfig = (): MulterConfig => {
|
|
const allowedMimes = env('MULTER_DIGITAL_STOCK_ATTACHMENT_ALLOWED_MIMES')
|
|
.split(',')
|
|
.map(v => v.trim())
|
|
.filter(Boolean);
|
|
|
|
const maxFileBytes = envInt('MULTER_DIGITAL_STOCK_ATTACHMENT_MAX_FILE_BYTES');
|
|
|
|
return { allowedMimes, maxFileBytes };
|
|
};
|
|
|
|
export const getCoingeckoConfig = (): CoingeckoConfig => {
|
|
return {
|
|
apiBaseUrl: env('COINGECKO_API_BASE_URL'),
|
|
rateFetchTimeoutMs: envInt('COINGECKO_RATE_FETCH_TIMEOUT_MS')
|
|
};
|
|
};
|
|
|
|
export const getCoinPaprikaConfig = (): CoinPaprikaConfig => {
|
|
return {
|
|
apiBaseUrl: env('COINPAPRIKA_API_BASE_URL'),
|
|
rateFetchTimeoutMs: envInt('COINPAPRIKA_RATE_FETCH_TIMEOUT_MS')
|
|
};
|
|
};
|
|
|
|
export const getEncryptionConfig = (): EncryptionConfig => ({
|
|
keyBase64: env('BASE64_ENCRYPTION_KEY')
|
|
});
|
|
|
|
export const getShopSettingsConfig = (): ShopSettingsConfig => ({
|
|
shopName: env('SHOP_NAME'),
|
|
shopFiatCurrency: env('SHOP_FIAT_CURRENCY') as ShopFiatCurrency,
|
|
enabledPaymentMethods: parseEnabledPaymentMethods(env('PAYMENT_METHODS_ENABLED')),
|
|
monero: {
|
|
confirmationTiers: JSON.parse(env('MONERO_CONFIRMATION_TIERS')) as ConfirmationTier[]
|
|
},
|
|
bitcoin: {
|
|
confirmationTiers: JSON.parse(env('BITCOIN_CONFIRMATION_TIERS')) as ConfirmationTier[]
|
|
}
|
|
});
|
|
|
|
export const getOrderConfig = (): OrderConfig => ({
|
|
checkoutValidityMs: envInt('ORDER_CHECKOUT_VALIDITY_MS'),
|
|
shippingPaymentValidityMs: envInt('ORDER_SHIPPING_PAYMENT_VALIDITY_MS'),
|
|
checkoutStatusRefreshSec: envInt('ORDER_CHECKOUT_STATUS_REFRESH_SEC'),
|
|
dataRetentionDays: envInt('ORDER_DATA_RETENTION_DAYS')
|
|
});
|
|
|
|
export const getInvoiceConfig = (): InvoiceConfig => ({
|
|
minByMethod: {
|
|
[PaymentMethod.Xmr]: String(envInt('MONERO_MIN_INCOMING_ATOMIC')),
|
|
[PaymentMethod.Btc]: String(envInt('BITCOIN_MIN_INCOMING_ATOMIC'))
|
|
}
|
|
});
|
|
|
|
export const getMoneroWalletConfig = (): MoneroWalletConfig => ({
|
|
network: env('MONERO_NETWORK') as MoneroNetwork,
|
|
rpcUrl: `http://${env('MONERO_WALLET_RPC_HOST')}:${envInt('MONERO_WALLET_RPC_PORT')}/json_rpc`,
|
|
daemonRpcUrl: `http://${env('MONERO_DAEMON_ADDRESS')}/json_rpc`,
|
|
username: env('MONERO_WALLET_RPC_USERNAME'),
|
|
password: env('MONERO_WALLET_RPC_PASSWORD'),
|
|
rpcTimeoutMs: envInt('MONERO_WALLET_RPC_TIMEOUT_MS')
|
|
});
|
|
|
|
export const getElectrumWalletConfig = (): ElectrumWalletConfig => ({
|
|
network: env('ELECTRUM_NETWORK') as ElectrumNetwork,
|
|
server: env('ELECTRUM_SERVER'),
|
|
rpcUrl: `http://${env('ELECTRUM_DAEMON_HOST')}:${envInt('ELECTRUM_DAEMON_PORT')}`,
|
|
username: env('ELECTRUM_DAEMON_RPC_USER'),
|
|
password: env('ELECTRUM_DAEMON_RPC_PASSWORD'),
|
|
walletPassword: env('ELECTRUM_WALLET_PASSWORD'),
|
|
rpcTimeoutMs: envInt('ELECTRUM_DAEMON_RPC_TIMEOUT_MS')
|
|
});
|
|
|
|
export const getSimplexConfig = (): SimplexConfig => ({
|
|
wsUrl: env('SIMPLEX_WS_URL'),
|
|
botDisplayName: env('SIMPLEX_BOT_DISPLAY_NAME')
|
|
});
|
|
|
|
export default () => ({
|
|
postgres: getPostgresConfig(),
|
|
app: getAppConfig(),
|
|
jwt: getJwtConfig(),
|
|
coingecko: getCoingeckoConfig(),
|
|
coinPaprika: getCoinPaprikaConfig(),
|
|
encryption: getEncryptionConfig(),
|
|
shopSettings: getShopSettingsConfig(),
|
|
order: getOrderConfig(),
|
|
invoice: getInvoiceConfig(),
|
|
moneroWallet: getMoneroWalletConfig(),
|
|
electrumWallet: getElectrumWalletConfig(),
|
|
simplex: getSimplexConfig()
|
|
});
|