a-mail-signature
Version:
Generate and modify Apple Mail E-Mail signatures
171 lines (170 loc) • 8.1 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const os_1 = __importDefault(require("os"));
const inline_css_1 = __importDefault(require("inline-css"));
const plist_1 = __importDefault(require("plist"));
const prompt = require('select-prompt');
const xattr = require('fs-xattr');
const log_1 = require("./log");
const enums_1 = require("./enums");
const BASE_DIR = process.env.LOCAL_HOME_DIR
? 'test-drive/home-drive'
: os_1.default.homedir();
/**
* determine the current used base path
* for storing mail signatures in apple mail
*/
exports.getBasePath = (mailDir) => {
if (mailDir === 'container') {
mailDir = `${BASE_DIR}/Library/Containers/com.apple.mail/Data/Library/Mail`;
}
const baseDir = mailDir || `${BASE_DIR}/Library/Mail`;
const persistenceInfoPath = `${baseDir}/${enums_1.fileDefaults.persistenceInfo}`;
const persistenceInfoParsed = plist_1.default.parse(fs_1.default.readFileSync(persistenceInfoPath, 'utf8'));
return `${baseDir}/${persistenceInfoParsed.LastUsedVersionDirectoryName}/MailData/Signatures`;
};
/**
* add a signature entry to the file containing all signatures
* @param uuid the uuid for the signature to be added
*/
exports.addSignatureToAllSignatures = (uuid, name, mailDir) => {
const allSignaturesParsed = plist_1.default.parse(fs_1.default.readFileSync(`${exports.getBasePath(mailDir)}/${enums_1.fileDefaults.allSignatures}`, 'utf8'));
if (allSignaturesParsed.find((signature) => signature.SignatureUniqueId === uuid)) {
log_1.logError(`Signature with unique ID "${uuid}" already exists`);
process.exit(1);
}
const dictJson = [
...allSignaturesParsed,
{
SignatureIsRich: false,
SignatureName: name,
SignatureUniqueId: uuid,
},
];
const plistResult = plist_1.default.build(dictJson);
fs_1.default.writeFileSync(`${exports.getBasePath()}/${enums_1.fileDefaults.allSignatures}`, plistResult, 'utf8');
};
/**
* Promt the user to select the account to which the signature will be added
* @param uuid the uuid for the signature to be added
*/
exports.addSignatureToAccount = (uuid, mailDir) => {
const accountMapParsed = plist_1.default.parse(fs_1.default.readFileSync(`${exports.getBasePath(mailDir)}/${enums_1.fileDefaults.accountMap}`, 'utf8'));
return new Promise((resolve) => {
const accounts = [];
for (let [key, value] of Object.entries(accountMapParsed)) {
accounts.push({
title: value.AccountURL.replace('%40', '@'),
value: key,
});
}
prompt('To which account you want to add this signature?', accounts)
.on('abort', (v) => {
log_1.logWarn('No account selected. No signature added.');
process.exit(2);
})
.on('submit', (v) => {
if (accountMapParsed[v].Signatures.includes(uuid)) {
log_1.logWarn(`Signature with unique ID "${uuid}" is already linked with account ${accountMapParsed[v].AccountURL}. Action skipped.`);
}
else {
accountMapParsed[v].Signatures.push(uuid);
}
const plistResult = plist_1.default.build(
// workaround because of wrong type matching
JSON.parse(JSON.stringify(accountMapParsed)));
fs_1.default.writeFileSync(`${exports.getBasePath()}/${enums_1.fileDefaults.accountMap}`, plistResult, 'utf8');
resolve();
});
});
};
/**
* create the mail signature file
* @param uuid the uuid for the signature to be added
* @param templateFilePath the template file to be used
*/
exports.createMailSignature = (uuid, templateFilePath, update = false, mailDir) => __awaiter(void 0, void 0, void 0, function* () {
const filePath = `${exports.getBasePath(mailDir)}/${uuid}.mailsignature`;
if (!update && fs_1.default.existsSync(filePath)) {
log_1.logError(`Signature file "${uuid}.mailsignature" already exists`);
process.exit(1);
}
const htmlTemplate = fs_1.default.readFileSync(templateFilePath, 'utf8');
let inlinedHtml = yield inline_css_1.default(htmlTemplate, {
url: ' ',
removeStyleTags: true,
removeLinkTags: true,
});
inlinedHtml = inlinedHtml
.replace(/(.|\n)*<body.*>/, '') // replace everything until "body>"
.replace(/<\/body(.|\n)*/g, ''); // replace everything before "</body"
const fileContent = `Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
charset=utf-8
Mime-Version: 1.0
<body>${inlinedHtml}</body>
`;
fs_1.default.writeFileSync(filePath, fileContent, 'utf8');
yield xattr.set(filePath, 'com.apple.quarantine', new Buffer(19));
});
/**
* Find an existing signature by it's name
* @param name the signature name
*/
exports.getSignatureIdByName = (name, mailDir) => {
const allSignaturesParsed = plist_1.default.parse(fs_1.default.readFileSync(`${exports.getBasePath(mailDir)}/${enums_1.fileDefaults.allSignatures}`, 'utf8'));
const signatureToBeRemoved = allSignaturesParsed.find((signature) => signature.SignatureName === name);
if (!signatureToBeRemoved) {
log_1.logError(`The signature with the name "${name}" doesn't exist`);
process.exit(1);
}
return signatureToBeRemoved.SignatureUniqueId;
};
/**
* Delete an existing mail signature
* @param name the name for the signature that should be deleted
*/
exports.removeSignatureFromAllSignatures = (name, mailDir) => {
const allSignaturesParsed = plist_1.default.parse(fs_1.default.readFileSync(`${exports.getBasePath(mailDir)}/${enums_1.fileDefaults.allSignatures}`, 'utf8'));
const signatureToBeRemoved = exports.getSignatureIdByName(name);
const filteredSignatures = allSignaturesParsed.filter((signature) => signature.SignatureName !== name);
const dictJson = filteredSignatures;
const plistResult = plist_1.default.build(dictJson);
fs_1.default.writeFileSync(`${exports.getBasePath(mailDir)}/${enums_1.fileDefaults.allSignatures}`, plistResult, 'utf8');
return signatureToBeRemoved;
};
/**
* remove an existing mail signature file
* @param uuid the uuid for the signature to be removed
*/
exports.removeMailSignature = (uuid, mailDir) => {
fs_1.default.unlinkSync(`${exports.getBasePath(mailDir)}/${uuid}.mailsignature`);
};
/**
* Promt the user to select the account to which the signature will be added
* @param uuid the uuid for the signature to be added
*/
exports.removeSignatureFromAccount = (uuid, mailDir) => {
const accountMapParsed = plist_1.default.parse(fs_1.default.readFileSync(`${exports.getBasePath(mailDir)}/${enums_1.fileDefaults.accountMap}`, 'utf8'));
for (let account of Object.values(accountMapParsed)) {
account.Signatures = account.Signatures.filter((v) => v !== uuid);
}
const plistResult = plist_1.default.build(
// workaround because of wrong type matching
JSON.parse(JSON.stringify(accountMapParsed)));
fs_1.default.writeFileSync(`${exports.getBasePath(mailDir)}/${enums_1.fileDefaults.accountMap}`, plistResult, 'utf8');
};
//# sourceMappingURL=utils.js.map