P4TB-131 add a disclaimer option

1.1.101
francesco 3 years ago
parent ff1568f5e9
commit 8f998339f0

@ -16,7 +16,7 @@ When we want to change the plugin preferences we can do so by
modifying three areas in the code:
- `options.xul` the markup, here you define the identifier for the option that will be used also elsewhere
- `prefsFactory.js` update getter and setter functions corresponding to the option
- `prefsFactory.js` update getter and setter functions corresponding to the option and the default value
- `options.js` update `addAll`, the window load handler, the dialogAccept handler
## Compat and Prefs

@ -29,6 +29,10 @@ if (typeof btoa === "undefined" && typeof require == "function") {
var btoa = require('btoa');
}
function deepCopy(obj) {
return obj && JSON.parse(JSON.stringify(obj));
}
class pEp {
constructor(env, logger, adapter, files, os) {
if (pEp.exists) return pEp.instance;
@ -228,9 +232,6 @@ class pEp {
}
static cloneMessage(source) {
function deepCopy(obj) {
return obj && JSON.parse(JSON.stringify(obj));
}
let clone = new pEp.Message(source.id,
source.shortmsg,
source.longmsg,
@ -244,6 +245,40 @@ class pEp {
source.bcc && clone.setBcc(source.bcc);
return clone;
}
setPrefs(prefs) {
this.prefs = prefs;
}
disclaimerStep(message) {
let mode = this.prefs.getDisclaimerMode();
let disclaimer = this.prefs.getDisclaimer();
function withDisclaimer(message) {
let modified = deepCopy(message);
modified.longmsg += "\r\n" + disclaimer;
return modified;
}
if (mode === "disclaimer-encrypted") {
return this
.getOngoingRating(
message.from,
message.to,
message.cc,
message.bcc)
.then((rating) => {
if (rating > 5) {
return withDisclaimer(message);
} else {
return message;
}
})
.catch(() => message );
} else if (mode === "disclaimer-all") {
return Promise.resolve(withDisclaimer(message));
} else {
return Promise.resolve(message);
}
}
}
pEp.Identity = class {

@ -6,6 +6,9 @@ tabpanel {
h3 {
padding-left: 8px; /* to match any groupbox below */
}
select, textarea {
margin: 0.5em 0;
}
.section {
margin-top: 0.1em;
margin-bottom: 0.1em;
@ -26,3 +29,6 @@ h3 {
padding: 0;
margin: 0;
}
.hidden {
display: none;
}

@ -1,10 +1,16 @@
// see developer.thunderbird.net/add-ons/updates/tb68
// i got an exception when trying to access preferences before this call
Preferences.addAll([
{ id: "extensions.p4tb.storeAllSecurely", type: "bool" },
{ id: "extensions.p4tb.warnUnencrypted", type: "bool" },
{ id: "extensions.p4tb.unprotectedSubjects", type: "bool" },
{ id: "extensions.p4tb.storeProtectedOptions", type: "bool" },
{ id: "extensions.p4tb.pEpSync", type: "bool" },
{ id: "extensions.p4tb.disclaimerMode", type: "string" },
{ id: "extensions.p4tb.disclaimer", type: "string" },
// `pristine` is used only by us in order to provide defaults, see
// `options.js`
{ id: "extensions.p4tb.initialised", type: "bool" },
// examples with different types
//{ id: "extensions.nameOfAddon.pref2", type: "string" },
//{ id: "extensions.nameOfAddon.pref3", type: "int" },
@ -15,17 +21,31 @@ const Compat = ChromeUtils.import("chrome://p4t/content/compatFactory.js")
const Prefs = ChromeUtils.import("chrome://p4t/content/prefsFactory.js")
.prefsFactory(Compat);
function update() {
let hidden = document.querySelector('#disclaimerMode').value === "disclaimer-none"
document.querySelector('#disclaimer').classList.toggle("hidden", hidden);
}
window.addEventListener('load', function () {
Prefs.maybeSetDefaults();
document.getElementById('storeAllSecurely').checked = Prefs.isStoreAllSecurely();
document.getElementById('warnUnencrypted').checked = Prefs.isWarnUnencrypted();
document.getElementById('disclaimerMode').value = Prefs.getDisclaimerMode();
document.getElementById('disclaimer').value = Prefs.getDisclaimer();
let acceptButton = document.querySelector('button#accept');
let cancelButton = document.querySelector('button#cancel');
acceptButton.addEventListener('click', function () {
Prefs.setIsStoreAllSecurely(document.getElementById('storeAllSecurely').checked);
Prefs.setWarnUnencrypted(document.getElementById('warnUnencrypted').checked);
Prefs.setDisclaimerMode(document.getElementById('disclaimerMode').value);
Prefs.setDisclaimer(document.getElementById('disclaimer').value);
window.close();
});
cancelButton.addEventListener('click', function () {
window.close();
});
update();
document.addEventListener('change', update);
});

@ -38,6 +38,27 @@
<checkbox disabled="true" id="storeProtectedOptions" preference="extensions.p4tb.storeProtectedOptions" label="Show store protected options" tooltiptext="" />
<checkbox disabled="true" id="pEpSync" preference="extensions.p4tb.pEpSync" label="Enable p≡p Sync" tooltiptext="" />
</groupbox>
<groupbox>
<hbox class="groupbox-title">
<label class="header">
Append a disclaimer to outgoing mail:
</label>
</hbox>
<html:select id="disclaimerMode">
<html:option value="disclaimer-none">
None
</html:option>
<html:option value="disclaimer-all">
All mail
</html:option>
<html:option value="disclaimer-encrypted">
Only encrypted mail
</html:option>
</html:select>
<html:textarea id="disclaimer" cols="80" rows="10">
Disclaimer text here
</html:textarea>
</groupbox>
<hbox>
<html:button id="cancel">
Cancel

@ -343,6 +343,8 @@ PgpMimeEncrypt.prototype = {
console.log(pEpMessage);
console.log("==============");
return this.pEpController.disclaimerStep(pEpMessage);
}).then((pEpMessage) => {
this.pEpController.encryptMailWithMessage(pEpMessage).then((result) => {
resultObj = result;

@ -99,12 +99,13 @@ var pEpComposer = {
// resolved. pEpComposer init is run when the compose window
// is open and privacy will be checked when the message is
// sent. A race condition is unlikely yet possible.
pEpController.setPrefs(this.prefs);
TbAbstraction.getCurrentIdentity().setIntAttribute("encryptionpolicy", 2);
},
initPrivacyWarning() {
let id = this.window.arguments[0].originalMsgURI;
if (typeof id == 'undefined') {
if (id === '') {
// these windows have no original, users are starting a
// new conversation
return Promise.reject();

@ -1,6 +1,10 @@
var pEpController = ChromeUtils.import("chrome://p4t/content/p4tb.js").pEpController;
var Helper = ChromeUtils.import("chrome://p4t/content/TbHelper.js").TbHelper;
var MessageView = ChromeUtils.import("chrome://p4t/content/TbMessageView.js").TbMessageView;
const Compat = ChromeUtils.import("chrome://p4t/content/compatFactory.js")
.compatFactory(window);
const Prefs = ChromeUtils.import("chrome://p4t/content/prefsFactory.js")
.prefsFactory(Compat);
var PEP_COLUMN_NAME = "pEpStatusCol";

@ -1,3 +1,4 @@
function prefsFactory(Compat) {
function newVersion () {
return Services.prefs.getBranch('extensions.p4tb.');
@ -5,9 +6,10 @@ function prefsFactory(Compat) {
function oldVersion () {
return Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService)
.getBranch("extensions.stockwatcher2.");
.getBranch("extensions.p4tb.");
}
const prefs = Compat.versionBranch(newVersion, oldVersion);
return {
isStoreAllSecurely: () => {
return prefs.getBoolPref('storeAllSecurely');
@ -20,6 +22,55 @@ function prefsFactory(Compat) {
},
setWarnUnencrypted: (v) => {
return prefs.setBoolPref('warnUnencrypted', v);
},
setDisclaimer: (v) => {
return prefs.setStringPref('disclaimer', v);
},
getDisclaimer: () => {
return prefs.getStringPref('disclaimer');
},
setDisclaimerMode: (v) => {
return prefs.setStringPref('disclaimerMode', v);
},
getDisclaimerMode: () => {
return prefs.getStringPref('disclaimerMode');
},
maybeSetDefaults: () => {
// set up default values to avoid exceptions when we try to access a
// preference for the first time
if (prefs.getBoolPref("initialised")) {
return;
} else {
let defaults = {
bool: {
"storeAllSecurely": true,
"warnUnencrypted": false,
"unprotectedSubjects": false,
"storeProtectedOptions": true,
"pEpSync": false,
"pristine": false // this is just for us to set up defaults
},
string: {
"disclaimerMode": "disclaimer-none",
"disclaimer": "Disclaimer text here"
}
}
function ObjectEntries(object) {
return Object
.keys(object)
.map((key) => {
return [key, object[key]];
});
}
function setter(type) {
return function([key, value]) {
prefs["set"+type+"Pref"](key, value);
}
}
ObjectEntries(defaults.bool).map(setter("Bool"));
ObjectEntries(defaults.string).map(setter("String"));
prefs.setBoolPref("initialised", true);
}
}
}
}

@ -30,3 +30,14 @@ your mail server
When you reply or forward a private message to untrusted receivers,
the conversation will continue without encryption. In this case you
will see a warning when this option is set
## Disclaimer
This option is designed to work with the disclaimer functionality
provided by your mail server. You can choose "Only encrypted mail" in
order for p≡p to add the disclaimer to encrypted messages that cannot
be modified by your mail server.
Alternatively you can disable the disclaimer on your server and select
"All mail" here to use only p≡p's disclaimer.

@ -1,6 +1,7 @@
/* eslint-disable no-console */
let {describe, it, before, beforeEach} = require('mocha');
let chai = require('chai').use(require('chai-as-promised'));
let sinon = require('sinon');
let getQueue = require('../mock').getQueue;
let getController = require('../boilerplate').getController;
let expect = require('chai').expect
@ -174,4 +175,50 @@ describe('controller calls', () => {
return result.should.become([]);
});
});
describe('appends the disclaimer, P4TB-131', () => {
it('to unencrypted messages', () => {
controller.setPrefs({
getDisclaimer: () => "disclaimer",
getDisclaimerMode: () => "disclaimer-all"
});
let prom = controller.disclaimerStep(messages.unencrypted.simple);
return expect(prom).to.eventually.have.property("longmsg", "body\r\ndisclaimer");
});
it('to encrypted messages', () => {
queue.respondWith({"jsonrpc":"2.0","id":21,"result":{"outParams":[{"rating": 6}],"return":{"status":0,"hex":"0 \"PEP_STATUS_OK\""},"errorstack":["(1 elements cleared)"]}});
controller.setPrefs({
getDisclaimer: () => "disclaimer",
getDisclaimerMode: () => "disclaimer-encrypted"
});
let prom = controller.disclaimerStep(messages.unencrypted.simple);
return expect(prom).to.eventually.have.property("longmsg", "body\r\ndisclaimer");
});
it('encrypted mode with unencrypted message', () => {
queue.respondWith({"jsonrpc":"2.0","id":21,"result":{"outParams":[{"rating":3}],"return":{"status":0,"hex":"0 \"PEP_STATUS_OK\""},"errorstack":["(1 elements cleared)"]}});
controller.setPrefs({
getDisclaimer: () => "disclaimer",
getDisclaimerMode: () => "disclaimer-encrypted"
});
let prom = controller.disclaimerStep(messages.unencrypted.simple);
return expect(prom).to.eventually.have.property("longmsg", "body");
});
it('none mode', () => {
controller.setPrefs({
getDisclaimer: () => "disclaimer",
getDisclaimerMode: () => "disclaimer-none"
});
let prom = controller.disclaimerStep(messages.unencrypted.simple);
return expect(prom).to.eventually.have.property("longmsg", "body");
});
it('leaves the message untouched when the call to the engine fails', () => {
controller.setPrefs({
getDisclaimer: () => "disclaimer",
getDisclaimerMode: () => "disclaimer-encrypted"
});
let rating = sinon.stub(controller, "getOngoingRating");
rating.returns(Promise.reject());
let prom = controller.disclaimerStep(messages.unencrypted.simple);
return expect(prom).to.eventually.have.property("longmsg", "body");
});
});
});

Loading…
Cancel
Save