Bug 1786920 - Show hostname in pop3 password dialog, prevent showing multiple auth dialogs. r=mkmelin

The bug is server.hostname should be server.hostName.
Take the chance to refactor MsgIncomingServer and MailAuthenticator a bit to prevent showing multiple auth dialogs for the same server.

Differential Revision: https://phabricator.services.mozilla.com/D155534

--HG--
extra : amend_source : 67039c16f44a4c3bb2062fd67b50c32b99e9d7b9
This commit is contained in:
Ping Chen 2022-08-25 20:43:19 +10:00
Родитель 646ba07646
Коммит 05769e8fe1
6 изменённых файлов: 95 добавлений и 80 удалений

Просмотреть файл

@ -66,24 +66,6 @@ class MailAuthenticator {
);
}
/**
* Get the ByteString form of the current password.
* @returns string
*/
getByteStringPassword() {
return MailStringUtils.stringToByteString(this.getPassword());
}
/**
* Get the PLAIN auth token for a connection.
* @returns string
*/
getPlainToken() {
// According to rfc4616#section-2, password should be UTF-8 BinaryString
// before base64 encoded.
return btoa("\0" + this.username + "\0" + this.getByteStringPassword());
}
/**
* Get the CRAM-MD5 auth token for a connection.
* @param {string} password - The password, used as HMAC-MD5 secret.
@ -293,6 +275,24 @@ class SmtpAuthenticator extends MailAuthenticator {
);
}
/**
* Get the ByteString form of the current password.
* @returns string
*/
getByteStringPassword() {
return MailStringUtils.stringToByteString(this.getPassword());
}
/**
* Get the PLAIN auth token for a connection.
* @returns string
*/
getPlainToken() {
// According to rfc4616#section-2, password should be UTF-8 BinaryString
// before base64 encoded.
return btoa("\0" + this.username + "\0" + this.getByteStringPassword());
}
async getOAuthToken() {
let oauth2Module = Cc["@mozilla.org/mail/oauth2-module;1"].createInstance(
Ci.msgIOAuth2Module
@ -345,6 +345,26 @@ class IncomingServerAuthenticator extends MailAuthenticator {
this._server.forgetPassword();
}
/**
* Get the ByteString form of the current password.
* @returns string
*/
async getByteStringPassword() {
return MailStringUtils.stringToByteString(await this.getPassword());
}
/**
* Get the PLAIN auth token for a connection.
* @returns string
*/
async getPlainToken() {
// According to rfc4616#section-2, password should be UTF-8 BinaryString
// before base64 encoded.
return btoa(
"\0" + this.username + "\0" + (await this.getByteStringPassword())
);
}
async getOAuthToken() {
let oauth2Module = Cc["@mozilla.org/mail/oauth2-module;1"].createInstance(
Ci.msgIOAuth2Module
@ -380,27 +400,31 @@ class NntpAuthenticator extends IncomingServerAuthenticator {
* @extends {IncomingServerAuthenticator}
*/
class Pop3Authenticator extends IncomingServerAuthenticator {
getPassword() {
async getPassword() {
if (this._server.password) {
return this._server.password;
}
let composeBundle = Services.strings.createBundle(
"chrome://messenger/locale/localMsgs.properties"
);
let params = [this._server.username, this._server.hostname];
let params = [this._server.username, this._server.hostName];
let promptString = composeBundle.formatStringFromName(
"pop3EnterPasswordPrompt",
params
);
let promptTitle = composeBundle.formatStringFromName(
"pop3EnterPasswordPromptTitleWithUsername",
[this._server.hostname]
[this._server.hostName]
);
let msgWindow;
try {
msgWindow = MailServices.mailSession.topmostMsgWindow;
} catch (e) {}
return this._server.getPasswordWithUI(promptString, promptTitle, msgWindow);
return this._server.wrappedJSObject.getPasswordWithUIAsync(
promptString,
promptTitle,
msgWindow
);
}
promptAuthFailed() {
@ -420,20 +444,20 @@ class ImapAuthenticator extends IncomingServerAuthenticator {
let composeBundle = Services.strings.createBundle(
"chrome://messenger/locale/imapMsgs.properties"
);
let params = [this._server.username, this._server.hostname];
let params = [this._server.username, this._server.hostName];
let promptString = composeBundle.formatStringFromName(
"imapEnterServerPasswordPrompt",
params
);
let promptTitle = composeBundle.formatStringFromName(
"imapEnterPasswordPromptTitleWithUsername",
[this._server.hostname]
[this._server.hostName]
);
let msgWindow;
try {
msgWindow = MailServices.mailSession.topmostMsgWindow;
} catch (e) {}
return this._server.wrappedJSObject.getPasswordFromAuthPrompt(
return this._server.wrappedJSObject.getPasswordWithUIAsync(
promptString,
promptTitle,
msgWindow

Просмотреть файл

@ -1161,4 +1161,38 @@ class MsgIncomingServer {
}
performExpand(msgWindow) {}
get wrappedJSObject() {
return this;
}
_passwordPromise = null;
/**
* Show a password prompt. If a prompt is currently shown, just wait for it.
* @param {string} message - The text inside the prompt.
* @param {string} title - The title of the prompt.
* @param {nsIMsgWindow} - The associated msg window.
*/
async getPasswordWithUIAsync(promptMessage, promptTitle, msgWindow) {
if (this._passwordPromise) {
await this._passwordPromise;
return this.password;
}
let deferred = {};
this._passwordPromise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
try {
this.getPasswordWithUI(promptMessage, promptTitle, msgWindow);
} catch (e) {
deferred.reject(e);
throw e;
} finally {
this._passwordPromise = null;
}
deferred.resolve();
return this.password;
}
}

Просмотреть файл

@ -800,15 +800,7 @@ class ImapClient {
*/
_actionAuthPlain = async res => {
this._nextAction = this._actionAuthResponse;
// According to rfc4616#section-2, password should be BinaryString before
// base64 encoded.
let password = MailStringUtils.stringToByteString(
await this._getPassword()
);
this._send(
btoa("\0" + this._authenticator.username + "\0" + password),
true
);
this._send(await this._authenticator.getPlainToken(), true);
};
/**

Просмотреть файл

@ -390,46 +390,12 @@ class ImapIncomingServer extends MsgIncomingServer {
}
}
get wrappedJSObject() {
return this;
}
_capabilities = [];
set capabilities(value) {
this._capabilities = value;
}
_passwordPromise = null;
/**
* Show a password prompt. If a prompt is currently shown, just wait for it.
* @param {string} message - The text inside the prompt.
* @param {string} title - The title of the prompt.
* @param {nsIMsgWindow} - The associated msg window.
*/
async getPasswordFromAuthPrompt(message, title, msgWindow) {
if (this._passwordPromise) {
await this._passwordPromise;
return this.password;
}
let deferred = {};
this._passwordPromise = new Promise((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});
try {
this.getPasswordWithUI(message, title, msgWindow);
} catch (e) {
deferred.reject(e);
throw e;
} finally {
this._passwordPromise = null;
}
deferred.resolve();
return this.password;
}
// @type {ImapClient[]} - An array of connections can be used.
_freeConnections = [];
// @type {ImapClient[]} - An array of connections in use.

Просмотреть файл

@ -702,25 +702,28 @@ class Pop3Client {
/**
* The second step of USER/PASS auth, send the password to the server.
*/
_actionAuthUserPass = res => {
_actionAuthUserPass = async res => {
if (!res.success) {
this._actionError("pop3UsernameFailure", [], res.statusText);
return;
}
this._nextAction = this._actionAuthResponse;
this._send(`PASS ${this._authenticator.getByteStringPassword()}`, true);
this._send(
`PASS ${await this._authenticator.getByteStringPassword()}`,
true
);
};
/**
* The second step of PLAIN auth, send the auth token to the server.
*/
_actionAuthPlain = res => {
_actionAuthPlain = async res => {
if (!res.success) {
this._actionError("pop3UsernameFailure", [], res.statusText);
return;
}
this._nextAction = this._actionAuthResponse;
this._send(this._authenticator.getPlainToken(), true);
this._send(await this._authenticator.getPlainToken(), true);
};
/**
@ -735,14 +738,14 @@ class Pop3Client {
/**
* The third step of LOGIN auth, send the password to the server.
*/
_actionAuthLoginPass = res => {
_actionAuthLoginPass = async res => {
if (!res.success) {
this._actionError("pop3UsernameFailure", [], res.statusText);
return;
}
this._nextAction = this._actionAuthResponse;
this._logger.debug("AUTH LOGIN PASS");
let password = this._authenticator.getPassword();
let password = await this._authenticator.getPassword();
if (
!Services.prefs.getBoolPref(
"mail.smtp_login_pop3_user_pass_auth_is_latin1",
@ -763,7 +766,7 @@ class Pop3Client {
* The second step of CRAM-MD5 auth, send a HMAC-MD5 signature to the server.
* @param {Pop3Response} res - AUTH response received from the server.
*/
_actionAuthCramMd5 = res => {
_actionAuthCramMd5 = async res => {
if (!res.success) {
this._actionError("pop3UsernameFailure", [], res.statusText);
return;
@ -771,7 +774,7 @@ class Pop3Client {
this._nextAction = this._actionAuthResponse;
this._send(
this._authenticator.getCramMd5Token(
this._authenticator.getPassword(),
await this._authenticator.getPassword(),
res.statusText
),
true

Просмотреть файл

@ -558,10 +558,6 @@ class NntpIncomingServer extends MsgIncomingServer {
);
}
get wrappedJSObject() {
return this;
}
/**
* Get an idle connection that can be used.
* @returns {NntpClient}