--HG--
extra : rebase_source : 4905bf56bf8efc90b49f99f56603a93908efdd63
This commit is contained in:
Anant Narayanan 2009-07-21 14:31:16 -07:00
Родитель 560c2aac4b
Коммит e44d2d0d1a
12 изменённых файлов: 316 добавлений и 149 удалений

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

@ -0,0 +1,58 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<?xml-stylesheet href="chrome://weave/content/login.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://weave/locale/preferences.dtd">
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="changepph-dialog"
windowtype="Weave:ChangePassphrase"
title="&pph.title;"
buttons="accept,cancel"
buttonlabelaccept="&pph.accept;"
buttonlabelcancel="&pph.cancel;"
ondialogaccept="return Login.doResetPassphrase();"
ondialogcancel="return true;"
defaultButton="accept">
<script type="application/x-javascript" src="chrome://weave/content/load-weave.js"/>
<script type="application/x-javascript" src="chrome://weave/content/preferences.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="weaveStringBundle" src="chrome://weave/locale/preferences.properties"/>
</stringbundleset>
<hbox align="center">
<label class="title" value="&pph.message;"/>
</hbox>
<vbox>
<grid>
<columns>
<column pack="left" align="right"/>
<column/>
</columns>
<rows>
<row align="center">
<hbox flex="1" align="right">
<label value="&pph.enterNew1;"/>
</hbox>
<textbox id="newPassphrase1" type="password"/>
</row>
<row align="center">
<hbox flex="1" align="right">
<label value="&pph.enterNew2;"/>
</hbox>
<textbox id="newPassphrase2" type="password"/>
</row>
<row><label value=""/></row>
</rows>
</grid>
<hbox align="center">
<image id="pphStatusIcon" class="statusIcon"/>
<label id="pphStatus" class="status"/>
</hbox>
</vbox>
</dialog>

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

@ -0,0 +1,58 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
<?xml-stylesheet href="chrome://weave/content/login.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://weave/locale/login.dtd">
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="forgotpph-dialog"
windowtype="Weave:ForgotPassphrase"
title="&pph.title;"
buttons="accept,cancel"
buttonlabelaccept="&pph.accept;"
buttonlabelcancel="&pph.cancel;"
ondialogaccept="return Login.doResetPassphrase();"
ondialogcancel="return true;"
defaultButton="accept">
<script type="application/x-javascript" src="chrome://weave/content/load-weave.js"/>
<script type="application/x-javascript" src="chrome://weave/content/login.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="weaveStringBundle" src="chrome://weave/locale/login.properties"/>
</stringbundleset>
<hbox align="center">
<label class="title" value="&pph.message;"/>
</hbox>
<vbox>
<grid>
<columns>
<column pack="left" align="right"/>
<column/>
</columns>
<rows>
<row align="center">
<hbox flex="1" align="right">
<label value="&pph.enter1;"/>
</hbox>
<textbox id="newPassphrase1" type="password"/>
</row>
<row align="center">
<hbox flex="1" align="right">
<label value="&pph.enter2;"/>
</hbox>
<textbox id="newPassphrase2" type="password"/>
</row>
<row><label value=""/></row>
</rows>
</grid>
<hbox align="center">
<image id="pphStatusIcon" class="statusIcon"/>
<label id="pphStatus" class="status"/>
</hbox>
</vbox>
</dialog>

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

@ -102,6 +102,9 @@
<button id="change-password-button"
label="&changePasswordButton.label;"
oncommand="gWeavePrefs.doChangePassword()"/>
<button id="change-passphrase-button"
label="&changePassphraseButton.label;"
oncommand="Weave.Utils.openDialog('ChangePassphrase', 'changepph.xul')"/>
<button id="signOutButton" label="&signOutButton.label;"
oncommand="gWeavePrefs.doSignOut()"/>
</hbox>

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

@ -3,11 +3,6 @@
padding-right: 5px;
}
#loginTitle {
font-size: 14px;
font-weight: bold;
}
#loginStatusBox {
margin-top: 10px;
height: 16px;
@ -18,18 +13,23 @@
font-weight: bold;
}
#loginStatus {
.title {
font-size: 14px;
font-weight: bold;
}
#loginStatusIcon[status="active"] {
.status {
font-weight: bold;
}
.statusIcon[status="active"] {
list-style-image: url("chrome://global/skin/icons/loading_16.png");
}
#loginStatusIcon[status="error"] {
.statusIcon[status="error"] {
list-style-image: url("chrome://global/skin/icons/error-16.png");
}
#loginStatusIcon[status="success"] {
.statusIcon[status="success"] {
list-style-image: url("chrome://global/skin/icons/information-16.png");
}

83
source/chrome/content/login.js Normal file → Executable file
Просмотреть файл

@ -22,16 +22,31 @@ let Login = {
return this._loginDialog = document.getElementById("login-dialog");
},
get _forgotDialog() {
delete this._forgotDialog;
return this._forgotDialog = document.getElementById("forgotpph-dialog");
},
get _loginStatus() {
delete this._loginStatus;
return this._loginStatus = document.getElementById("loginStatus");
},
get _forgotStatus() {
delete this._forgotStatus;
return this._forgotStatus = document.getElementById("pphStatus");
},
get _loginStatusIcon() {
delete this._loginStatusIcon;
return this._loginStatusIcon = document.getElementById("loginStatusIcon");
},
get _forgotStatusIcon() {
delete this._forgotStatusIcon;
return this._forgotStatusIcon = document.getElementById("pphStatusIcon");
},
onLoad: function Login_onLoad() {
this._log = Log4Moz.repository.getLogger("Chrome.Login");
this._log.trace("Sync login window opened");
@ -39,6 +54,8 @@ let Login = {
this._os.addObserver(this, "weave:service:login:start", false);
this._os.addObserver(this, "weave:service:login:error", false);
this._os.addObserver(this, "weave:service:login:finish", false);
this._os.addObserver(this, "weave:service:resetpph:error", false);
this._os.addObserver(this, "weave:service:resetpph:finish", false);
if (Weave.Utils.prefs.getBoolPref("rememberpassword"))
document.getElementById("save-password-checkbox").checked = true;
@ -69,6 +86,8 @@ let Login = {
this._os.removeObserver(this, "weave:service:login:start");
this._os.removeObserver(this, "weave:service:login:error");
this._os.removeObserver(this, "weave:service:login:finish");
this._os.removeObserver(this, "weave:service:resetpph:error");
this._os.removeObserver(this, "weave:service:resetpph:finish");
this._log.trace("Sync login window closed");
},
@ -88,8 +107,8 @@ let Login = {
this._loginDialog.defaultButton = "cancel";
cancel.focus();
break;
case "weave:service:login:error":
this._loginStatusIcon.setAttribute("status", "error");
this._loginStatus.value = this._stringBundle.getString("loginError.label");
@ -98,14 +117,29 @@ let Login = {
this._loginDialog.getButton("cancel").setAttribute("label", this._origCancel);
this._loginDialog.defaultButton = "extra2";
document.getElementById("username").focus();
break;
case "weave:service:login:finish":
this._loginStatusIcon.setAttribute("status", "success");
this._loginStatus.value = this._stringBundle.getString("loginSuccess.label");
this._loginStatus.style.color = "blue";
window.setTimeout(window.close, 1500);
break;
case "weave:service:resetpph:error":
this._forgotStatusIcon.setAttribute("status", "error");
this._forgotStatus.value = this._stringBundle.getString("pphError.label");
this._forgotStatus.style.color = "red";
this._forgotDialog.getButton("cancel").setAttribute("disabled", "false");
this._forgotDialog.getButton("accept").setAttribute("disabled", "false");
break;
case "weave:service:resetpph:finish":
this._forgotStatusIcon.setAttribute("status", "success");
this._forgotStatus.value = this._stringBundle.getString("pphSuccess.label");
this._forgotStatus.style.color = "blue";
window.setTimeout(window.close, 1500);
break;
}
},
@ -125,6 +159,11 @@ let Login = {
Weave.Utils.prefs.setBoolPref("rememberpassword", savePass.checked);
Weave.Utils.prefs.setBoolPref("autoconnect", autoconnect.checked);
if (!username.value) {
alert(this._stringBundle.getString("noUsername.alert"));
return false;
}
if (!password.value) {
alert(this._stringBundle.getString("noPassword.alert"));
return false;
@ -156,8 +195,46 @@ let Login = {
return true;
},
doCancel: function Login_doCancel() { return true; }
doCancel: function Login_doCancel() { return true; },
showResetPassphrase: function Login_showResetPassphrase() {
let username = document.getElementById("username");
let password = document.getElementById("password");
if (!username.value) {
alert(this._stringBundle.getString("noUsername.alert"));
return false;
}
if (!password.value) {
alert(this._stringBundle.getString("noPassword.alert"));
return false;
}
Weave.Utils.openDialog('ForgotPassphrase', 'forgotpph.xul');
},
doResetPassphrase: function Login_doResetPassphrase() {
let pph1 = document.getElementById("newPassphrase1");
let pph2 = document.getElementById("newPassphrase2");
if (!pph1.value) {
alert(this._stringBundle.getString("noPassphrase.alert"));
} else if (pph1.value != pph2.value) {
alert(this._stringBundle.getString("pphNoMatch.alert"));
} else {
this._forgotStatusIcon.setAttribute("status", "active");
this._forgotStatus.value = this._stringBundle.getString("pphStart.label");
this._forgotStatus.style.color = "-moz-dialogtext";
this._forgotDialog.getButton("cancel").setAttribute("disabled", "true");
this._forgotDialog.getButton("accept").setAttribute("disabled", "true");
Weave.Service.resetPassphrase(pph1.value);
this._loginDialog.cancelDialog();
return true;
}
return false;
}
};
window.addEventListener("load", function(e) { Login.onLoad(); }, false);

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

@ -60,6 +60,7 @@
<label class="text-link" value="&whatsThis.label;"
onclick="window.open('https://services.mozilla.com/help/login/');"/>
</hbox>
<label class="text-link" value="&forgotPhrase.label;" onclick="Login.showResetPassphrase();"/>
</row>
<row><label value=""/></row>
</rows>
@ -69,8 +70,8 @@
<checkbox id="autoconnect-checkbox" label="&autoconnect.label;"/>
<hbox id="loginStatusBox" align="center">
<image id="loginStatusIcon"/>
<label id="loginStatus"/>
<image id="loginStatusIcon" class="statusIcon"/>
<label id="loginStatus" class="status"/>
</hbox>
</vbox>
</dialog>

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

@ -1,6 +1,10 @@
var Ci = Components.interfaces;
var Cc = Components.classes;
var Cr = Components.results;
var Cu = Components.utils;
Cu.import("resource://weave/base_records/wbo.js");
Cu.import("resource://weave/base_records/keys.js");
function WeavePrefs() {
this._log = Log4Moz.repository.getLogger("Chrome.Prefs");
@ -48,6 +52,7 @@ WeavePrefs.prototype = {
let createButton = document.getElementById('sync-create-button');
let syncUserName = document.getElementById('sync-username-field');
let changePasswordButton = document.getElementById('change-password-button');
let changePassphraseButton = document.getElementById('change-passphrase-button');
if (!Weave.Service.isLoggedIn) {
signOnButton.setAttribute("hidden", "false");
@ -56,6 +61,7 @@ WeavePrefs.prototype = {
syncNowButton.setAttribute("disabled", "true");
syncUserName.setAttribute("value", "");
changePasswordButton.setAttribute("hidden", "true");
changePassphraseButton.setAttribute("hidden", "true");
} else {
let signedInDescription =
this._stringBundle.getFormattedString("signedIn.description",
@ -66,6 +72,7 @@ WeavePrefs.prototype = {
syncNowButton.setAttribute("disabled", "false");
syncUserName.setAttribute("value", signedInDescription);
changePasswordButton.setAttribute("hidden", "true"); // FIXME: temp
changePassphraseButton.setAttribute("hidden", "false");
}
},
@ -141,132 +148,37 @@ WeavePrefs.prototype = {
this._checkAccountInfo();
},
doToggleShowPasswords: function WeavePrefs_doToggleShowPasswords(event) {
let passwordFields = ["oldPassword", "newPassword", "newPasswordAgain"].
map(function(v) document.getElementById(v));
for each (let field in passwordFields) {
if (event.target.checked)
field.removeAttribute("type");
else
field.setAttribute("type", "password");
}
},
/**
* Make sure the new password fields contain identical values.
*
* Note: we don't validate the passwords unless both of them have been
* entered. Otherwise it would be annoying to users who enter one and are
* told they don't match before they've had a chance to enter the other.
*
* Note: we also do this in doChangePassword before submitting the form,
* but there we display the error even if one of the values is empty, so
* we don't submit the form unless the data is valid.
*/
validateNewPasswords: function WeavePrefs_validateNewPasswords() {
let newPassword = document.getElementById("newPassword");
let newPasswordAgain = document.getElementById("newPasswordAgain");
// Don't annoy the user until they've entered something into both fields.
if (!newPassword.value || !newPasswordAgain.value)
return;
if (newPassword.value == Weave.Service.passphrase)
this._setChangePasswordStatus("error", ["passwordSameAsPassphrase"]);
else if (newPassword.value != newPasswordAgain.value)
this._setChangePasswordStatus("error", ["passwordsDoNotMatch"]);
else
this._setChangePasswordStatus("idle");
},
doChangePassword: function WeavePrefs_doChangePassword() {
let url = "https://services.mozilla.com/";
setTimeout(function() { window.openUILinkIn(url, "tab"); }, 500);
},
_setChangePasswordStatus:
function WeavePrefs__setChangePasswordStatus(status, errorCodes) {
let statusBox = document.getElementById("changePasswordStatus");
let description = document.getElementById("changePasswordDescription");
doChangePassphrase: function WeavePrefs_doChangePassphrase() {
let pph1 = document.getElementById('newPassphrase1');
let pph2 = document.getElementById('newPassphrase2');
// A list of fields in the form. We use this array to disable the fields
// while we're in the process of changing the password, so the user doesn't
// think they can make a change once the process is underway.
let fields = ["oldPassword", "newPassword", "newPasswordAgain",
"changePasswordButton"].
map(function(v) document.getElementById(v));
if (!pph1.value || !pph2.value) {
alert(this._stringBundle.getString("change.passphrase.noPassAlert"));
} else if (pph1.value != pph2.value) {
alert(this._stringBundle.getString("change.passphrase.noMatchAlert"));
} else {
document.getElementById('pphStatusIcon').setAttribute("status", "active");
let status = document.getElementById('pphStatus');
status.value = this._stringBundle.getString("change.passphrase.label");
status.style.color = "-moz-dialogtext";
// Set the status attribute to update the icon (which gets set via CSS).
statusBox.setAttribute("status", status);
if (status == "active") {
// Disable the form fields so the user doesn't think they can change
// them in the middle of the process.
for each (let field in fields)
field.disabled = true;
description.value =
this._stringBundle.getString("change.password.status.active");
let dialog = document.getElementById('changepph-dialog');
dialog.getButton("cancel").setAttribute("disabled", "true");
dialog.getButton("accept").setAttribute("disabled", "true");
Weave.Service.changePassphrase(pph1.value);
return true;
}
else {
// Reenable the form fields so the user can use the form (again).
for each (let field in fields)
field.disabled = false;
switch(status) {
case "success":
description.value =
this._stringBundle.getString("change.password.status.success");
break;
case "error":
let errorProperty;
// We only have space to show one error message, so we check the codes
// in order of importance and show the most important one.
if (errorCodes.indexOf("passwordSameAsPassphrase") != -1)
errorProperty = "change.password.status.passwordSameAsPassphrase";
else if (errorCodes.indexOf("passwordsDoNotMatch") != -1)
errorProperty = "change.password.status.passwordsDoNotMatch";
else if (errorCodes.indexOf("-12") != -1)
errorProperty = "change.password.status.badOldPassword";
else if (errorCodes.indexOf("-11") != -1)
errorProperty = "change.password.status.noNewPassword";
else if (errorCodes.indexOf("-8") != -1)
errorProperty = "change.password.status.noOldPassword";
else
errorProperty = "change.password.status.error";
description.value = this._stringBundle.getString(errorProperty);
break;
case "idle":
default:
description.value = description.getAttribute("idlevalue");
break;
}
}
},
onChangePassword: function WeavePrefs_onChangePassword(event) {
let request = event.target;
switch(request.status) {
case 200:
this._setChangePasswordStatus("success");
Weave.Service.password = document.getElementById("newPassword").value;
break;
default:
this._setChangePasswordStatus("error", request.responseText);
break;
}
return false;
},
doCreateAccount: function WeavePrefs_doCreateAccount() {
Weave.Utils.openWizard();
// let url = "https://services.mozilla.com/";
// setTimeout(function() { window.openUILinkIn(url, "tab"); }, 500);
},
resetLoginCredentials: function WeavePrefs_resetLoginCredentials() {

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

@ -7,3 +7,11 @@
<!ENTITY encryptionPassphrase.label "Encryption Passphrase:">
<!ENTITY savePassword.label "Save password on this computer">
<!ENTITY autoconnect.label "Automatically connect each time I start Firefox">
<!ENTITY forgotPhrase.label "Forgot your passphrase?">
<!ENTITY pph.title "Reset your Passphrase">
<!ENTITY pph.message "Please update all your clients with the new passphrase">
<!ENTITY pph.accept "Reset">
<!ENTITY pph.cancel "Cancel">
<!ENTITY pph.enter1 "Enter new passphrase">
<!ENTITY pph.enter2 "Confirm new passphrase">

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

@ -1,4 +1,5 @@
loginFailed.alert = Login failed
noUsername.alert = You must enter a username
noPassword.alert = You must enter a password
noPassphrase.alert = You must enter a passphrase
samePasswordAndPassphrase.alert = Your password and passphrase must be different
@ -6,3 +7,7 @@ loginStart.label = Signing in, please wait...
loginError.label = Invalid username and/or password.
loginSuccess.label = Signed In
hide.label = Hide
pphStart.label = Resetting passphrase, please wait...
pphError.label = There was an error while resetting your passphrase!
pphSuccess.label = Your passphrase was successfully reset!
pphNoMatch.alert = Your passphrases do not match. Try again!

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

@ -22,6 +22,7 @@
<!ENTITY newPasswordAgain.label "Re-enter:">
<!ENTITY showPasswords.label "Show Passwords">
<!ENTITY changePasswordButton.label "Change Password">
<!ENTITY changePassphraseButton.label "Change Passphrase">
<!ENTITY backUpCheckbox.label "Back up and securely synchronize my data to a Weave server">
<!ENTITY encryptOnServerCheckbox.label "Encrypt locally and only store encrypted data on server">
@ -111,3 +112,10 @@
<!ENTITY tabs.sortBy.title.label "Title">
<!ENTITY tabs.sortBy.source.label "Source">
<!ENTITY tabs.sortBy.label "Sort by: ">
<!ENTITY pph.accept "Change">
<!ENTITY pph.cancel "Cancel">
<!ENTITY pph.title "Change passphrase">
<!ENTITY pph.message "Please update all your clients with the new phrase">
<!ENTITY pph.enterNew1 "New passphrase:">
<!ENTITY pph.enterNew2 "Confirm new passphrase:">

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

@ -21,3 +21,9 @@ change.password.status.passwordsDoNotMatch = The passwords you entered do not ma
change.password.status.noOldPassword = You didn't enter your current password.
change.password.status.noNewPassword = You didn't enter a new password.
change.password.status.badOldPassword = Your current password is incorrect.
change.passphrase.label = Changing passphrase, please wait...
change.passphrase.error = There was an error while changing your passphrase!
change.passphrase.success = Your passphrase was successfully changed!
change.passphrase.noMatchAlert = Your passphrases do not match. Try again!
change.passphrase.noPassAlert = You must enter the new passphrase

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

@ -517,6 +517,35 @@ WeaveSvc.prototype = {
// fixme: decrypt something here
}))),
changePassphrase: function WeaveSvc_changePassphrase(newphrase)
this._catch(this._notify("changepph", "", function() {
throw "Unimplemented!";
}))(),
resetPassphrase: function WeaveSvc_resetPassphrase(newphrase)
this._catch(this._notify("resetpph", "", function() {
/* Make remote commands ready so we have a list of clients beforehand */
this.prepCommand("logout", []);
let clientsBackup = Clients._store.clients;
/* Wipe */
this.wipeServer();
/* Set remote commands before syncing */
Clients._store.clients = clientsBackup;
let username = this.username;
let password = this.password;
this.logout();
/* Set this so UI is updated on next run */
this.passphrase = newphrase;
/* Login in sync: this also generates new keys */
this.login(username, password, newphrase);
this.sync(true);
return true;
}))(),
login: function WeaveSvc_login(username, password, passphrase)
this._catch(this._lock(this._notify("login", "", function() {
this._loggedIn = false;
@ -1073,6 +1102,7 @@ WeaveSvc.prototype = {
["resetEngine", 1, "Clear temporary local data for engine"],
["wipeAll", 0, "Delete all client data for all engines"],
["wipeEngine", 1, "Delete all client data for engine"],
["logout", 0, "Log out client"],
].reduce(function WeaveSvc__commands(commands, entry) {
commands[entry[0]] = {};
for (let [i, attr] in Iterator(["args", "desc"]))
@ -1106,14 +1136,15 @@ WeaveSvc.prototype = {
case "resetEngine":
this.resetClient(engines);
break;
case "wipeAll":
engines = null;
// Fallthrough
case "wipeEngine":
this.wipeClient(engines);
break;
case "logout":
this.logout();
return false;
default:
this._log.debug("Received an unknown command: " + command);
break;