Implemented user profile settings, OAuth apps, and maintenance windows. Other minor fixes/improvements

This commit is contained in:
2021-03-11 10:37:07 -05:00
parent a020009c47
commit c58e2fc545
48 changed files with 3152 additions and 36 deletions

View File

@ -35,7 +35,7 @@ along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
</tr>
<tr>
<td>Username</td>
<td>Email</td>
<td>Last Login</td>
<td>Restricted</td>
<td>Options</td>
</tr>

View File

@ -15,7 +15,7 @@
* along with Linode Manager Classic. If not, see <https://www.gnu.org/licenses/>.
*/
import { settings, elements, apiGet, md5, parseParams, setupHeader } from "/global.js";
import { settings, elements, apiGet, md5, parseParams, setupHeader, timeString } from "/global.js";
(function()
{
@ -30,6 +30,7 @@ import { settings, elements, apiGet, md5, parseParams, setupHeader } from "/glob
// Data received from API calls
var data = {};
data.logins = [];
data.users = [];
// Static references to UI elements
@ -37,6 +38,11 @@ import { settings, elements, apiGet, md5, parseParams, setupHeader } from "/glob
ui.loading = {};
ui.userTable = {};
// Temporary state
var state = {};
state.haveLogins = false;
state.haveUsers = false;
// Generates a user table row
var createUserRow = function(user, alt)
{
@ -51,7 +57,7 @@ import { settings, elements, apiGet, md5, parseParams, setupHeader } from "/glob
imgLink.href = "/user/edit?user=" + user.username;
var img = document.createElement("img");
img.className = elements.profileImg;
img.src = "https://www.gravatar.com/avatar/" + md5(user.email);
img.src = "https://www.gravatar.com/avatar/" + md5(user.email, false);
img.alt = user.username;
imgLink.appendChild(img);
var separator = document.createElement("span");
@ -64,9 +70,29 @@ import { settings, elements, apiGet, md5, parseParams, setupHeader } from "/glob
nameCell.appendChild(nameLink);
row.appendChild(nameCell);
var email = document.createElement("td");
email.innerHTML = user.email;
row.appendChild(email);
var lastLogin = document.createElement("td");
var loginDate = null;
for (var i = data.logins.length - 1; i >= 0; i--) {
if (data.logins[i].username == user.username) {
loginDate = new Date(data.logins[i].datetime + "Z");
break;
}
}
if (loginDate) {
var now = new Date();
var ago = document.createElement("span");
ago.innerHTML = timeString(now - loginDate, true);
lastLogin.appendChild(ago);
var br = document.createElement("br");
lastLogin.appendChild(br);
var dateString = document.createElement("span");
dateString.className = elements.info;
dateString.innerHTML = loginDate.toLocaleString();
lastLogin.appendChild(dateString);
} else {
lastLogin.innerHTML = "Never";
}
row.appendChild(lastLogin);
var restricted = document.createElement("td");
if (user.restricted) {
@ -102,6 +128,27 @@ import { settings, elements, apiGet, md5, parseParams, setupHeader } from "/glob
return row;
};
// Callback for logins API call
var displayLogins = function(response)
{
data.logins = data.logins.concat(response.data);
// Request the next page if there are more
if (response.page != response.pages) {
apiGet("/account/logins?page=" + (response.page + 1), displayLogins, null);
return;
}
state.haveLogins = true;
if (state.haveUsers) {
ui.loading.remove();
// Add users to table
for (var i = 0; i < data.users.length; i++)
ui.userTable.appendChild(createUserRow(data.users[i], ui.userTable.children.length % 2));
}
};
// Callback for users API call
var displayUsers = function(response)
{
@ -113,11 +160,14 @@ import { settings, elements, apiGet, md5, parseParams, setupHeader } from "/glob
return;
}
ui.loading.remove();
state.haveUsers = true;
if (state.haveLogins) {
ui.loading.remove();
// Add users to table
for (var i = 0; i < data.users.length; i++)
ui.userTable.appendChild(createUserRow(data.users[i], ui.userTable.children.length % 2));
// Add users to table
for (var i = 0; i < data.users.length; i++)
ui.userTable.appendChild(createUserRow(data.users[i], ui.userTable.children.length % 2));
}
};
// Initial setup
@ -141,6 +191,7 @@ import { settings, elements, apiGet, md5, parseParams, setupHeader } from "/glob
// Get data from API
apiGet("/account/users", displayUsers, null);
apiGet("/account/logins", displayLogins, null);
};
// Attach onload handler