mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-26 13:20:41 +03:00
http fixs, added ip ban to api, and admin panel
This commit is contained in:
parent
e01ef642c3
commit
ab1f062d9d
17 changed files with 144 additions and 93 deletions
17
APIDOCS.md
17
APIDOCS.md
|
@ -16,25 +16,30 @@ But in front end, the API will works with session.
|
||||||
## How to request?
|
## How to request?
|
||||||
|
|
||||||
### Request types:
|
### Request types:
|
||||||
|
- GET `/api/bans/` fetch all bans.
|
||||||
|
- GET `/api/bans/:id` fetch a ban.
|
||||||
|
- POST `/api/bans/:id?reason=flood` for ban an IP adress.
|
||||||
|
- DELETE `/api/bans/:id` for unban an IP adress.
|
||||||
|
|
||||||
- GET `/api/users/:id` for fetch user.
|
- GET `/api/users/:id` for fetch user.
|
||||||
- POST `/api/users/:id/delete` for delete user.
|
- DELETE `/api/users/:id/` for delete user.
|
||||||
- POST `/api/users/:id/undelete` for undelete user.
|
- POST `/api/users/:id/undelete` for undelete user.
|
||||||
- POST `/api/users/:id/admin` for give admin permissions for a user.
|
- POST `/api/users/:id/admin` for give admin permissions for a user.
|
||||||
- POST `/api/users/:id/edit` for edit user.
|
- PATCH `/api/users/:id/` for edit user.
|
||||||
|
|
||||||
- GET `/api/threads/:id` for fetch thread.
|
- GET `/api/threads/:id` for fetch thread.
|
||||||
- GET `/api/threads/:id/messages/` for fetch messages in thread.
|
- GET `/api/threads/:id/messages/` for fetch messages in thread.
|
||||||
- POST `/api/threads` for create thread.
|
- POST `/api/threads` for create thread.
|
||||||
- POST `/api/threads/:id/delete` for delete thread.
|
- DELETE `/api/threads/:id/` for delete thread.
|
||||||
- POST `/api/threads/:id/undelete` for undelete thread.
|
- POST `/api/threads/:id/undelete` for undelete thread.
|
||||||
- POST `/api/threads/:id/edit` for edit thread.
|
- PATCH `/api/threads/:id/` for edit thread.
|
||||||
|
|
||||||
- GET `/api/messages/:id` for fetch message.
|
- GET `/api/messages/:id` for fetch message.
|
||||||
- POST `/api/messages` for create message.
|
- POST `/api/messages` for create message.
|
||||||
- POST `/api/messages/:id/delete` for delete message.
|
- DELETE `/api/messages/:id/` for delete message.
|
||||||
- POST `/api/messages/:id/undelete` for undelete message.
|
- POST `/api/messages/:id/undelete` for undelete message.
|
||||||
- POST `/api/messages/:id/react/:type` for react to a message.
|
- POST `/api/messages/:id/react/:type` for react to a message.
|
||||||
- POST `/api/messages/:id/edit` for edit message.
|
- PATCH `/api/messages/:id/` for edit message.
|
||||||
|
|
||||||
### Example request:
|
### Example request:
|
||||||
GET ```/api/messages/0```
|
GET ```/api/messages/0```
|
||||||
|
|
|
@ -37,6 +37,7 @@ Akf-forum has got an API for AJAX, other clients etc. And, you can learn about A
|
||||||
- API, ?fast=
|
- API, ?fast=
|
||||||
- extra ratelimits
|
- extra ratelimits
|
||||||
- better edits
|
- better edits
|
||||||
|
- IP BAN CLI IN ADMIN PANEL
|
||||||
|
|
||||||
### Frontend
|
### Frontend
|
||||||
#### User
|
#### User
|
||||||
|
|
2
index.js
2
index.js
|
@ -34,8 +34,6 @@ app.use(session({ secret: 'secret', resave: true, saveUninitialized: true }),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (const file of fs.readdirSync("./routes"))
|
for (const file of fs.readdirSync("./routes"))
|
||||||
app.use("/" + file.replace(".js", ""), require(`./routes/${file}`));
|
app.use("/" + file.replace(".js", ""), require(`./routes/${file}`));
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
const mongoose = require("mongoose")
|
const mongoose = require("mongoose")
|
||||||
|
|
||||||
const schema = new mongoose.Schema({
|
const schema = new mongoose.Schema({
|
||||||
ip: { type: String, unique: true }
|
ip: { type: String, unique: true },
|
||||||
|
reason: { type: String, default: "No reason given" },
|
||||||
|
authorID: { type: String }
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = mongoose.model('ban', schema);
|
module.exports = mongoose.model('ban', schema);
|
|
@ -2,24 +2,30 @@ import request from "./request.js";
|
||||||
|
|
||||||
window.edit_t = async function (id) {
|
window.edit_t = async function (id) {
|
||||||
const title = prompt("Enter new title!");
|
const title = prompt("Enter new title!");
|
||||||
const res = await request(`/api/threads/${id}/edit`, "POST", { title });
|
const res = await request(`/api/threads/${id}/edit`, "PATCH", { title });
|
||||||
if (res.error) return;
|
if (res.error) return;
|
||||||
alert(`Thread updated`);
|
alert(`Thread updated`);
|
||||||
document.getElementById("title").innerHTML = title;
|
document.getElementById("title").innerHTML = title;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
window.delete_thread = async function (id) {
|
||||||
|
const res = await request(`/api/threads/${id}/`, "DELETE");
|
||||||
window.thread = async function (id, un = "") {
|
|
||||||
const res = await request(`/api/threads/${id}/${un}delete`);
|
|
||||||
if (res.error) return;
|
if (res.error) return;
|
||||||
|
|
||||||
alert(`Thread ${un}deleted`);
|
alert(`Thread deleted`);
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.undelete_thread = async function (id) {
|
||||||
|
const res = await request(`/api/threads/${id}/undelete`);
|
||||||
|
if (res.error) return;
|
||||||
|
|
||||||
|
alert(`Thread undeleted`);
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
window.edit_message = async function (id) {
|
window.edit_message = async function (id) {
|
||||||
const content = prompt("Enter new content!");
|
const content = prompt("Enter new content!");
|
||||||
const res = await request(`/api/messages/${id}/edit`, "POST", { content });
|
const res = await request(`/api/messages/${id}/`, "PATCH", { content });
|
||||||
if (res.error) return;
|
if (res.error) return;
|
||||||
|
|
||||||
alert(`Message updated`);
|
alert(`Message updated`);
|
||||||
|
@ -36,7 +42,7 @@ window.undelete_message = async function (id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
window.delete_message = async function (id) {
|
window.delete_message = async function (id) {
|
||||||
const response = await request(`/api/messages/${id}/delete`);
|
const response = await request(`/api/messages/${id}/`,"DELETE");
|
||||||
if (response.deleted) {
|
if (response.deleted) {
|
||||||
alert("Message deleted");
|
alert("Message deleted");
|
||||||
document.getElementById("dots-" + id).innerHTML = `
|
document.getElementById("dots-" + id).innerHTML = `
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
const { Router } = require("express")
|
const { Router } = require("express")
|
||||||
|
const { BanModel } = require("../models");
|
||||||
const app = Router();
|
const app = Router();
|
||||||
|
|
||||||
app.get("/", async (req, res) => {
|
app.get("/", async (req, res) => {
|
||||||
if (!req.user?.admin) return res.error(403, "You have not got permissions for view to this page.");
|
if (!req.user?.admin) return res.error(403, "You have not got permissions for view to this page.");
|
||||||
res.reply("admin")
|
res.reply("admin",{bans: await BanModel.find({})});
|
||||||
});
|
});
|
||||||
module.exports = app;
|
module.exports = app;
|
|
@ -1,5 +1,6 @@
|
||||||
const { Router, request, response } = require("express")
|
const { Router, request, response } = require("express")
|
||||||
const app = Router();
|
const app = Router();
|
||||||
|
const fs =require("fs")
|
||||||
const bcrypt = require("bcrypt");
|
const bcrypt = require("bcrypt");
|
||||||
const { SecretModel, UserModel } = require("../../models")
|
const { SecretModel, UserModel } = require("../../models")
|
||||||
|
|
||||||
|
@ -32,10 +33,8 @@ app.use(async (req, res, next) => {
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* will add for loop */
|
for (const file of fs.readdirSync("./routes/api/routes"))
|
||||||
app.use("/messages", require("./routes/messages"))
|
app.use("/" + file.replace(".js", ""), require(`./routes/${file}`));
|
||||||
app.use("/users", require("./routes/users"))
|
|
||||||
app.use("/threads", require("./routes/threads"))
|
|
||||||
|
|
||||||
app.all("*", (req, res) => res.error(400, "Bad request"));
|
app.all("*", (req, res) => res.error(400, "Bad request"));
|
||||||
|
|
||||||
|
|
35
routes/api/routes/bans.js
Normal file
35
routes/api/routes/bans.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
const { BanModel } = require("../../../models");
|
||||||
|
const { Router } = require("express")
|
||||||
|
|
||||||
|
const app = Router();
|
||||||
|
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
if (!req.user || !req.user.admin) return res.error(403, "You have not got permission for this.");
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/", async (req, res) => {
|
||||||
|
const bans = await BanModel.find({});
|
||||||
|
res.complate(bans);
|
||||||
|
});
|
||||||
|
app.get("/:ip", async (req, res) => {
|
||||||
|
const ban = await BanModel.findOne({ ip: req.params.ip });
|
||||||
|
if (!ban) return res.error(400, "This ip is not banned.");
|
||||||
|
res.complate(ban);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/:ip", async (req, res) => {
|
||||||
|
|
||||||
|
if (await BanModel.exists({ ip: req.params.ip })) return res.error(400, "This ip is already banned.");
|
||||||
|
res.complate(await BanModel.create({ ip: req.params.ip, reason: req.query.reason || "No reason given", authorID: req.user.id }));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete("/:ip/", async (req, res) => {
|
||||||
|
|
||||||
|
if (!await BanModel.exists({ ip: req.params.ip })) return res.error(400, "This ip is already not banned.");
|
||||||
|
res.complate(await BanModel.deleteOne({ ip: req.params.ip }));
|
||||||
|
|
||||||
|
});
|
||||||
|
module.exports = app;
|
|
@ -15,7 +15,7 @@ app.get("/:id", async (req, res) => {
|
||||||
res.complate(message.toObject({ virtuals: true }));
|
res.complate(message.toObject({ virtuals: true }));
|
||||||
|
|
||||||
})
|
})
|
||||||
app.post("/:id/edit", async (req, res) => {
|
app.patch("/:id/", async (req, res) => {
|
||||||
|
|
||||||
const message = await MessageModel.get(req.params.id);
|
const message = await MessageModel.get(req.params.id);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ app.post("/:id/react/:type", async (req, res) => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/:id/delete", async (req, res) => {
|
app.delete("/:id/", async (req, res) => {
|
||||||
const message = await MessageModel.get(req.params.id);
|
const message = await MessageModel.get(req.params.id);
|
||||||
if (!message || (message.deleted && req.user && !req.user.admin))
|
if (!message || (message.deleted && req.user && !req.user.admin))
|
||||||
return res.error(404, `We don't have any message with id ${req.params.id}.`);
|
return res.error(404, `We don't have any message with id ${req.params.id}.`);
|
||||||
|
|
|
@ -53,7 +53,7 @@ app.post("/", async (req, res) => {
|
||||||
res.complate(thread.toObject({ virtuals: true }));
|
res.complate(thread.toObject({ virtuals: true }));
|
||||||
|
|
||||||
});
|
});
|
||||||
app.post("/:id/edit", async (req, res) => {
|
app.patch("/:id/", async (req, res) => {
|
||||||
|
|
||||||
const thread = await ThreadModel.get(req.params.id);
|
const thread = await ThreadModel.get(req.params.id);
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ app.post("/:id/edit", async (req, res) => {
|
||||||
res.complate(thread.toObject({ virtuals: true }));
|
res.complate(thread.toObject({ virtuals: true }));
|
||||||
|
|
||||||
})
|
})
|
||||||
app.post("/:id/delete", async (req, res) => {
|
app.delete("/:id/", async (req, res) => {
|
||||||
const thread = await ThreadModel.get(req.params.id);
|
const thread = await ThreadModel.get(req.params.id);
|
||||||
if (!thread || thread.deleted) return res.error(404, `We don't have any thread with id ${req.params.id}.`);
|
if (!thread || thread.deleted) return res.error(404, `We don't have any thread with id ${req.params.id}.`);
|
||||||
const user = req.user;
|
const user = req.user;
|
||||||
|
|
|
@ -14,7 +14,7 @@ app.get("/:id", async (req, res) => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/:id/delete/", async (req, res) => {
|
app.delete("/:id/", async (req, res) => {
|
||||||
const user = req.user;
|
const user = req.user;
|
||||||
if (!user.admin)
|
if (!user.admin)
|
||||||
return res.error(403, "You have not got permission for this.");
|
return res.error(403, "You have not got permission for this.");
|
||||||
|
@ -46,7 +46,7 @@ app.post("/:id/undelete/", async (req, res) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
app.post("/:id/edit", async (req, res) => {
|
app.patch("/:id/", async (req, res) => {
|
||||||
|
|
||||||
const member = await UserModel.get(req.params.id);
|
const member = await UserModel.get(req.params.id);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ app.get("/", async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
app.get("/create*", (req, res) => res.reply("create_thread"));
|
app.get("/create/", (req, res) => res.reply("create_thread"));
|
||||||
|
|
||||||
app.get("/:id/", async (req, res) => {
|
app.get("/:id/", async (req, res) => {
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,7 @@ mongoose.connect(process.env.MONGO_DB_URL, () => console.log("Database is connec
|
||||||
const { UserModel } = require("../models");
|
const { UserModel } = require("../models");
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
||||||
const member= await UserModel.get(0);
|
const member= await UserModel.get("0");
|
||||||
member.admin = true;
|
member.admin = true;
|
||||||
console.log(await member.save());
|
console.log(await member.save());
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,6 @@ require("dotenv").config();
|
||||||
|
|
||||||
mongoose.connect(process.env.MONGO_DB_URL, () => console.log("Database is connected"));
|
mongoose.connect(process.env.MONGO_DB_URL, () => console.log("Database is connected"));
|
||||||
|
|
||||||
const { SecretModel, UserModel, MessageModel, ThreadModel } = require("../models");
|
const Models = require("../models");
|
||||||
(async () => {
|
|
||||||
|
|
||||||
await UserModel.deleteMany({});
|
|
||||||
await ThreadModel.deleteMany({});
|
|
||||||
await MessageModel.deleteMany({});
|
|
||||||
await SecretModel.deleteMany({});
|
|
||||||
console.log("Success")
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
|
Object.values(Models).forEach(model => model.deleteMany({}).then(console.log));
|
||||||
|
|
|
@ -6,8 +6,31 @@
|
||||||
|
|
||||||
<body style="text-align: center;">
|
<body style="text-align: center;">
|
||||||
<%- include("extra/navbar") %>
|
<%- include("extra/navbar") %>
|
||||||
<b>SİLME LAN İT BEN SİLECEĞİM</b>
|
<b>SİLME LAN İT BEN SİLECEĞİM</b>
|
||||||
<h1 style="color: #4d18e6;">Welcome to the admin panel of the forum, <%= user.name %>!</h1>
|
<h1 style="color: #4d18e6;">Welcome to the admin panel of the forum, <%= user.name %>!</h1>
|
||||||
<h2 style="color: #606060;">Write an ID to give someone admin permissions:</h2>
|
<h2 style="color: #606060;">Banned users:</h2>
|
||||||
|
|
||||||
|
<table >
|
||||||
|
<tr>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>Reason</th>
|
||||||
|
<th>AuthorID</th>
|
||||||
|
</tr>
|
||||||
|
<% for (const ban of bans) { %>
|
||||||
|
<tr>
|
||||||
|
<td><%=ban.ip%></td>
|
||||||
|
<td><%=ban.reason%></td>
|
||||||
|
<td><%=ban.authorID%></td>
|
||||||
|
</tr>
|
||||||
|
<% } %>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function ban() {
|
||||||
|
var id = document.getElementById("id").value;
|
||||||
|
window.location.href = "/ban/give/" + id;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div style="text-align:center;padding:8px">
|
<div style="text-align:center;padding:8px">
|
||||||
<div class="title" id="title"><%= thread.title %></div>
|
<div class="title" id="title"><%= thread.title %></div>
|
||||||
<div class="date">
|
<div class="date">
|
||||||
<%= new Date(thread.time).toLocaleString() %> • Views: <%= thread.views %>
|
<%= new Date(thread.time).toLocaleString() %> • Views: <%= thread.views %> <%= "• "+thread.edited %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,11 +25,11 @@
|
||||||
|
|
||||||
<% if (user && !thread.deleted){ %>
|
<% if (user && !thread.deleted){ %>
|
||||||
|
|
||||||
<a onclick="thread('<%= thread.id %>')" class="btn-outline-primary" >DELETE</a>
|
<a onclick="delete_thread('<%= thread.id %>')" class="btn-outline-primary" >DELETE</a>
|
||||||
<a onclick="edit_t('<%= thread.id %>')" class="btn-outline-primary" >EDIT</a>
|
<a onclick="edit_t('<%= thread.id %>')" class="btn-outline-primary" >EDIT</a>
|
||||||
<% } else if (thread.deleted) { %>
|
<% } else if (thread.deleted) { %>
|
||||||
<h3 style="display:inline;">This thread has been deleted</h3>
|
<h3 style="display:inline;">This thread has been deleted</h3>
|
||||||
<a onclick="thread('<%= thread.id %>', 'un')" class="btn-primary" >UNDELETE</a>
|
<a onclick="undelete_thread('<%= thread.id %>')" class="btn-primary" >UNDELETE</a>
|
||||||
|
|
||||||
<% }; %>
|
<% }; %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -36,17 +36,16 @@
|
||||||
<h2 class="box-value"><%= counts.thread %></h2>
|
<h2 class="box-value"><%= counts.thread %></h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<h2 class="box-title">About:</h2><br>
|
<h2 class="box-title">About:</h2>
|
||||||
</div>
|
</div>
|
||||||
<p class="box-value">
|
<p class="box-value">
|
||||||
<%= member.about %>
|
<%= member.about %>
|
||||||
</p>
|
</p>
|
||||||
<% if (user && (user.id === member.id ||user.admin)) {%>
|
|
||||||
|
|
||||||
<a class="btn-outline-primary" id="edit_n">Change name of the user!</a>
|
|
||||||
<a class="btn-outline-primary" id="edit_a">Change avatar of the user!</a>
|
|
||||||
|
|
||||||
<% if (user?.admin && !member.deleted) {%>
|
<% if (user?.admin && !member.deleted) {%>
|
||||||
|
<a class="btn-outline-primary" id="edit_name">Change name of the user!</a>
|
||||||
|
<a class="btn-outline-primary" id="edit_avatar">Change avatar of the user!</a>
|
||||||
|
<a class="btn-outline-primary" id="edit_about">Change about of the user!</a>
|
||||||
<a class="btn-outline-primary" id="admin">Give admin permissions!</a>
|
<a class="btn-outline-primary" id="admin">Give admin permissions!</a>
|
||||||
<a class="btn-outline-primary" id="delete">Delete user!</a>
|
<a class="btn-outline-primary" id="delete">Delete user!</a>
|
||||||
|
|
||||||
|
@ -61,27 +60,27 @@
|
||||||
if (response.admin)
|
if (response.admin)
|
||||||
return alert("Making admin of " + response.name + " is success!");
|
return alert("Making admin of " + response.name + " is success!");
|
||||||
|
|
||||||
}else if (e.target.id == "delete") {
|
} else if (e.target.id == "delete") {
|
||||||
|
|
||||||
const response = await request("/api/users/<%= member.id %>/delete");
|
const response = await request("/api/users/<%= member.id %>","DELETE");
|
||||||
|
|
||||||
if (!response.deleted) return
|
if (!response.deleted) return
|
||||||
alert("User is deleted!");
|
alert("User is deleted!");
|
||||||
location.reload()
|
location.reload()
|
||||||
|
|
||||||
}else if (e.target.id == "edit_n") {
|
} else {
|
||||||
|
|
||||||
const name = prompt("Enter new username!");
|
const body = {};
|
||||||
const res =await request(`/api/users/<%= member.id %>/edit`, "POST", { name });
|
|
||||||
if (res.error) return;
|
|
||||||
alert(`User updated!`);
|
|
||||||
location.reload();
|
|
||||||
|
|
||||||
|
if (e.target.id == "edit_name")
|
||||||
|
body.name = prompt("Enter new username!");
|
||||||
|
else if (e.target.id == "edit_avatar")
|
||||||
|
body.avatar = prompt("Enter new avatar URL!");
|
||||||
|
else if (e.target.id == "edit_avatar")
|
||||||
|
body.about = prompt("Enter new about text!");
|
||||||
|
else return;
|
||||||
|
const res = await request(`/api/users/<%= member.id %>`, "PATCH", body);
|
||||||
|
|
||||||
}else if (e.target.id == "edit_a") {
|
|
||||||
|
|
||||||
const avatar = prompt("Enter new avatar URL!");
|
|
||||||
const res =await request(`/api/users/<%= member.id %>/edit`, "POST", { avatar });
|
|
||||||
if (res.error) return;
|
if (res.error) return;
|
||||||
alert(`User updated!`);
|
alert(`User updated!`);
|
||||||
location.reload();
|
location.reload();
|
||||||
|
@ -89,17 +88,13 @@
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<% }; %>
|
<% }; %>
|
||||||
<% if (member.deleted) {%>
|
<% if (member.deleted) {%>
|
||||||
<h1>This user has been deleted!</h1>
|
<h1>This user has been deleted!</h1>
|
||||||
<a onclick="undelete();" class="btn-primary" >Undelete user! </a>
|
<a onclick="undelete();" class="btn-primary" >Undelete user! </a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
|
|
||||||
import request from "../../js/request.js";
|
import request from "../../js/request.js";
|
||||||
window.undelete= async function undelete(params) {
|
window.undelete= async function undelete(params) {
|
||||||
|
|
||||||
|
@ -109,13 +104,10 @@
|
||||||
alert("User is undeleted successfully!");
|
alert("User is undeleted successfully!");
|
||||||
location.reload()
|
location.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<% }; %>
|
<% }; %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue