diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd2ba0ce..014a8241 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -73,4 +73,5 @@ repos: ^src/core/engines/webjs/_lodash.js| ^tests/perf/.*| ^scripts/.*| + ^scripts/init-waha.js| )$ diff --git a/Dockerfile b/Dockerfile index 3c2dc96c..8c82106c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -195,6 +195,11 @@ COPY --from=build /git/node_modules ./node_modules COPY --from=build /git/dist ./dist COPY --from=dashboard /dashboard ./dist/dashboard COPY --from=gows /go/gows/bin/gows /app/gows +COPY .env.example ./.env.example +COPY scripts/init-waha.js ./scripts/init-waha.js +RUN chmod +x ./scripts/init-waha.js \ + && printf '%s\n' '#!/bin/sh' 'exec node /app/scripts/init-waha.js "$@"' > /usr/local/bin/init-waha \ + && chmod +x /usr/local/bin/init-waha ENV WAHA_GOWS_PATH=/app/gows ENV WAHA_GOWS_SOCKET=/tmp/gows.sock diff --git a/scripts/init-waha.js b/scripts/init-waha.js new file mode 100755 index 00000000..3e56f9be --- /dev/null +++ b/scripts/init-waha.js @@ -0,0 +1,92 @@ +#!/usr/bin/env node +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const crypto = require('crypto'); + +const projectRoot = path.resolve(__dirname, '..'); + +const args = process.argv.slice(2); +const forceIndex = args.indexOf('--force'); +const forceOverwrite = forceIndex !== -1; + +if (forceOverwrite) { + args.splice(forceIndex, 1); +} + +const folderArg = args[0] || '.'; +const sourceArgRaw = args[1]; +const targetArg = args[2] || '.env'; + +const envDir = path.resolve(process.cwd(), folderArg); +const sourceArg = sourceArgRaw || '.env.example'; +const templateBaseDir = sourceArgRaw ? envDir : projectRoot; +const templatePath = path.isAbsolute(sourceArg) + ? sourceArg + : path.resolve(templateBaseDir, sourceArg); +const targetPath = path.isAbsolute(targetArg) + ? targetArg + : path.resolve(envDir, targetArg); + +function exitWithMessage(message, code = 1) { + console.error(message); + process.exit(code); +} + +if (!fs.existsSync(envDir)) { + exitWithMessage(`Target directory does not exist: ${envDir}`); +} + +if (!fs.existsSync(templatePath)) { + exitWithMessage(`Missing template file: ${templatePath}`); +} + +if (!forceOverwrite && fs.existsSync(targetPath)) { + const stats = fs.statSync(targetPath); + if (stats.size > 0) { + exitWithMessage( + `${targetPath} already exists and is not empty. Remove it manually or rerun with --force to overwrite.`, + ); + } +} + +const exampleContent = fs.readFileSync(templatePath, 'utf8'); + +function generateSecret() { + return crypto.randomUUID({ disableEntropyCache: true }).replace(/-/g, ''); +} + +const apiKey = generateSecret(); +const adminPassword = generateSecret(); + +const updatedContent = exampleContent + .replace(/^WAHA_API_KEY=.*/m, `WAHA_API_KEY=${apiKey}`) + .replace(/^WAHA_API_KEY_PLAIN=.*/m, `WAHA_API_KEY_PLAIN=${apiKey}`) + .replace(/^WAHA_DASHBOARD_USERNAME=.*/m, 'WAHA_DASHBOARD_USERNAME=admin') + .replace( + /^WAHA_DASHBOARD_PASSWORD=.*/m, + `WAHA_DASHBOARD_PASSWORD=${adminPassword}`, + ) + .replace(/^WHATSAPP_SWAGGER_USERNAME=.*/m, 'WHATSAPP_SWAGGER_USERNAME=admin') + .replace( + /^WHATSAPP_SWAGGER_PASSWORD=.*/m, + `WHATSAPP_SWAGGER_PASSWORD=${adminPassword}`, + ); + +fs.writeFileSync(targetPath, updatedContent, { encoding: 'utf8' }); + +const lines = [ + 'Credentials generated.', + '', + 'Dashboard and Swagger:', + ' - Username: admin', + ` - Password: ${adminPassword}`, + '', + 'API key: ', + ` - ${apiKey}`, + '', + 'Use it in the Dashboard connection flow: https://waha.devlike.pro/docs/how-to/dashboard/#api-key', +]; + +console.log(lines.join('\n'));