@kyro-cms/core 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/WebhookService-BCgL1bLF.d.cts +112 -0
- package/dist/WebhookService-BPVJUgTl.d.ts +112 -0
- package/dist/{base-DlhVlwnN.d.cts → base-B0Y6isUJ.d.cts} +1 -1
- package/dist/{base-CQkFzqQl.d.ts → base-DaP-5PPG.d.ts} +1 -1
- package/dist/bootstrap-BMWVB2T6.cjs +31 -0
- package/dist/{bootstrap-WMWQ4DBX.cjs.map → bootstrap-BMWVB2T6.cjs.map} +1 -1
- package/dist/bootstrap-LL6O7PWO.js +6 -0
- package/dist/{bootstrap-WOVGAKZP.js.map → bootstrap-LL6O7PWO.js.map} +1 -1
- package/dist/{chunk-3VZCX4DF.cjs → chunk-42JPONZU.cjs} +77 -14
- package/dist/chunk-42JPONZU.cjs.map +1 -0
- package/dist/{chunk-3EVLFWH2.cjs → chunk-4M5PHMUE.cjs} +60 -346
- package/dist/chunk-4M5PHMUE.cjs.map +1 -0
- package/dist/chunk-4PWRCMTQ.cjs +15 -0
- package/dist/chunk-4PWRCMTQ.cjs.map +1 -0
- package/dist/chunk-6COM32WF.js +47 -0
- package/dist/chunk-6COM32WF.js.map +1 -0
- package/dist/chunk-6MSSF46R.js +941 -0
- package/dist/chunk-6MSSF46R.js.map +1 -0
- package/dist/{chunk-TZFJMPCH.cjs → chunk-7YITG2US.cjs} +9 -18
- package/dist/chunk-7YITG2US.cjs.map +1 -0
- package/dist/{chunk-A3RQWHKD.cjs → chunk-BLMFBDBG.cjs} +56 -6
- package/dist/chunk-BLMFBDBG.cjs.map +1 -0
- package/dist/{chunk-EINVJPFM.js → chunk-BTOE3VUK.js} +65 -3
- package/dist/chunk-BTOE3VUK.js.map +1 -0
- package/dist/chunk-E5X75WNB.js +497 -0
- package/dist/chunk-E5X75WNB.js.map +1 -0
- package/dist/chunk-E63IF3MD.cjs +951 -0
- package/dist/chunk-E63IF3MD.cjs.map +1 -0
- package/dist/{chunk-K7QF2QCM.cjs → chunk-FTSSDDZQ.cjs} +7 -3
- package/dist/chunk-FTSSDDZQ.cjs.map +1 -0
- package/dist/chunk-G7VZBCD6.cjs +35 -0
- package/dist/{chunk-5BLDMQED.cjs.map → chunk-G7VZBCD6.cjs.map} +1 -1
- package/dist/{chunk-VMSRTAH7.js → chunk-GLCPGZPM.js} +56 -6
- package/dist/chunk-GLCPGZPM.js.map +1 -0
- package/dist/{chunk-V3B25QOK.cjs → chunk-GVFB5C6O.cjs} +74 -2
- package/dist/chunk-GVFB5C6O.cjs.map +1 -0
- package/dist/chunk-HVSQDZZJ.cjs +765 -0
- package/dist/chunk-HVSQDZZJ.cjs.map +1 -0
- package/dist/chunk-HYC4GNHX.js +758 -0
- package/dist/chunk-HYC4GNHX.js.map +1 -0
- package/dist/chunk-KDVDIZ4Y.cjs +3479 -0
- package/dist/chunk-KDVDIZ4Y.cjs.map +1 -0
- package/dist/{chunk-OG3KX56O.js → chunk-KWGNR4HM.js} +7 -3
- package/dist/chunk-KWGNR4HM.js.map +1 -0
- package/dist/chunk-LIJVWQKU.cjs +256 -0
- package/dist/chunk-LIJVWQKU.cjs.map +1 -0
- package/dist/{chunk-XTZSUDSI.js → chunk-LTRCYJAG.js} +3 -18
- package/dist/chunk-LTRCYJAG.js.map +1 -0
- package/dist/{chunk-UEYC46RL.js → chunk-OUGKLCYF.js} +71 -8
- package/dist/chunk-OUGKLCYF.js.map +1 -0
- package/dist/chunk-RONAX6UU.js +3456 -0
- package/dist/chunk-RONAX6UU.js.map +1 -0
- package/dist/{chunk-5Y7QGIHD.js → chunk-RRYXQMZG.js} +60 -344
- package/dist/chunk-RRYXQMZG.js.map +1 -0
- package/dist/{chunk-QUJ4OLSC.js → chunk-U74F3YZU.js} +87 -7
- package/dist/chunk-U74F3YZU.js.map +1 -0
- package/dist/chunk-VIONYQ2K.cjs +517 -0
- package/dist/chunk-VIONYQ2K.cjs.map +1 -0
- package/dist/chunk-VSTRLXMQ.cjs +50 -0
- package/dist/chunk-VSTRLXMQ.cjs.map +1 -0
- package/dist/chunk-YT7HXXVN.js +13 -0
- package/dist/chunk-YT7HXXVN.js.map +1 -0
- package/dist/chunk-Z6ZWNWWR.js +30 -0
- package/dist/{chunk-NSBPE2FW.js.map → chunk-Z6ZWNWWR.js.map} +1 -1
- package/dist/cli/index.cjs +11 -7
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +11 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/drizzle/index.cjs +20 -17
- package/dist/drizzle/index.d.cts +4 -4
- package/dist/drizzle/index.d.ts +4 -4
- package/dist/drizzle/index.js +4 -5
- package/dist/graphql/index.cjs +4 -4
- package/dist/graphql/index.d.cts +3 -2
- package/dist/graphql/index.d.ts +3 -2
- package/dist/graphql/index.js +2 -2
- package/dist/{index-DI0DRPNv.d.cts → index-BwE4NueJ.d.cts} +1 -1
- package/dist/{index-CMUNCIWQ.d.ts → index-DUKmDSeC.d.cts} +96 -24
- package/dist/{index-BMySjW6o.d.cts → index-DtBi3zP0.d.ts} +96 -24
- package/dist/{index-4fJKLFK2.d.ts → index-DupWTmW6.d.ts} +1 -1
- package/dist/index.cjs +3317 -352
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +379 -105
- package/dist/index.d.ts +379 -105
- package/dist/index.js +3211 -310
- package/dist/index.js.map +1 -1
- package/dist/media-HOT3O7RW.js +4 -0
- package/dist/media-HOT3O7RW.js.map +1 -0
- package/dist/media-WKP5AOX2.cjs +17 -0
- package/dist/media-WKP5AOX2.cjs.map +1 -0
- package/dist/mongodb/index.cjs +1 -1
- package/dist/mongodb/index.d.cts +2 -2
- package/dist/mongodb/index.d.ts +2 -2
- package/dist/mongodb/index.js +1 -1
- package/dist/mysql-media-AI6YK767.cjs +48 -0
- package/dist/mysql-media-AI6YK767.cjs.map +1 -0
- package/dist/mysql-media-CDZUS7YX.js +45 -0
- package/dist/mysql-media-CDZUS7YX.js.map +1 -0
- package/dist/postgres-auth-adapter-EVRPO7BQ.cjs +14 -0
- package/dist/{postgres-auth-adapter-VK6GY7LX.cjs.map → postgres-auth-adapter-EVRPO7BQ.cjs.map} +1 -1
- package/dist/postgres-auth-adapter-OTRWSTT5.js +5 -0
- package/dist/{postgres-auth-adapter-REJFUMP7.js.map → postgres-auth-adapter-OTRWSTT5.js.map} +1 -1
- package/dist/redis-adapter-2N6VA7BI.cjs +13 -0
- package/dist/{redis-adapter-LBLNKGNS.cjs.map → redis-adapter-2N6VA7BI.cjs.map} +1 -1
- package/dist/redis-adapter-RA24FNCX.js +4 -0
- package/dist/{redis-adapter-4YDY4LWE.js.map → redis-adapter-RA24FNCX.js.map} +1 -1
- package/dist/rest/index.cjs +7 -5
- package/dist/rest/index.d.cts +29 -3
- package/dist/rest/index.d.ts +29 -3
- package/dist/rest/index.js +5 -3
- package/dist/schema-CNB2DDTX.js +6 -0
- package/dist/schema-CNB2DDTX.js.map +1 -0
- package/dist/schema-Y777CQQS.cjs +67 -0
- package/dist/schema-Y777CQQS.cjs.map +1 -0
- package/dist/templates/index.cjs +24 -28
- package/dist/templates/index.d.cts +2 -4
- package/dist/templates/index.d.ts +2 -4
- package/dist/templates/index.js +2 -2
- package/dist/trpc/index.cjs +12 -12
- package/dist/trpc/index.d.cts +19 -14
- package/dist/trpc/index.d.ts +19 -14
- package/dist/trpc/index.js +3 -3
- package/dist/{types-BGM5MV_K.d.cts → types-BM0s_YOy.d.cts} +67 -35
- package/dist/{types-BGM5MV_K.d.ts → types-BM0s_YOy.d.ts} +67 -35
- package/dist/ws/index.cjs +1 -1
- package/dist/ws/index.js +1 -1
- package/package.json +11 -1
- package/dist/bootstrap-WMWQ4DBX.cjs +0 -29
- package/dist/bootstrap-WOVGAKZP.js +0 -4
- package/dist/chunk-3EVLFWH2.cjs.map +0 -1
- package/dist/chunk-3QX6KG2S.js +0 -2125
- package/dist/chunk-3QX6KG2S.js.map +0 -1
- package/dist/chunk-3VZCX4DF.cjs.map +0 -1
- package/dist/chunk-5BLDMQED.cjs +0 -18
- package/dist/chunk-5Y7QGIHD.js.map +0 -1
- package/dist/chunk-7G6EVYCU.cjs +0 -94
- package/dist/chunk-7G6EVYCU.cjs.map +0 -1
- package/dist/chunk-A3RQWHKD.cjs.map +0 -1
- package/dist/chunk-EINVJPFM.js.map +0 -1
- package/dist/chunk-F5B64H5S.cjs +0 -2149
- package/dist/chunk-F5B64H5S.cjs.map +0 -1
- package/dist/chunk-K7QF2QCM.cjs.map +0 -1
- package/dist/chunk-LRTZJJPD.js +0 -86
- package/dist/chunk-LRTZJJPD.js.map +0 -1
- package/dist/chunk-NSBPE2FW.js +0 -15
- package/dist/chunk-OG3KX56O.js.map +0 -1
- package/dist/chunk-QUJ4OLSC.js.map +0 -1
- package/dist/chunk-R3XIBBAW.cjs +0 -34
- package/dist/chunk-R3XIBBAW.cjs.map +0 -1
- package/dist/chunk-SDMNUYVU.js +0 -30
- package/dist/chunk-SDMNUYVU.js.map +0 -1
- package/dist/chunk-TZFJMPCH.cjs.map +0 -1
- package/dist/chunk-UEG7KMKC.cjs +0 -228
- package/dist/chunk-UEG7KMKC.cjs.map +0 -1
- package/dist/chunk-UEYC46RL.js.map +0 -1
- package/dist/chunk-V3B25QOK.cjs.map +0 -1
- package/dist/chunk-VMSRTAH7.js.map +0 -1
- package/dist/chunk-XTZSUDSI.js.map +0 -1
- package/dist/chunk-YD7Y25W7.cjs +0 -176
- package/dist/chunk-YD7Y25W7.cjs.map +0 -1
- package/dist/chunk-YPAFJ7EV.js +0 -225
- package/dist/chunk-YPAFJ7EV.js.map +0 -1
- package/dist/database-7CJOXEZR.js +0 -5
- package/dist/database-7CJOXEZR.js.map +0 -1
- package/dist/database-QOIV44GT.cjs +0 -22
- package/dist/database-QOIV44GT.cjs.map +0 -1
- package/dist/postgres-auth-adapter-REJFUMP7.js +0 -5
- package/dist/postgres-auth-adapter-VK6GY7LX.cjs +0 -14
- package/dist/redis-adapter-4YDY4LWE.js +0 -4
- package/dist/redis-adapter-LBLNKGNS.cjs +0 -13
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/ConfigService.ts","../src/auth/nodemailer-transport.ts"],"names":[],"mappings":"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","file":"chunk-HYC4GNHX.js","sourcesContent":["import { eq } from \"drizzle-orm\";\nimport { settings as settingsSchema } from \"../database/drizzle/schema/settings.js\";\n\nexport interface S3CompatibleConfig {\n bucket?: string;\n region?: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n endpoint?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface R2Config {\n accountId?: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n bucket?: string;\n cdnUrl?: string;\n prefix?: string;\n publicDevUrl?: string;\n}\n\nexport interface GCSConfig {\n bucket?: string;\n projectId?: string;\n clientEmail?: string;\n privateKey?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface BackblazeConfig {\n bucket?: string;\n accountId?: string;\n applicationKeyId?: string;\n applicationKey?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface BunnyConfig {\n storageZone?: string;\n apiKey?: string;\n cdnUrl?: string;\n prefix?: string;\n}\n\nexport interface FTPConfig {\n host?: string;\n port?: number;\n user?: string;\n password?: string;\n secure?: boolean;\n baseUrl?: string;\n prefix?: string;\n}\n\nexport interface StorageConfig {\n type: string;\n s3: S3CompatibleConfig;\n r2: R2Config;\n gcs: GCSConfig;\n digitalocean: S3CompatibleConfig;\n backblaze: BackblazeConfig;\n wasabi: S3CompatibleConfig;\n bunny: BunnyConfig;\n ftp: FTPConfig;\n cloudinary: {\n cloudName?: string;\n apiKey?: string;\n apiSecret?: string;\n folder?: string;\n };\n imgix: {\n domain?: string;\n signKey?: string;\n };\n local: {\n uploadDir?: string;\n baseUrl?: string;\n };\n}\n\nexport interface EmailConfig {\n provider?: string;\n host?: string;\n port?: number;\n secure?: boolean;\n user?: string;\n pass?: string;\n from?: string;\n fromName?: string;\n replyTo?: string;\n}\n\nexport class ConfigService {\n private db: any;\n private cache: Record<string, string> = {};\n private static readonly SENSITIVE_KEYS = [\n \"storage.s3.secret_access_key\",\n \"storage.r2.secret_access_key\",\n \"storage.gcs.private_key\",\n \"storage.backblaze.application_key\",\n \"storage.wasabi.secret_access_key\",\n \"storage.ftp.password\",\n \"storage.bunny.api_key\",\n \"storage.cloudinary.api_secret\",\n \"storage.imgix.sign_key\",\n \"email.smtp.pass\",\n \"auth.jwt_secret\",\n \"auth.github_secret\",\n \"auth.google_secret\",\n \"auth.app_secret\",\n \"database.url\",\n \"redis.url\",\n \"auth.admin_password\",\n ];\n\n constructor(db: any) {\n this.db = db;\n }\n\n /**\n * Initialize the service by loading all settings from the database\n */\n async load(): Promise<void> {\n try {\n const allSettings = await this.db.select().from(settingsSchema);\n this.cache = allSettings.reduce((acc: any, row: any) => {\n acc[row.key] = row.value;\n return acc;\n }, {});\n } catch (error) {\n console.warn(\n \"ConfigService: Could not load settings from database, using environment fallbacks.\",\n error,\n );\n }\n }\n\n /**\n * Get a settings value with environment fallback\n */\n get(key: string, envKey?: string, defaultValue?: string): string | undefined {\n // 1. Check database cache\n if (this.cache[key]) return this.cache[key];\n\n // 2. Check environment variable\n if (envKey && process.env[envKey]) return process.env[envKey];\n\n // 3. Return default\n return defaultValue;\n }\n\n /**\n * Get storage configuration\n */\n getStorageConfig(): StorageConfig {\n return {\n type: this.get(\"storage.type\", \"STORAGE_TYPE\", \"local\")!,\n s3: {\n bucket: this.get(\"storage.s3.bucket\", \"STORAGE_BUCKET\"),\n region: this.get(\"storage.s3.region\", \"STORAGE_REGION\", \"us-east-1\"),\n accessKeyId: this.get(\n \"storage.s3.access_key_id\",\n \"STORAGE_ACCESS_KEY_ID\",\n ),\n secretAccessKey: this.get(\n \"storage.s3.secret_access_key\",\n \"STORAGE_SECRET_ACCESS_KEY\",\n ),\n endpoint: this.get(\"storage.s3.endpoint\", \"STORAGE_ENDPOINT\"),\n cdnUrl: this.get(\"storage.s3.cdn_url\", \"STORAGE_CDN_URL\"),\n prefix: this.get(\"storage.s3.prefix\", \"STORAGE_PREFIX\"),\n },\n r2: {\n accountId: this.get(\"storage.r2.account_id\", \"R2_ACCOUNT_ID\"),\n accessKeyId: this.get(\"storage.r2.access_key_id\", \"R2_ACCESS_KEY_ID\"),\n secretAccessKey: this.get(\n \"storage.r2.secret_access_key\",\n \"R2_SECRET_ACCESS_KEY\",\n ),\n bucket: this.get(\"storage.r2.bucket\", \"R2_BUCKET\"),\n cdnUrl: this.get(\"storage.r2.cdn_url\", \"R2_CDN_URL\"),\n prefix: this.get(\"storage.r2.prefix\", \"R2_PREFIX\"),\n },\n gcs: {\n bucket: this.get(\"storage.gcs.bucket\", \"GCS_BUCKET\"),\n projectId: this.get(\"storage.gcs.project_id\", \"GCS_PROJECT_ID\"),\n clientEmail: this.get(\"storage.gcs.client_email\", \"GCS_CLIENT_EMAIL\"),\n privateKey: this.get(\"storage.gcs.private_key\", \"GCS_PRIVATE_KEY\"),\n cdnUrl: this.get(\"storage.gcs.cdn_url\", \"GCS_CDN_URL\"),\n prefix: this.get(\"storage.gcs.prefix\", \"GCS_PREFIX\"),\n },\n digitalocean: {\n bucket: this.get(\"storage.digitalocean.bucket\", \"DO_BUCKET\"),\n region: this.get(\"storage.digitalocean.region\", \"DO_REGION\", \"nyc3\"),\n accessKeyId: this.get(\n \"storage.digitalocean.access_key_id\",\n \"DO_ACCESS_KEY_ID\",\n ),\n secretAccessKey: this.get(\n \"storage.digitalocean.secret_access_key\",\n \"DO_SECRET_ACCESS_KEY\",\n ),\n cdnUrl: this.get(\"storage.digitalocean.cdn_url\", \"DO_CDN_URL\"),\n prefix: this.get(\"storage.digitalocean.prefix\", \"DO_PREFIX\"),\n },\n backblaze: {\n bucket: this.get(\"storage.backblaze.bucket\", \"BB_BUCKET\"),\n accountId: this.get(\"storage.backblaze.account_id\", \"BB_ACCOUNT_ID\"),\n applicationKeyId: this.get(\n \"storage.backblaze.application_key_id\",\n \"BB_APPLICATION_KEY_ID\",\n ),\n applicationKey: this.get(\n \"storage.backblaze.application_key\",\n \"BB_APPLICATION_KEY\",\n ),\n cdnUrl: this.get(\"storage.backblaze.cdn_url\", \"BB_CDN_URL\"),\n prefix: this.get(\"storage.backblaze.prefix\", \"BB_PREFIX\"),\n },\n wasabi: {\n bucket: this.get(\"storage.wasabi.bucket\", \"WASABI_BUCKET\"),\n region: this.get(\"storage.wasabi.region\", \"WASABI_REGION\", \"us-east-1\"),\n accessKeyId: this.get(\n \"storage.wasabi.access_key_id\",\n \"WASABI_ACCESS_KEY_ID\",\n ),\n secretAccessKey: this.get(\n \"storage.wasabi.secret_access_key\",\n \"WASABI_SECRET_ACCESS_KEY\",\n ),\n cdnUrl: this.get(\"storage.wasabi.cdn_url\", \"WASABI_CDN_URL\"),\n prefix: this.get(\"storage.wasabi.prefix\", \"WASABI_PREFIX\"),\n },\n bunny: {\n storageZone: this.get(\n \"storage.bunny.storage_zone\",\n \"BUNNY_STORAGE_ZONE\",\n ),\n apiKey: this.get(\"storage.bunny.api_key\", \"BUNNY_API_KEY\"),\n cdnUrl: this.get(\"storage.bunny.cdn_url\", \"BUNNY_CDN_URL\"),\n prefix: this.get(\"storage.bunny.prefix\", \"BUNNY_PREFIX\"),\n },\n ftp: {\n host: this.get(\"storage.ftp.host\", \"FTP_HOST\"),\n port: parseInt(this.get(\"storage.ftp.port\", \"FTP_PORT\", \"21\")!, 10),\n user: this.get(\"storage.ftp.user\", \"FTP_USER\"),\n password: this.get(\"storage.ftp.password\", \"FTP_PASSWORD\"),\n secure: this.get(\"storage.ftp.secure\", \"FTP_SECURE\") === \"true\",\n baseUrl: this.get(\"storage.ftp.base_url\", \"FTP_BASE_URL\"),\n prefix: this.get(\"storage.ftp.prefix\", \"FTP_PREFIX\"),\n },\n cloudinary: {\n cloudName: this.get(\n \"storage.cloudinary.cloud_name\",\n \"CLOUDINARY_CLOUD_NAME\",\n ),\n apiKey: this.get(\"storage.cloudinary.api_key\", \"CLOUDINARY_API_KEY\"),\n apiSecret: this.get(\n \"storage.cloudinary.api_secret\",\n \"CLOUDINARY_API_SECRET\",\n ),\n folder: this.get(\"storage.cloudinary.folder\", \"CLOUDINARY_FOLDER\"),\n },\n imgix: {\n domain: this.get(\"storage.imgix.domain\", \"IMGIX_DOMAIN\"),\n signKey: this.get(\"storage.imgix.sign_key\", \"IMGIX_SIGN_KEY\"),\n },\n local: {\n uploadDir: this.get(\"storage.local.dir\", \"STORAGE_LOCAL_DIR\"),\n baseUrl: this.get(\"storage.local.url\", \"STORAGE_LOCAL_URL\", \"/uploads\"),\n },\n };\n }\n\n /**\n * Get email configuration\n */\n getEmailConfig(): EmailConfig {\n return {\n provider: this.get(\"email.provider\", \"EMAIL_PROVIDER\", \"smtp\"),\n host: this.get(\"email.smtp.host\", \"SMTP_HOST\"),\n port: parseInt(this.get(\"email.smtp.port\", \"SMTP_PORT\", \"587\")!, 10),\n secure: this.get(\"email.smtp.secure\", \"SMTP_SECURE\") === \"true\",\n user: this.get(\"email.smtp.user\", \"SMTP_USER\"),\n pass: this.get(\"email.smtp.pass\", \"SMTP_PASS\"),\n from: this.get(\"email.smtp.from\", \"SMTP_FROM\", \"noreply@example.com\"),\n fromName: this.get(\"email.smtp.from_name\", \"SMTP_FROM_NAME\", \"Kyro CMS\"),\n replyTo: this.get(\"email.smtp.reply_to\", \"SMTP_REPLY_TO\"),\n };\n }\n\n /**\n * Mask sensitive values for display\n */\n maskSensitive(key: string, value: string | undefined): string | undefined {\n if (!value) return value;\n if (ConfigService.SENSITIVE_KEYS.includes(key)) {\n return \"********\";\n }\n return value;\n }\n\n /**\n * Update a setting in the database\n */\n async set(key: string, value: string, description?: string): Promise<void> {\n await this.db\n .insert(settingsSchema)\n .values({\n key,\n value,\n description,\n updatedAt: new Date(),\n })\n .onConflictDoUpdate({\n target: [settingsSchema.key],\n set: { value, description, updatedAt: new Date() },\n });\n this.cache[key] = value;\n }\n}\n","import nodemailer, { Transporter } from \"nodemailer\";\nimport type { SentMessageInfo } from \"nodemailer\";\n\nexport interface EmailConfig {\n provider: \"smtp\" | \"resend\" | \"sendgrid\" | \"mailgun\" | \"ses\";\n from: string;\n fromName?: string;\n replyTo?: string;\n smtp?: {\n host: string;\n port: number;\n secure: boolean;\n auth: {\n user: string;\n pass: string;\n };\n };\n resend?: {\n apiKey: string;\n };\n sendgrid?: {\n apiKey: string;\n };\n mailgun?: {\n apiKey: string;\n domain: string;\n region?: \"us\" | \"eu\";\n };\n ses?: {\n accessKeyId: string;\n secretAccessKey: string;\n region: string;\n };\n}\n\nexport interface EmailOptions {\n to: string | string[];\n subject: string;\n html: string;\n text?: string;\n replyTo?: string;\n}\n\nexport interface EmailTemplates {\n verifyEmail: (\n link: string,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n resetPassword: (\n link: string,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n welcome: (userName?: string) => {\n subject: string;\n html: string;\n text: string;\n };\n accountLocked: (\n attempts: number,\n duration: number,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n passwordChanged: (userName?: string) => {\n subject: string;\n html: string;\n text: string;\n };\n newLogin: (\n location: string,\n time: string,\n userName?: string,\n ) => { subject: string; html: string; text: string };\n}\n\nconst defaultTemplates: EmailTemplates = {\n verifyEmail: (link, userName = \"User\") => ({\n subject: \"Verify your email address\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Verify Email</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .button { display: inline-block; padding: 12px 24px; background: #0b1222; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Welcome, ${userName}!</h1>\n <p>Please verify your email address by clicking the button below:</p>\n <p style=\"text-align: center; margin: 30px 0;\">\n <a href=\"${link}\" class=\"button\">Verify Email</a>\n </p>\n <p>Or copy and paste this link into your browser:</p>\n <p style=\"word-break: break-all; color: #666;\">${link}</p>\n <p>This link will expire in 24 hours.</p>\n <div class=\"footer\">\n <p>If you didn't create an account, you can safely ignore this email.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `Welcome ${userName}!\\n\\nPlease verify your email by clicking this link: ${link}\\n\\nThis link will expire in 24 hours.\\n\\nIf you didn't create an account, you can safely ignore this email.`,\n }),\n\n resetPassword: (link, userName = \"User\") => ({\n subject: \"Reset your password\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Reset Password</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .button { display: inline-block; padding: 12px 24px; background: #dc2626; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; }\n .warning { background: #fef3c7; border: 1px solid #f59e0b; padding: 12px; border-radius: 6px; margin: 20px 0; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Password Reset Request</h1>\n <p>Hello ${userName},</p>\n <p>We received a request to reset your password. Click the button below to create a new password:</p>\n <p style=\"text-align: center; margin: 30px 0;\">\n <a href=\"${link}\" class=\"button\">Reset Password</a>\n </p>\n <p>Or copy and paste this link into your browser:</p>\n <p style=\"word-break: break-all; color: #666;\">${link}</p>\n <div class=\"warning\">\n <strong>⚠️ Important:</strong> This link will expire in 1 hour. If you didn't request a password reset, please ignore this email or contact support if you have concerns.\n </div>\n <div class=\"footer\">\n <p>For security reasons, please don't share this email with anyone.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `Password Reset Request\\n\\nHello ${userName},\\n\\nWe received a request to reset your password. Click this link to create a new password: ${link}\\n\\nThis link will expire in 1 hour.\\n\\nIf you didn't request a password reset, please ignore this email.`,\n }),\n\n welcome: (userName = \"User\") => ({\n subject: \"Welcome to Kyro CMS\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Welcome</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .button { display: inline-block; padding: 12px 24px; background: #0b1222; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Welcome to Kyro CMS, ${userName}!</h1>\n <p>Your account has been created successfully.</p>\n <p>You can now:</p>\n <ul>\n <li>Manage your content collections</li>\n <li>Upload and organize media</li>\n <li>Configure settings</li>\n <li>And much more...</li>\n </ul>\n <p style=\"text-align: center; margin: 30px 0;\">\n <a href=\"#\" class=\"button\">Get Started</a>\n </p>\n <p>If you have any questions, feel free to reach out to our support team.</p>\n </div>\n </body>\n </html>\n `,\n text: `Welcome to Kyro CMS, ${userName}!\\n\\nYour account has been created successfully.\\n\\nYou can now:\\n- Manage your content collections\\n- Upload and organize media\\n- Configure settings\\n- And much more...\\n\\nGet started by logging into your dashboard.`,\n }),\n\n accountLocked: (attempts, duration, userName = \"User\") => ({\n subject: \"Account Security Alert - Account Locked\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Account Locked</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .alert { background: #fef2f2; border: 1px solid #ef4444; padding: 16px; border-radius: 8px; margin: 20px 0; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Account Security Alert</h1>\n <p>Hello ${userName},</p>\n <div class=\"alert\">\n <p><strong>⚠️ Your account has been temporarily locked due to multiple failed login attempts.</strong></p>\n <p>Failed attempts: ${attempts}</p>\n <p>Lockout duration: ${Math.round(duration / 60000)} minutes</p>\n </div>\n <p>Your account will automatically unlock after the lockout period expires.</p>\n <p>If this wasn't you, we recommend:</p>\n <ul>\n <li>Using a strong, unique password</li>\n <li>Enabling two-factor authentication (coming soon)</li>\n <li>Reviewing your recent account activity</li>\n </ul>\n <div class=\"footer\">\n <p>If you need immediate assistance, please contact support.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `Account Security Alert\\n\\nHello ${userName},\\n\\nYour account has been temporarily locked due to multiple failed login attempts (${attempts}).\\n\\nLockout duration: ${Math.round(duration / 60000)} minutes\\n\\nYour account will automatically unlock after this period.\\n\\nIf this wasn't you, we recommend using a strong, unique password.`,\n }),\n\n passwordChanged: (userName = \"User\") => ({\n subject: \"Your password has been changed\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Password Changed</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .info { background: #f0fdf4; border: 1px solid #22c55e; padding: 12px; border-radius: 6px; margin: 20px 0; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Password Changed</h1>\n <p>Hello ${userName},</p>\n <div class=\"info\">\n <p>Your password was recently changed.</p>\n </div>\n <p>If you did this, you can safely ignore this email.</p>\n <p><strong>If you didn't change your password</strong>, please contact our support team immediately as your account may have been compromised.</p>\n </div>\n </body>\n </html>\n `,\n text: `Password Changed\\n\\nHello ${userName},\\n\\nYour password was recently changed.\\n\\nIf you did this, you can safely ignore this email.\\n\\nIf you didn't change your password, please contact support immediately.`,\n }),\n\n newLogin: (location, time, userName = \"User\") => ({\n subject: \"New login to your account\",\n html: `\n <!DOCTYPE html>\n <html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>New Login</title>\n <style>\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; }\n .container { max-width: 600px; margin: 0 auto; padding: 20px; }\n .info-box { background: #f8fafc; border: 1px solid #e2e8f0; padding: 16px; border-radius: 8px; margin: 20px 0; }\n .footer { margin-top: 30px; font-size: 12px; color: #666; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>New Login Detected</h1>\n <p>Hello ${userName},</p>\n <p>We detected a new login to your account:</p>\n <div class=\"info-box\">\n <p><strong>Location:</strong> ${location}</p>\n <p><strong>Time:</strong> ${time}</p>\n </div>\n <p><strong>If this was you</strong>, no action is needed.</p>\n <p><strong>If this wasn't you</strong>, your account may be compromised. Please:</p>\n <ol>\n <li>Change your password immediately</li>\n <li>Review your recent account activity</li>\n <li>Contact support if needed</li>\n </ol>\n <div class=\"footer\">\n <p>This is an automated security notification.</p>\n </div>\n </div>\n </body>\n </html>\n `,\n text: `New Login Detected\\n\\nHello ${userName},\\n\\nWe detected a new login to your account:\\n\\nLocation: ${location}\\nTime: ${time}\\n\\nIf this wasn't you, please change your password immediately and contact support.`,\n }),\n};\n\nimport { ConfigService } from \"../config/ConfigService.js\";\n\nexport class EmailTransport {\n private transporter?: Transporter<SentMessageInfo>;\n private config: EmailConfig;\n private templates: EmailTemplates;\n\n constructor(config: EmailConfig, templates?: Partial<EmailTemplates>) {\n this.config = config;\n this.templates = { ...defaultTemplates, ...templates };\n\n if (config.provider === \"smtp\" && config.smtp) {\n this.transporter = nodemailer.createTransport({\n host: config.smtp.host,\n port: config.smtp.port,\n secure: config.smtp.secure,\n auth: config.smtp.auth,\n });\n } else if (config.provider === \"ses\" && config.ses) {\n // In a real implementation, you'd use @aws-sdk/client-ses\n // For now, we reuse standard SMTP if credentials look like SMTP,\n // or we'd add the SES transporter. SES usually provides SMTP.\n this.transporter = nodemailer.createTransport({\n host: `email-smtp.${config.ses.region}.amazonaws.com`,\n port: 587,\n secure: false,\n auth: {\n user: config.ses.accessKeyId,\n pass: config.ses.secretAccessKey,\n },\n });\n }\n }\n\n async send(options: EmailOptions): Promise<any> {\n const { provider, from, fromName, replyTo: configReplyTo } = this.config;\n const fromFull = `\"${fromName || \"Kyro CMS\"}\" <${from}>`;\n const replyTo = options.replyTo || configReplyTo;\n\n console.log(`[EmailTransport] Sending email via ${provider}...`);\n console.log(`[EmailTransport] To: ${Array.isArray(options.to) ? options.to.join(\", \") : options.to}`);\n console.log(`[EmailTransport] Subject: ${options.subject}`);\n\n try {\n let result;\n switch (provider) {\n case \"smtp\":\n case \"ses\":\n if (!this.transporter)\n throw new Error(`${provider} transporter not initialized`);\n result = await this.transporter.sendMail({\n from: fromFull,\n to: Array.isArray(options.to) ? options.to.join(\", \") : options.to,\n subject: options.subject,\n html: options.html,\n text: options.text,\n replyTo,\n });\n break;\n\n case \"resend\":\n result = await this.sendViaResend(fromFull, options, replyTo);\n break;\n\n case \"sendgrid\":\n result = await this.sendViaSendGrid(fromFull, options, replyTo);\n break;\n\n case \"mailgun\":\n result = await this.sendViaMailgun(fromFull, options, replyTo);\n break;\n\n default:\n throw new Error(`Unsupported email provider: ${provider}`);\n }\n console.log(`[EmailTransport] Success! Provider response received.`);\n return result;\n } catch (error: any) {\n console.error(`[EmailTransport] FAILED to send email:`, error.message);\n if (error.response) {\n console.error(`[EmailTransport] Provider Error Detail:`, JSON.stringify(error.response, null, 2));\n }\n throw error;\n }\n }\n\n private async sendViaResend(\n from: string,\n options: EmailOptions,\n replyTo?: string,\n ) {\n const apiKey = this.config.resend?.apiKey;\n if (!apiKey) throw new Error(\"Resend API Key missing\");\n\n const body = {\n from,\n to: options.to,\n subject: options.subject,\n html: options.html,\n text: options.text,\n reply_to: replyTo,\n };\n\n console.log(`[EmailTransport] Calling Resend API...`);\n const resp = await fetch(\"https://api.resend.com/emails\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!resp.ok) {\n const error = await resp.json();\n throw new Error(`Resend Error: ${JSON.stringify(error)}`);\n }\n return resp.json();\n }\n\n private async sendViaSendGrid(\n from: string,\n options: EmailOptions,\n replyTo?: string,\n ) {\n const apiKey = this.config.sendgrid?.apiKey;\n if (!apiKey) throw new Error(\"SendGrid API Key missing\");\n\n const body = {\n personalizations: [\n { to: Array.isArray(options.to) ? options.to.map(email => ({ email })) : [{ email: options.to }] },\n ],\n from: { email: from.match(/<(.+)>/)?.[1] || from, name: from.match(/\"(.+)\"/)?.[1] },\n subject: options.subject,\n content: [\n { type: \"text/plain\", value: options.text || \"\" },\n { type: \"text/html\", value: options.html },\n ],\n reply_to: replyTo ? { email: replyTo } : undefined,\n };\n\n console.log(`[EmailTransport] Calling SendGrid API...`);\n const resp = await fetch(\"https://api.sendgrid.com/v3/mail/send\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (!resp.ok) {\n const error = await resp.json();\n throw new Error(`SendGrid Error: ${JSON.stringify(error)}`);\n }\n return { success: true };\n }\n\n private async sendViaMailgun(\n from: string,\n options: EmailOptions,\n replyTo?: string,\n ) {\n const { apiKey, domain, region } = this.config.mailgun || {};\n if (!apiKey || !domain) throw new Error(\"Mailgun config missing\");\n\n const base = region === \"eu\" ? \"api.eu.mailgun.net\" : \"api.mailgun.net\";\n const auth = btoa(`api:${apiKey}`);\n\n const formData = new URLSearchParams();\n formData.append(\"from\", from);\n const to = Array.isArray(options.to) ? options.to.join(\", \") : options.to;\n formData.append(\"to\", to);\n formData.append(\"subject\", options.subject);\n formData.append(\"html\", options.html);\n if (options.text) formData.append(\"text\", options.text);\n if (replyTo) formData.append(\"h:Reply-To\", replyTo);\n\n console.log(`[EmailTransport] Calling Mailgun API (${region || 'us'})...`);\n const resp = await fetch(`https://${base}/v3/${domain}/messages`, {\n method: \"POST\",\n headers: {\n Authorization: `Basic ${auth}`,\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: formData,\n });\n\n if (!resp.ok) {\n const error = await resp.json();\n throw new Error(`Mailgun Error: ${JSON.stringify(error)}`);\n }\n return resp.json();\n }\n\n getTemplates(): EmailTemplates {\n return this.templates;\n }\n\n async verifyConnection(): Promise<boolean> {\n if (this.transporter) {\n try {\n await this.transporter.verify();\n return true;\n } catch {\n return false;\n }\n }\n return !!(this.config.resend?.apiKey || this.config.sendgrid?.apiKey || this.config.mailgun?.apiKey);\n }\n\n static async fromConfig(db: any): Promise<EmailTransport | null> {\n const configService = new ConfigService(db);\n await configService.load();\n const config = configService.getEmailConfig();\n\n if (!config.provider) {\n return this.fromEnv();\n }\n\n const transformed: EmailConfig = {\n provider: config.provider as any || \"smtp\",\n from: config.from || \"noreply@example.com\",\n fromName: config.fromName,\n replyTo: config.replyTo,\n smtp: config.provider === \"smtp\" ? {\n host: config.host || \"\",\n port: config.port || 587,\n secure: config.secure || false,\n auth: { user: config.user || \"\", pass: config.pass || \"\" },\n } : undefined,\n resend: config.provider === \"resend\" ? { apiKey: config.pass || \"\" } : undefined,\n sendgrid: config.provider === \"sendgrid\" ? { apiKey: config.pass || \"\" } : undefined,\n mailgun: config.provider === \"mailgun\" ? { \n apiKey: config.pass || \"\", \n domain: config.host || \"\",\n region: (config.secure ? \"eu\" : \"us\") as any\n } : undefined,\n ses: config.provider === \"ses\" ? {\n accessKeyId: config.user || \"\",\n secretAccessKey: config.pass || \"\",\n region: config.host || \"us-east-1\"\n } : undefined\n };\n\n return new EmailTransport(transformed);\n }\n\n static fromEnv(): EmailTransport | null {\n const provider = (process.env.EMAIL_PROVIDER as any) || \"smtp\";\n const from = process.env.SMTP_FROM || process.env.DEFAULT_FROM || \"noreply@example.com\";\n const fromName = process.env.SMTP_FROM_NAME || \"Kyro CMS\";\n const replyTo = process.env.SMTP_REPLY_TO;\n\n if (provider === \"smtp\") {\n const host = process.env.SMTP_HOST;\n const user = process.env.SMTP_USER;\n const pass = process.env.SMTP_PASS;\n if (!host || !user || !pass) return null;\n\n return new EmailTransport({\n provider: \"smtp\",\n from,\n fromName,\n replyTo,\n smtp: {\n host,\n port: parseInt(process.env.SMTP_PORT || \"587\", 10),\n secure: process.env.SMTP_SECURE === \"true\",\n auth: { user, pass },\n },\n });\n }\n\n if (provider === \"resend\") {\n const apiKey = process.env.RESEND_API_KEY || process.env.SMTP_PASS;\n if (!apiKey) return null;\n return new EmailTransport({ provider: \"resend\", from, fromName, replyTo, resend: { apiKey } });\n }\n\n if (provider === \"sendgrid\") {\n const apiKey = process.env.SENDGRID_API_KEY || process.env.SMTP_PASS;\n if (!apiKey) return null;\n return new EmailTransport({ provider: \"sendgrid\", from, fromName, replyTo, sendgrid: { apiKey } });\n }\n\n if (provider === \"mailgun\") {\n const apiKey = process.env.MAILGUN_API_KEY || process.env.SMTP_PASS;\n const domain = process.env.MAILGUN_DOMAIN || process.env.SMTP_HOST;\n if (!apiKey || !domain) return null;\n return new EmailTransport({ \n provider: \"mailgun\", \n from, \n fromName, \n replyTo, \n mailgun: { \n apiKey, \n domain, \n region: (process.env.MAILGUN_REGION || (process.env.SMTP_SECURE === \"true\" ? \"eu\" : \"us\")) as any \n } \n });\n }\n\n if (provider === \"ses\") {\n const accessKeyId = process.env.AWS_ACCESS_KEY_ID || process.env.SMTP_USER;\n const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY || process.env.SMTP_PASS;\n const region = process.env.AWS_REGION || process.env.SMTP_HOST || \"us-east-1\";\n if (!accessKeyId || !secretAccessKey) return null;\n return new EmailTransport({ provider: \"ses\", from, fromName, replyTo, ses: { accessKeyId, secretAccessKey, region } });\n }\n\n return null;\n }\n}\n"]}
|