Fixed passwords

This commit is contained in:
2021-07-25 18:52:46 +10:00
parent 2af9532930
commit f85b6e8793
+304 -304
View File
@@ -1,304 +1,304 @@
//setup //setup
const readline = require('readline'); const readline = require('readline');
const fs = require('fs'); const fs = require('fs');
const crypto = require("crypto"); const crypto = require("crypto");
const uuid = (bytes = 16) => crypto.randomBytes(bytes).toString("hex"); const uuid = (bytes = 16) => crypto.randomBytes(bytes).toString("hex");
const rl = readline.createInterface({ const rl = readline.createInterface({
input: process.stdin, input: process.stdin,
output: process.stdout, output: process.stdout,
terminal: false terminal: false
}); });
//manually promisify this (util didn't work) //manually promisify this (util didn't work)
const question = (prompt, def = null) => { const question = (prompt, def = null) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
rl.question(`${prompt}${def ? ` (${def})` : ''}: `, answer => { rl.question(`${prompt}${def ? ` (${def})` : ''}: `, answer => {
//loop on required //loop on required
if (def === null && !answer) { if (def === null && !answer) {
return resolve(question(prompt, def)); return resolve(question(prompt, def));
} }
return resolve(answer || def); return resolve(answer || def);
}); });
}); });
}; };
//questions //questions
(async () => { (async () => {
console.log( console.log(
`This configure script will generate the following files: `This configure script will generate the following files:
* docker-compose.yml * docker-compose.yml
* Dockerfile * Dockerfile
* startup.sql * startup.sql
Currently, all microservices are mandatory; you'll have to mess with the result Currently, all microservices are mandatory; you'll have to mess with the result
and the source code if you wish to be more selective. Microservices currently and the source code if you wish to be more selective. Microservices currently
impelented are: impelented are:
* auth-server * auth-server
* news-server * news-server
* chat-server * chat-server
See https://github.com/krgamestudios/MERN-template/wiki for help. See https://github.com/krgamestudios/MERN-template/wiki for help.
` `
); );
//project configuration //project configuration
const projectName = await question('Project Name', 'template'); const projectName = await question('Project Name', 'template');
const projectWebAddress = await question('Project Web Address', 'example.com'); const projectWebAddress = await question('Project Web Address', 'example.com');
const projectDBUser = await question('Project DB Username', projectName); const projectDBUser = await question('Project DB Username', projectName);
const projectDBPass = await question('Project DB Password', 'pikachu'); const projectDBPass = await question('Project DB Password', 'pikachu');
//news configuration //news configuration
const newsName = await question('News Name', 'news'); const newsName = await question('News Name', 'news');
const newsWebAddress = await question('News Web Address', `${newsName}.${projectWebAddress}`); const newsWebAddress = await question('News Web Address', `${newsName}.${projectWebAddress}`);
const newsDBUser = await question('News DB Username', newsName); const newsDBUser = await question('News DB Username', newsName);
const newsDBPass = await question('News DB Password', 'charizard'); const newsDBPass = await question('News DB Password', 'venusaur');
//auth configuration //auth configuration
const authName = await question('Auth Name', 'auth'); const authName = await question('Auth Name', 'auth');
const authWebAddress = await question('Auth Web Address', `${authName}.${projectWebAddress}`); const authWebAddress = await question('Auth Web Address', `${authName}.${projectWebAddress}`);
const authDBUser = await question('Auth DB Username', authName); const authDBUser = await question('Auth DB Username', authName);
const authDBPass = await question('Auth DB Password', 'venusaur'); const authDBPass = await question('Auth DB Password', 'charizard');
const emailSMTP = await question('Email SMTP', 'smtp.example.com'); const emailSMTP = await question('Email SMTP', 'smtp.example.com');
const emailUser = await question('Email Address', 'foobar@example.com'); const emailUser = await question('Email Address', 'foobar@example.com');
const emailPass = await question('Email Password', 'foobar'); const emailPass = await question('Email Password', 'foobar');
const emailPhysical = await question('Physical Mailing Address', ''); const emailPhysical = await question('Physical Mailing Address', '');
//chat goes here //chat goes here
const chatName = await question('Chat Name', 'chat'); const chatName = await question('Chat Name', 'chat');
const chatWebAddress = await question('Chat Web Address', `${chatName}.${projectWebAddress}`); const chatWebAddress = await question('Chat Web Address', `${chatName}.${projectWebAddress}`);
const chatDBUser = await question('Chat DB Username', chatName); const chatDBUser = await question('Chat DB Username', chatName);
const chatDBPass = await question('Chat DB Password', 'blastoise'); const chatDBPass = await question('Chat DB Password', 'blastoise');
//database configuration //database configuration
const dbRootPassword = await question('Database Root Password', 'password'); const dbRootPassword = await question('Database Root Password', 'password');
const dbTimeZone = await question('Database Timezone', 'Australia/Sydney'); const dbTimeZone = await question('Database Timezone', 'Australia/Sydney');
//joint configuration //joint configuration
const accessToken = await question('Access Token Secret', uuid(32)); const accessToken = await question('Access Token Secret', uuid(32));
const refreshToken = await question('Refresh Token Secret', uuid(32)); const refreshToken = await question('Refresh Token Secret', uuid(32));
console.log('--Leave "Default User" blank if you don\'t want one--'); console.log('--Leave "Default User" blank if you don\'t want one--');
const defaultUser = await question('Default Admin User', ''); const defaultUser = await question('Default Admin User', '');
//MUST be at least 8 chars //MUST be at least 8 chars
let tmpPass = ''; let tmpPass = '';
while (defaultUser && tmpPass.length < 8) { while (defaultUser && tmpPass.length < 8) {
console.log('--All passwords must be at least 8 characters long--'); console.log('--All passwords must be at least 8 characters long--');
tmpPass = await question('Default Admin Pass', ''); tmpPass = await question('Default Admin Pass', '');
} }
const defaultPass = tmpPass; const defaultPass = tmpPass;
if (defaultUser) { if (defaultUser) {
console.log(`Default user email will be: ${defaultUser}@${authWebAddress}`); console.log(`Default user email will be: ${defaultUser}@${authWebAddress}`);
} }
//traefic configuration //traefic configuration
const supportEmail = await question('Support Email', emailUser); const supportEmail = await question('Support Email', emailUser);
//misc. configuration //misc. configuration
const projectPort = 3000; const projectPort = 3000;
const newsPort = 3100; const newsPort = 3100;
const authPort = 3200; const authPort = 3200;
const chatPort = 3300; const chatPort = 3300;
const ymlfile = ` const ymlfile = `
version: "3.6" version: "3.6"
services: services:
${projectName}: ${projectName}:
build: . build: .
ports: ports:
- "${projectPort}" - "${projectPort}"
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.${projectName}router.rule=Host(\`${projectWebAddress}\`) - traefik.http.routers.${projectName}router.rule=Host(\`${projectWebAddress}\`)
- traefik.http.routers.${projectName}router.entrypoints=websecure - traefik.http.routers.${projectName}router.entrypoints=websecure
- traefik.http.routers.${projectName}router.tls.certresolver=myresolver - traefik.http.routers.${projectName}router.tls.certresolver=myresolver
- traefik.http.routers.${projectName}router.service=${projectName}service@docker - traefik.http.routers.${projectName}router.service=${projectName}service@docker
- traefik.http.services.${projectName}service.loadbalancer.server.port=${projectPort} - traefik.http.services.${projectName}service.loadbalancer.server.port=${projectPort}
environment: environment:
- WEB_PORT=${projectPort} - WEB_PORT=${projectPort}
- DB_HOSTNAME=database - DB_HOSTNAME=database
- DB_DATABASE=${projectName} - DB_DATABASE=${projectName}
- DB_USERNAME=${projectDBUser} - DB_USERNAME=${projectDBUser}
- DB_PASSWORD=${projectDBPass} - DB_PASSWORD=${projectDBPass}
- DB_TIMEZONE=${dbTimeZone} - DB_TIMEZONE=${dbTimeZone}
- NEWS_URI=https://${newsWebAddress} - NEWS_URI=https://${newsWebAddress}
- AUTH_URI=https://${authWebAddress} - AUTH_URI=https://${authWebAddress}
- CHAT_URI=https://${chatWebAddress} - CHAT_URI=https://${chatWebAddress}
- SECRET_ACCESS=${accessToken} - SECRET_ACCESS=${accessToken}
networks: networks:
- app-network - app-network
depends_on: depends_on:
- database - database
- traefik - traefik
${newsName}: ${newsName}:
image: krgamestudios/news-server:latest image: krgamestudios/news-server:latest
ports: ports:
- ${newsPort} - ${newsPort}
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.${newsName}router.rule=Host(\`${newsWebAddress}\`) - traefik.http.routers.${newsName}router.rule=Host(\`${newsWebAddress}\`)
- traefik.http.routers.${newsName}router.entrypoints=websecure - traefik.http.routers.${newsName}router.entrypoints=websecure
- traefik.http.routers.${newsName}router.tls.certresolver=myresolver - traefik.http.routers.${newsName}router.tls.certresolver=myresolver
- traefik.http.routers.${newsName}router.service=${newsName}service@docker - traefik.http.routers.${newsName}router.service=${newsName}service@docker
- traefik.http.services.${newsName}service.loadbalancer.server.port=${newsPort} - traefik.http.services.${newsName}service.loadbalancer.server.port=${newsPort}
environment: environment:
- WEB_PORT=${newsPort} - WEB_PORT=${newsPort}
- DB_HOSTNAME=database - DB_HOSTNAME=database
- DB_DATABASE=${newsName} - DB_DATABASE=${newsName}
- DB_USERNAME=${newsDBUser} - DB_USERNAME=${newsDBUser}
- DB_PASSWORD=${newsDBPass} - DB_PASSWORD=${newsDBPass}
- DB_TIMEZONE=${dbTimeZone} - DB_TIMEZONE=${dbTimeZone}
- QUERY_LIMIT=10 - QUERY_LIMIT=10
- SECRET_ACCESS=${accessToken} - SECRET_ACCESS=${accessToken}
networks: networks:
- app-network - app-network
depends_on: depends_on:
- database - database
- traefik - traefik
${authName}: ${authName}:
image: krgamestudios/auth-server:latest image: krgamestudios/auth-server:latest
ports: ports:
- ${authPort} - ${authPort}
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.${authName}router.rule=Host(\`${authWebAddress}\`) - traefik.http.routers.${authName}router.rule=Host(\`${authWebAddress}\`)
- traefik.http.routers.${authName}router.entrypoints=websecure - traefik.http.routers.${authName}router.entrypoints=websecure
- traefik.http.routers.${authName}router.tls.certresolver=myresolver - traefik.http.routers.${authName}router.tls.certresolver=myresolver
- traefik.http.routers.${authName}router.service=${authName}service@docker - traefik.http.routers.${authName}router.service=${authName}service@docker
- traefik.http.services.${authName}service.loadbalancer.server.port=${authPort} - traefik.http.services.${authName}service.loadbalancer.server.port=${authPort}
environment: environment:
- WEB_PROTOCOL=https - WEB_PROTOCOL=https
- WEB_ADDRESS=${authWebAddress} - WEB_ADDRESS=${authWebAddress}
- WEB_PORT=${authPort} - WEB_PORT=${authPort}
- DB_HOSTNAME=database - DB_HOSTNAME=database
- DB_DATABASE=${authName} - DB_DATABASE=${authName}
- DB_USERNAME=${authDBUser} - DB_USERNAME=${authDBUser}
- DB_PASSWORD=${authDBPass} - DB_PASSWORD=${authDBPass}
- DB_TIMEZONE=${dbTimeZone} - DB_TIMEZONE=${dbTimeZone}
- MAIL_SMTP=${emailSMTP} - MAIL_SMTP=${emailSMTP}
- MAIL_USERNAME=${emailUser} - MAIL_USERNAME=${emailUser}
- MAIL_PASSWORD=${emailPass} - MAIL_PASSWORD=${emailPass}
- MAIL_PHYSICAL=${emailPhysical} - MAIL_PHYSICAL=${emailPhysical}
- ADMIN_DEFAULT_USERNAME=${defaultUser} - ADMIN_DEFAULT_USERNAME=${defaultUser}
- ADMIN_DEFAULT_PASSWORD=${defaultPass} - ADMIN_DEFAULT_PASSWORD=${defaultPass}
- SECRET_ACCESS=${accessToken} - SECRET_ACCESS=${accessToken}
- SECRET_REFRESH=${refreshToken} - SECRET_REFRESH=${refreshToken}
networks: networks:
- app-network - app-network
depends_on: depends_on:
- database - database
- traefik - traefik
${chatName}: ${chatName}:
image: krgamestudios/chat-server:latest image: krgamestudios/chat-server:latest
ports: ports:
- ${chatPort} - ${chatPort}
labels: labels:
- traefik.enable=true - traefik.enable=true
- traefik.http.routers.${chatName}router.rule=Host(\`${chatWebAddress}\`) - traefik.http.routers.${chatName}router.rule=Host(\`${chatWebAddress}\`)
- traefik.http.routers.${chatName}router.entrypoints=websecure - traefik.http.routers.${chatName}router.entrypoints=websecure
- traefik.http.routers.${chatName}router.tls.certresolver=myresolver - traefik.http.routers.${chatName}router.tls.certresolver=myresolver
- traefik.http.routers.${chatName}router.service=${chatName}service@docker - traefik.http.routers.${chatName}router.service=${chatName}service@docker
- traefik.http.services.${chatName}service.loadbalancer.server.port=${chatPort} - traefik.http.services.${chatName}service.loadbalancer.server.port=${chatPort}
environment: environment:
- WEB_PORT=${chatPort} - WEB_PORT=${chatPort}
- DB_HOSTNAME=database - DB_HOSTNAME=database
- DB_DATABASE=${chatName} - DB_DATABASE=${chatName}
- DB_USERNAME=${chatDBUser} - DB_USERNAME=${chatDBUser}
- DB_PASSWORD=${chatDBPass} - DB_PASSWORD=${chatDBPass}
- DB_TIMEZONE=${dbTimeZone} - DB_TIMEZONE=${dbTimeZone}
- SECRET_ACCESS=${accessToken} - SECRET_ACCESS=${accessToken}
networks: networks:
- app-network - app-network
depends_on: depends_on:
- database - database
- traefik - traefik
database: database:
image: mariadb image: mariadb
restart: always restart: always
environment: environment:
MYSQL_ROOT_PASSWORD: ${dbRootPassword} MYSQL_ROOT_PASSWORD: ${dbRootPassword}
volumes: volumes:
- ./mysql:/var/lib/mysql - ./mysql:/var/lib/mysql
- ./startup.sql:/docker-entrypoint-initdb.d/startup.sql:ro - ./startup.sql:/docker-entrypoint-initdb.d/startup.sql:ro
networks: networks:
- app-network - app-network
traefik: traefik:
image: traefik:v2.4 image: traefik:v2.4
container_name: traefik container_name: traefik
command: command:
- --log.level=ERROR - --log.level=ERROR
- --api.insecure=false - --api.insecure=false
- --providers.docker=true - --providers.docker=true
- --providers.docker.exposedbydefault=false - --providers.docker.exposedbydefault=false
- --entrypoints.websecure.address=:443 - --entrypoints.websecure.address=:443
- --certificatesresolvers.myresolver.acme.tlschallenge=true - --certificatesresolvers.myresolver.acme.tlschallenge=true
- --certificatesresolvers.myresolver.acme.email=${supportEmail} - --certificatesresolvers.myresolver.acme.email=${supportEmail}
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
- traefik.docker.network=app-network - traefik.docker.network=app-network
ports: ports:
- 80:80 - 80:80
- 443:443 - 443:443
volumes: volumes:
- ./letsencrypt:/letsencrypt - ./letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro - /var/run/docker.sock:/var/run/docker.sock:ro
networks: networks:
- app-network - app-network
networks: networks:
app-network: app-network:
driver: bridge driver: bridge
`; `;
const dockerfile = ` const dockerfile = `
FROM node:15 FROM node:15
WORKDIR "/app" WORKDIR "/app"
COPY . /app COPY . /app
RUN mkdir /app/public RUN mkdir /app/public
RUN chown node:node /app/public RUN chown node:node /app/public
RUN npm install --production RUN npm install --production
EXPOSE ${projectPort} EXPOSE ${projectPort}
USER node USER node
ENTRYPOINT ["bash", "-c"] ENTRYPOINT ["bash", "-c"]
CMD ["sleep 10 && npm start"] CMD ["sleep 10 && npm start"]
`; `;
const sqlfile = ` const sqlfile = `
CREATE DATABASE IF NOT EXISTS ${projectName}; CREATE DATABASE IF NOT EXISTS ${projectName};
CREATE USER IF NOT EXISTS '${projectDBUser}'@'%' IDENTIFIED BY '${projectDBPass}'; CREATE USER IF NOT EXISTS '${projectDBUser}'@'%' IDENTIFIED BY '${projectDBPass}';
GRANT ALL PRIVILEGES ON ${projectName}.* TO '${projectDBUser}'@'%'; GRANT ALL PRIVILEGES ON ${projectName}.* TO '${projectDBUser}'@'%';
CREATE DATABASE IF NOT EXISTS ${newsName}; CREATE DATABASE IF NOT EXISTS ${newsName};
CREATE USER IF NOT EXISTS '${newsDBUser}'@'%' IDENTIFIED BY '${newsDBPass}'; CREATE USER IF NOT EXISTS '${newsDBUser}'@'%' IDENTIFIED BY '${newsDBPass}';
GRANT ALL PRIVILEGES ON ${newsName}.* TO '${newsDBUser}'@'%'; GRANT ALL PRIVILEGES ON ${newsName}.* TO '${newsDBUser}'@'%';
CREATE DATABASE IF NOT EXISTS ${authName}; CREATE DATABASE IF NOT EXISTS ${authName};
CREATE USER IF NOT EXISTS '${authDBUser}'@'%' IDENTIFIED BY '${authDBPass}'; CREATE USER IF NOT EXISTS '${authDBUser}'@'%' IDENTIFIED BY '${authDBPass}';
GRANT ALL PRIVILEGES ON ${authName}.* TO '${authDBUser}'@'%'; GRANT ALL PRIVILEGES ON ${authName}.* TO '${authDBUser}'@'%';
CREATE DATABASE IF NOT EXISTS ${chatName}; CREATE DATABASE IF NOT EXISTS ${chatName};
CREATE USER IF NOT EXISTS '${chatDBUser}'@'%' IDENTIFIED BY '${chatDBPass}'; CREATE USER IF NOT EXISTS '${chatDBUser}'@'%' IDENTIFIED BY '${chatDBPass}';
GRANT ALL PRIVILEGES ON ${chatName}.* TO '${chatDBUser}'@'%'; GRANT ALL PRIVILEGES ON ${chatName}.* TO '${chatDBUser}'@'%';
FLUSH PRIVILEGES; FLUSH PRIVILEGES;
`; `;
fs.writeFileSync('docker-compose.yml', ymlfile); fs.writeFileSync('docker-compose.yml', ymlfile);
fs.writeFileSync('Dockerfile', dockerfile); fs.writeFileSync('Dockerfile', dockerfile);
fs.writeFileSync('startup.sql', sqlfile); fs.writeFileSync('startup.sql', sqlfile);
})() })()
.then(() => rl.close()) .then(() => rl.close())
.catch(e => console.error(e)) .catch(e => console.error(e))
; ;