This commit is contained in:
lingdocs 2021-08-26 12:19:09 +04:00
parent 934e5c7b05
commit 7b954238b3
7 changed files with 44 additions and 12 deletions

View File

@ -104,7 +104,8 @@ export async function updateLingdocsUser(uuid: T.UUID, toUpdate:
requestedUpgradeToStudent: undefined,
} |
{ userTextOptionsRecord: T.UserTextOptionsRecord } |
{ requestedUpgradeToStudent: true }
{ upgradeToStudentRequest: "waiting" } |
{ upgradeToStudentRequest: "denied" }
): Promise<T.LingdocsUser> {
const user = await getLingdocsUser("userId", uuid);
if (!user) throw new Error("unable to update - user not found " + uuid);

View File

@ -71,6 +71,12 @@ export async function upgradeUser(userId: T.UUID): Promise<T.UpgradeUserResponse
};
}
export async function denyUserUpgradeRequest(userId: T.UUID): Promise<void> {
await updateLingdocsUser(userId, {
upgradeToStudentRequest: "denied",
});
}
export async function createNewUser(input: {
strategy: "local",
email: string,

View File

@ -148,7 +148,7 @@ apiRouter.post("/user/upgradeToStudentRequest", async (req, res, next) => {
return;
}
sendUpgradeRequestToAdmin(req.user).catch(console.error);
await updateLingdocsUser(req.user.userId, { requestedUpgradeToStudent: true });
await updateLingdocsUser(req.user.userId, { upgradeToStudentRequest: "waiting" });
res.send({ ok: true, message: "request for upgrade sent" });
} catch (e) {
next(e);

View File

@ -15,6 +15,7 @@ import {
} from "../lib/password-utils";
import {
upgradeUser,
denyUserUpgradeRequest,
} from "../lib/user-utils";
import { validateReCaptcha } from "../lib/recaptcha";
import {
@ -157,13 +158,21 @@ const authRouter = (passport: PassportStatic) => {
}
});
router.post("/admin/upgradeToStudent/:userId", async (req, res, next) => {
/**
* Grant request for upgrade to student
*/
router.post("/admin/upgradeToStudent/:userId/:grantOrDeny", async (req, res, next) => {
try {
if (!req.user || !req.user.admin) {
return res.redirect("/");
}
const userId = req.params.userId;
await upgradeUser(userId as T.UUID);
const userId = req.params.userId as T.UUID;
const grantOrDeny = req.params.grantOrDeny as "grant" | "deny";
if (grantOrDeny === "grant") {
await upgradeUser(userId);
} else {
await denyUserUpgradeRequest(userId);
}
res.redirect("/admin");
} catch (e) {
next(e);

View File

@ -60,10 +60,22 @@
<% } %>
</td>
<td>
<% if (users[i].requestedUpgradeToStudent) { %>
<form action="/admin/upgradeToStudent/<%= users[i].userId %>" method="POST">
<button class="btn btn-sm btn-primary" type="submit"><i class="fas fa-stamp mr-2"></i> Grant Upgrade Request</button>
</form>
<% if (users[i].upgradeToStudentRequest === "waiting") { %>
<div class="d-flex flex-row">
<div>Requested Upgrade </div>
<div>
<form action="/admin/upgradeToStudent/<%= users[i].userId %>/grand" method="POST">
<button class="btn btn-sm btn-success" type="submit"><i class="fas fa-thumbs-up mr-2"></i> Grant </button>
</form>
</div>
<div>
<form action="/admin/upgradeToStudent/<%= users[i].userId %>/deny" method="POST">
<button class="btn btn-sm btn-danger" type="submit"><i class="fas fa-thumbs-down mr-2"></i> Deny </button>
</form>
</div>
</div>
<% } else if (users[i].upgradeToStudentRequest === "waiting"){ %>
Upgrade Denied
<% } else { %>
<%= users[i].level %>
<% } %>

View File

@ -39,7 +39,7 @@ export type LingdocsUser = {
tokenHash: Hash,
requestedOn: TimeStamp,
},
requestedUpgradeToStudent?: boolean,
upgradeToStudentRequest?: "waiting" | "denied",
tests: [],
lastLogin: TimeStamp,
lastActive: TimeStamp,

View File

@ -155,10 +155,14 @@ const Account = ({ user, loadUser }: { user: AT.LingdocsUser | undefined, loadUs
</div>
</div>
</li>}
<li className="list-group-item">Account Level: {capitalize(user.level)} {user.requestedUpgradeToStudent ? "(Upgrade Requested)" : ""}</li>
<li className="list-group-item">Account Level: {capitalize(user.level)} {user.upgradeToStudentRequest === "waiting"
? "(Upgrade Requested)"
: user.upgradeToStudentRequest === "denied"
? "(Upgrade Denied)"
: ""}</li>
<li className="list-group-item">Signs in with:
{(user.password && user.email) && <span>
<i className="fas fa-key ml-2"></i> <span className="small">Password</span>
<i className="fas fa-key ml-3"></i> <span className="small">Password</span>
</span>}
{providers.map((provider) => (
user[provider] && <span>