mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-17 10:58:20 -07:00
fixes #941 - Rework password recovery and remove IsLocal checks
This commit is contained in:
parent
0adfd30015
commit
7f6f74fb54
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
43
dashboard-ui/forgotpassword.html
Normal file
43
dashboard-ui/forgotpassword.html
Normal 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>
|
42
dashboard-ui/forgotpasswordpin.html
Normal file
42
dashboard-ui/forgotpasswordpin.html
Normal 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>
|
@ -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>
|
||||||
|
@ -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" />
|
||||||
|
74
dashboard-ui/scripts/forgotpassword.js
Normal file
74
dashboard-ui/scripts/forgotpassword.js
Normal 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);
|
63
dashboard-ui/scripts/forgotpasswordpin.js
Normal file
63
dashboard-ui/scripts/forgotpasswordpin.js
Normal 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);
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user