mostly because code is being autogenerated by all the AI stuff using this prefix. it's also used in the stack trace.
122 lines
5.5 KiB
JavaScript
122 lines
5.5 KiB
JavaScript
'use strict';
|
|
|
|
var async = require('async'),
|
|
crypto = require('node:crypto'),
|
|
fs = require('node:fs'),
|
|
os = require('node:os'),
|
|
path = require('node:path'),
|
|
safe = require('safetydance'),
|
|
tldjs = require('tldjs');
|
|
|
|
exports.up = function(db, callback) {
|
|
db.all('SELECT * FROM apps', function (error, apps) {
|
|
if (error) return callback(error);
|
|
|
|
async.eachSeries(apps, function (app, callback) {
|
|
if (!app.altDomain) {
|
|
console.log('App %s does not use altDomain, skip', app.id);
|
|
return callback();
|
|
}
|
|
|
|
const domain = tldjs.getDomain(app.altDomain);
|
|
const subdomain = tldjs.getSubdomain(app.altDomain);
|
|
const mailboxName = (subdomain ? subdomain : JSON.parse(app.manifestJson).title.toLowerCase().replace(/[^a-zA-Z0-9]/g, '')) + '.app';
|
|
|
|
console.log('App %s is on domain %s and subdomain %s with mailbox', app.id, domain, subdomain, mailboxName);
|
|
|
|
async.series([
|
|
// Add domain if not exists
|
|
function (callback) {
|
|
const query = 'INSERT INTO domains (domain, zoneName, provider, configJson, tlsConfigJson) VALUES (?, ?, ?, ?, ?)';
|
|
const args = [ domain, domain, 'manual', JSON.stringify({}), JSON.stringify({ provider: 'letsencrypt-prod' }) ];
|
|
|
|
db.runSql(query, args, function (error) {
|
|
if (error && error.code !== 'ER_DUP_ENTRY') return callback(error);
|
|
|
|
console.log('Added domain %s', domain);
|
|
|
|
// ensure we have a fallback cert for the newly added domain. This is the same as in reverseproxy.js
|
|
// WARNING this will only work on the cloudron itself not during local testing!
|
|
const certFilePath = `/home/yellowtent/boxdata/certs/${domain}.host.cert`;
|
|
const keyFilePath = `/home/yellowtent/boxdata/certs/${domain}.host.key`;
|
|
|
|
if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) { // generate it
|
|
let opensslConf = safe.fs.readFileSync('/etc/ssl/openssl.cnf', 'utf8');
|
|
let opensslConfWithSan = `${opensslConf}\n[SAN]\nsubjectAltName=DNS:${domain}\n`;
|
|
let configFile = path.join(os.tmpdir(), 'openssl-' + crypto.randomBytes(4).readUInt32LE(0) + '.conf');
|
|
let certCommand = `openssl req -x509 -newkey rsa:2048 -keyout ${keyFilePath} -out ${certFilePath} -days 3650 -subj /CN=*.${domain} -extensions SAN -config ${configFile} -nodes`;
|
|
|
|
safe.fs.writeFileSync(configFile, opensslConfWithSan, 'utf8');
|
|
if (!safe.child_process.execSync(certCommand)) return callback(safe.error.message);
|
|
safe.fs.unlinkSync(configFile);
|
|
}
|
|
|
|
callback();
|
|
});
|
|
},
|
|
// Add domain to mail table if not exists
|
|
function (callback) {
|
|
const query = 'INSERT INTO mail (domain, enabled, mailFromValidation, catchAllJson, relayJson) VALUES (?, ?, ?, ?, ?)';
|
|
const args = [ domain, 0, 1, '[]', JSON.stringify({ provider: 'cloudron-smtp' }) ];
|
|
|
|
db.runSql(query, args, function (error) {
|
|
if (error && error.code !== 'ER_DUP_ENTRY') return callback(error);
|
|
|
|
console.log('Added domain %s to mail table', domain);
|
|
|
|
callback();
|
|
});
|
|
},
|
|
// Remove old mailbox record if any
|
|
function (callback) {
|
|
const query = 'DELETE FROM mailboxes WHERE ownerId=?';
|
|
const args = [ app.id ];
|
|
|
|
db.runSql(query, args, function (error) {
|
|
if (error) return callback(error);
|
|
|
|
console.log('Cleaned up mailbox record for app %s', app.id);
|
|
|
|
callback();
|
|
});
|
|
},
|
|
// Add new mailbox record
|
|
function (callback) {
|
|
const query = 'INSERT INTO mailboxes (name, domain, ownerId, ownerType) VALUES (?, ?, ?, ?)';
|
|
const args = [ mailboxName, domain, app.id, 'app' /* mailboxdb.TYPE_APP */ ];
|
|
|
|
db.runSql(query, args, function (error) {
|
|
if (error) return callback(error);
|
|
|
|
console.log('Added mailbox record for app %s', app.id);
|
|
|
|
callback();
|
|
});
|
|
},
|
|
// Update app record
|
|
function (callback) {
|
|
const query = 'UPDATE apps SET location=?, domain=?, altDomain=? WHERE id=?';
|
|
const args = [ subdomain, domain, '', app.id ];
|
|
|
|
db.runSql(query, args, function (error) {
|
|
if (error) return error;
|
|
|
|
console.log('Updated app %s with new domain', app.id);
|
|
|
|
callback();
|
|
});
|
|
}
|
|
], callback);
|
|
}, function (error) {
|
|
if (error) return callback(error);
|
|
|
|
// finally drop the altDomain db field
|
|
db.runSql('ALTER TABLE apps DROP COLUMN altDomain', [], callback);
|
|
});
|
|
});
|
|
};
|
|
|
|
exports.down = function(db, callback) {
|
|
db.runSql('ALTER TABLE apps ADD COLUMN altDomain VARCHAR(256)', [], callback);
|
|
};
|