more functional auth admin panel

This commit is contained in:
lingdocs 2021-08-25 16:20:41 +04:00
parent e2a89f0798
commit 6caa20a2f9
3 changed files with 65 additions and 10 deletions

View File

@ -55,21 +55,20 @@ export async function upgradeUser(userId: T.UUID): Promise<T.UpgradeUserResponse
const { password, userDbName } = await addCouchDbAuthUser(userId); const { password, userDbName } = await addCouchDbAuthUser(userId);
// // create user db // // create user db
// update LingdocsUser // update LingdocsUser
const u = await updateLingdocsUser(userId, { const user = await updateLingdocsUser(userId, {
level: "student", level: "student",
wordlistDbName: userDbName, wordlistDbName: userDbName,
couchDbPassword: password, couchDbPassword: password,
requestedUpgradeToStudent: undefined, requestedUpgradeToStudent: undefined,
}); });
if (u.email) { if (user.email) {
sendAccountUpgradeMessage(u).catch(console.error); sendAccountUpgradeMessage(user).catch(console.error);
} }
const upgraded: T.UpgradeUserResponse = { return {
ok: true, ok: true,
message: "user upgraded to student", message: "user upgraded to student",
user: u, user,
}; };
return upgraded;
} }
export async function createNewUser(input: { export async function createNewUser(input: {

View File

@ -1,6 +1,7 @@
import { Router } from "express"; import { Router } from "express";
import { PassportStatic } from "passport"; import { PassportStatic } from "passport";
import { import {
deleteLingdocsUser,
getAllLingdocsUsers, getAllLingdocsUsers,
getLingdocsUser, getLingdocsUser,
updateLingdocsUser, updateLingdocsUser,
@ -158,7 +159,7 @@ const authRouter = (passport: PassportStatic) => {
router.post("/admin/upgradeToStudent/:userId", async (req, res, next) => { router.post("/admin/upgradeToStudent/:userId", async (req, res, next) => {
try { try {
if (!req.user.admin) { if (!req.user || !req.user.admin) {
return res.redirect("/"); return res.redirect("/");
} }
const userId = req.params.userId; const userId = req.params.userId;
@ -169,6 +170,20 @@ const authRouter = (passport: PassportStatic) => {
} }
}); });
router.delete("/admin/:userId", async (req, res, next) => {
try {
// TODO: MAKE PROPER MIDDLEWARE WITH TYPING
if (!req.user || !req.user.admin) {
return res.redirect("/");
}
const toDelete = req.params.userId as T.UUID;
await deleteLingdocsUser(toDelete);
res.send({ ok: true, message: "user deleted" });
} catch (e) {
next(e);
}
});
router.get("/email-verification/:uuid/:token", async (req, res, next) => { router.get("/email-verification/:uuid/:token", async (req, res, next) => {
const page = "email-verification"; const page = "email-verification";
const { uuid, token } = req.params; const { uuid, token } = req.params;

View File

@ -8,6 +8,21 @@
<link href="/css/bootstrap.min.css" rel="stylesheet"> <link href="/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
</head> </head>
<script>
function handleDeleteUser(uid, name) {
const answer = confirm(`Are you sure you want to delete ${name}?`);
if (answer) {
fetch(`/admin/${uid}`, {
method: "DELETE",
}).then((res) => res.json()).then((res) => {
console.log(res);
if (res.ok) {
window.location = "/admin";
}
}).catch(console.error);
}
}
</script>
<body> <body>
<div class="container"> <div class="container">
<h1 class="my-4">LingDocs Auth Admin</h1> <h1 class="my-4">LingDocs Auth Admin</h1>
@ -16,23 +31,49 @@
<tr> <tr>
<th scope="col">Name</th> <th scope="col">Name</th>
<th scope="col">Email</th> <th scope="col">Email</th>
<th scope="col">Providers</th>
<th scope="col">Level</th> <th scope="col">Level</th>
<th scope="col">Last Active</th>
<th shope="col"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% for(var i=0; i < users.length; i++) { %> <% for(var i=0; i < users.length; i++) { %>
<tr> <tr>
<td><%= users[i].name %></td> <td><%= users[i].name %> <% if (users[i].admin) { %>
<i class="fas fa-id-badge ml-2"></i>
<% } %>
</td>
<td><%= users[i].email %></td> <td><%= users[i].email %></td>
<td>
<% if (users[i].password && users[i].email) { %>
<i class="fas fa-key mr-2"></i>
<% } %>
<% if (users[i].google) { %>
<i class="fab fa-google mr-2"></i>
<% } %>
<% if (users[i].twitter) { %>
<i class="fab fa-twitter mr-2"></i>
<% } %>
<% if (users[i].github) { %>
<i class="fab fa-github mr-2"></i>
<% } %>
</td>
<td> <td>
<% if (users[i].requestedUpgradeToStudent) { %> <% if (users[i].requestedUpgradeToStudent) { %>
Requested Upgrade - <form action="/admin/upgradeToStudent/<%= users[i].userId %>" method="post"> <form action="/admin/upgradeToStudent/<%= users[i].userId %>" method="POST">
<button class="btn btn-sm btn-primary" type="submit">Grant</button> <button class="btn btn-sm btn-primary" type="submit"><i class="fas fa-stamp mr-2"></i> Grant Upgrade Request</button>
</form> </form>
<% } else { %> <% } else { %>
<%= users[i].level %> <%= users[i].level %>
<% } %> <% } %>
</td> </td>
<td>
<%= new Date(users[i].lastActive).toUTCString() %>
</td>
<td>
<button class="btn btn-sm btn-danger" onClick="handleDeleteUser('<%= users[i].userId %>', '<%= users[i].name %>')"><i class="fa fa-trash"></i></button>
</td>
</tr> </tr>
<% } %> <% } %>
</tbody> </tbody>