fixes #941 - Rework password recovery and remove IsLocal checks

This commit is contained in:
Luke Pulverenti 2014-11-08 22:18:14 -05:00
parent 0adfd30015
commit 7f6f74fb54
11 changed files with 263 additions and 40 deletions

View File

@ -169,6 +169,7 @@
overflow-x: scroll; overflow-x: scroll;
-ms-overflow-style: none; -ms-overflow-style: none;
overflow: -moz-scrollbars-none; overflow: -moz-scrollbars-none;
-webkit-overflow-scrolling: touch;
} }
.viewMenuBar { .viewMenuBar {

View File

@ -115,6 +115,32 @@ h1 a:hover {
font-weight: 400; font-weight: 400;
} }
/*
Make all panels vertically scrollable
If this causes any problems then perhaps require a css class to activate
*/
.ui-panel.ui-panel-open {
position: fixed;
}
.ui-panel-inner {
position: absolute;
top: 1px;
left: 0;
bottom: 0;
right: 0;
overflow: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
}
.ui-panel-inner::-webkit-scrollbar {
width: 0 !important;
display: none;
}
pre, textarea.pre { pre, textarea.pre {
display: block; display: block;
padding: 8.5px; padding: 8.5px;

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<title>${TitleForgotPassword}</title>
</head>
<body>
<div data-role="page" class="page standalonePage forgotPasswordPage">
<div data-role="content">
<form class="forgotPasswordForm" style="text-align: center; margin: 0 auto;">
<div style="text-align: left;">
<h2>${HeaderForgotPassword}</h2>
<label for="txtName" style="text-align: left;">${LabelUser}</label>
<input type="text" id="txtName" />
<div class="fieldDescription">${LabelForgotPasswordUsernameHelp}</div>
<br />
<p>
<button type="submit" data-icon="check" data-theme="b">
${ButtonSubmit}
</button>
</p>
<p>
<a data-role="button" data-icon="delete" href="login.html">
${ButtonCancel}
</a>
</p>
</div>
</form>
</div>
<script type="text/javascript">
$('.forgotPasswordForm').off('submit', ForgotPasswordPage.onSubmit).on('submit', ForgotPasswordPage.onSubmit);
</script>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<title>${TitlePasswordReset}</title>
</head>
<body>
<div data-role="page" class="page standalonePage forgotPasswordPage">
<div data-role="content">
<form class="forgotPasswordPinForm" style="text-align: center; margin: 0 auto;">
<div style="text-align: left;">
<h2>${HeaderPasswordReset}</h2>
<label for="txtPin" style="text-align: left;">${LabelPasswordRecoveryPinCode}</label>
<input type="text" id="txtPin" required="required" />
<br />
<p>
<button type="submit" data-icon="check" data-theme="b">
${ButtonSubmit}
</button>
</p>
<p>
<a data-role="button" data-icon="delete" href="login.html">
${ButtonCancel}
</a>
</p>
</div>
</form>
</div>
<script type="text/javascript">
$('.forgotPasswordPinForm').off('submit', ForgotPasswordPinPage.onSubmit).on('submit', ForgotPasswordPinPage.onSubmit);
</script>
</div>
</body>
</html>

View File

@ -27,13 +27,19 @@
${ButtonCancel} ${ButtonCancel}
</button> </button>
</p> </p>
<br />
<p>
<a href="forgotpassword.html">
${ButtonForgotPassword}
</a>
</p>
</form> </form>
<div class="visualLoginForm" style="display: none; text-align: center;"> <div class="visualLoginForm" style="display: none; text-align: center;">
<div id="divUsers" class="itemsContainer"></div> <div id="divUsers" class="itemsContainer"></div>
<p class="localhostMessage" style="text-align: center; display: none;">${PasswordLocalhostMessage}</p> <p class="localhostMessage" style="text-align: center; display: none;">${PasswordLocalhostMessage}</p>
<p><a href="#" class="lnkManualLogin" onclick="LoginPage.showManualForm($.mobile.activePage, true);">${ButtonManualLogin}</a></p> <p><a href="#" class="lnkManualLogin" onclick="LoginPage.showManualForm($.mobile.activePage, true);">${ButtonManualLogin}</a></p>
</div> </div>

View File

@ -104,11 +104,11 @@
<input type="checkbox" id="chkChaptersOtherVideos" /> <input type="checkbox" id="chkChaptersOtherVideos" />
<label for="chkChaptersOtherVideos">${OptionOtherVideos}</label> <label for="chkChaptersOtherVideos">${OptionOtherVideos}</label>
<div class="fieldDescription">${ExtractChapterImagesHelp}</div>
</div> </div>
<div class="fieldDescription">${ExtractChapterImagesHelp}</div>
</li> </li>
</ul> </ul>
<br/>
<div> <div>
<label for="chkExtractChaptersDuringLibraryScan">${LabelExtractChaptersDuringLibraryScan}</label> <label for="chkExtractChaptersDuringLibraryScan">${LabelExtractChaptersDuringLibraryScan}</label>
<input type="checkbox" id="chkExtractChaptersDuringLibraryScan" /> <input type="checkbox" id="chkExtractChaptersDuringLibraryScan" />

View File

@ -0,0 +1,74 @@
(function (window) {
function processForgotPasswordResult(page, result) {
if (result.Action == 'ContactAdmin') {
Dashboard.alert({
message: Globalize.translate('MessageContactAdminToResetPassword'),
title: Globalize.translate('HeaderForgotPassword')
});
return;
}
if (result.Action == 'InNetworkRequired') {
Dashboard.alert({
message: Globalize.translate('MessageForgotPasswordInNetworkRequired'),
title: Globalize.translate('HeaderForgotPassword')
});
return;
}
if (result.Action == 'PinCode') {
var msg = Globalize.translate('MessageForgotPasswordFileCreated');
msg += "<br/>";
msg += "<br/>";
msg += result.PinFile;
msg += "<br/>";
msg += "<br/>";
msg += Globalize.translate('MessageForgotPasswordFileExpiration', parseISO8601Date(result.PinExpirationDate, { toLocal: true }).toLocaleString());
Dashboard.alert({
message: msg,
title: Globalize.translate('HeaderForgotPassword')
});
return;
}
}
function onSubmit(page) {
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('Users/ForgotPassword'),
dataType: 'json',
data: {
EnteredUsername: $('#txtName', page).val()
}
}).done(function (result) {
processForgotPasswordResult(page, result);
});
}
window.ForgotPasswordPage = {
onSubmit: function () {
var page = $(this).parents('.page');
onSubmit(page);
return false;
}
};
})(window);

View File

@ -0,0 +1,63 @@
(function (window) {
function processForgotPasswordResult(page, result) {
if (result.Success) {
var msg = Globalize.translate('MessagePasswordResetForUsers');
msg += '<br/>';
msg += '<br/>';
msg += result.UsersReset.join('<br/>');
Dashboard.alert({
message: msg,
title: Globalize.translate('HeaderPasswordReset'),
callback: function () {
window.location = 'login.html';
}
});
return;
}
Dashboard.alert({
message: Globalize.translate('MessageInvalidForgotPasswordPin'),
title: Globalize.translate('HeaderPasswordReset')
});
return;
}
function onSubmit(page) {
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('Users/ForgotPassword/Pin'),
dataType: 'json',
data: {
Pin: $('#txtPin', page).val()
}
}).done(function (result) {
processForgotPasswordResult(page, result);
});
}
window.ForgotPasswordPinPage = {
onSubmit: function () {
var page = $(this).parents('.page');
onSubmit(page);
return false;
}
};
})(window);

View File

@ -6,12 +6,6 @@
var page = this; var page = this;
if (LoginPage.isLocalhost()) {
$('.localhostMessage', page).show();
} else {
$('.localhostMessage', page).hide();
}
// Show all users on localhost // Show all users on localhost
var promise1 = ApiClient.getPublicUsers(); var promise1 = ApiClient.getPublicUsers();
@ -37,13 +31,7 @@
}); });
}, },
isLocalhost: function () { cancelLogin: function () {
var location = getWindowUrl().toString().toLowerCase();
return location.indexOf('localhost') != -1 || location.indexOf('127.0.0.1') != -1;
},
cancelLogin: function() {
LoginPage.showVisualForm($.mobile.activePage); LoginPage.showVisualForm($.mobile.activePage);
}, },
@ -52,7 +40,7 @@
$('.visualLoginForm', page).hide(); $('.visualLoginForm', page).hide();
$('#manualLoginForm', page).show(); $('#manualLoginForm', page).show();
$('#txtManualName', page).focus(); $('#txtManualName', page).focus();
if (showCancel) { if (showCancel) {
$('.btnCancel', page).show(); $('.btnCancel', page).show();
} else { } else {
@ -137,7 +125,7 @@
if (user.PrimaryImageTag) { if (user.PrimaryImageTag) {
imgUrl = ApiClient.getUserImageUrl(user.Id, { imgUrl = ApiClient.getUserImageUrl(user.Id, {
width: 300, width: 300,
tag: user.PrimaryImageTag, tag: user.PrimaryImageTag,
type: "Primary" type: "Primary"
@ -182,7 +170,7 @@
var name = this.getAttribute('data-username'); var name = this.getAttribute('data-username');
var haspw = this.getAttribute('data-haspw'); var haspw = this.getAttribute('data-haspw');
if (LoginPage.isLocalhost() || haspw == 'false') { if (haspw == 'false') {
LoginPage.authenticateUserByName(name, ''); LoginPage.authenticateUserByName(name, '');
} else { } else {
$('#txtManualName', page).val(name); $('#txtManualName', page).val(name);

View File

@ -1242,9 +1242,6 @@ var Dashboard = {
.on("websocketmessage.dashboard", Dashboard.onWebSocketMessageReceived) .on("websocketmessage.dashboard", Dashboard.onWebSocketMessageReceived)
.on('requestfail.dashboard', Dashboard.onRequestFail) .on('requestfail.dashboard', Dashboard.onRequestFail)
.on('serveraddresschanged.dashboard', Dashboard.onApiClientServerAddressChanged); .on('serveraddresschanged.dashboard', Dashboard.onApiClientServerAddressChanged);
// TODO: Improve with http://webpjs.appspot.com/
apiClient.supportsWebP($.browser.chrome);
} }
var appName = "Dashboard"; var appName = "Dashboard";
@ -1447,7 +1444,7 @@ $(document).on('pagebeforeshow', ".page", function () {
else { else {
if (this.id !== "loginPage" && !page.hasClass('wizardPage') && !isConnectMode) { if (this.id !== "loginPage" && !page.hasClass('forgotPasswordPage') && !page.hasClass('wizardPage') && !isConnectMode) {
console.log('Not logged into server. Redirecting to login.'); console.log('Not logged into server. Redirecting to login.');
Dashboard.logout(); Dashboard.logout();

View File

@ -2285,15 +2285,6 @@
}); });
}; };
var supportsWebP = false;
self.supportsWebP = function (val) {
if (val != null) {
supportsWebP = val;
}
return supportsWebP;
};
function normalizeImageOptions(options) { function normalizeImageOptions(options) {
var ratio = devicePixelRatio || 1; var ratio = devicePixelRatio || 1;
@ -2319,10 +2310,6 @@
} }
options.quality = options.quality || (options.type.toLowerCase() == 'backdrop' ? 80 : 90); options.quality = options.quality || (options.type.toLowerCase() == 'backdrop' ? 80 : 90);
if (self.supportsWebP()) {
options.format = 'webp';
}
} }
/** /**
@ -2396,10 +2383,6 @@
delete options.type; delete options.type;
delete options.index; delete options.index;
if (self.supportsWebP()) {
options.format = 'webp';
}
return self.getUrl(url, options); return self.getUrl(url, options);
}; };