Sqliteification
This commit is contained in:
101
mssql-wrapper.js
101
mssql-wrapper.js
@@ -1,101 +0,0 @@
|
||||
// Vibe coded since I needed more resources on my VPS :/
|
||||
|
||||
const Database = require('better-sqlite3');
|
||||
|
||||
// 1. Connect to the file (creates it if missing)
|
||||
const db = new Database('project.db');
|
||||
db.pragma('journal_mode = WAL'); // Faster, safer writes
|
||||
|
||||
class FakeMssqlRequest {
|
||||
constructor(db) {
|
||||
this.db = db;
|
||||
this.params = {}; // Stores your inputs: .input('id', 123)
|
||||
}
|
||||
|
||||
// Mimic the .input() method
|
||||
// We ignore 'type' because SQLite is loosely typed
|
||||
input(name, type, value) {
|
||||
// Handle case where value is passed as 2nd arg (omitting type)
|
||||
if (value === undefined) value = type;
|
||||
|
||||
this.params[name] = value;
|
||||
return this; // Return 'this' to allow chaining (.input().input())
|
||||
}
|
||||
|
||||
// Mimic the .query() method
|
||||
async query(sqlString) {
|
||||
try {
|
||||
let cleanSql = sqlString;
|
||||
|
||||
// --- FIX 1: Handle TOP -> LIMIT ---
|
||||
// Regex detects: SELECT TOP (@amount) ... OR SELECT TOP 10 ...
|
||||
// It captures the value (@amount or 10)
|
||||
const topRegex = /SELECT\s+TOP\s*\(?(@?\w+)\)?/i;
|
||||
const topMatch = cleanSql.match(topRegex);
|
||||
|
||||
if (topMatch) {
|
||||
const limitValue = topMatch[1]; // Extracts '@amount' or '10'
|
||||
|
||||
// 1. Remove "TOP (@amount)" from the start
|
||||
cleanSql = cleanSql.replace(topRegex, 'SELECT ');
|
||||
|
||||
// 2. Remove any trailing semicolon so we can append
|
||||
cleanSql = cleanSql.replace(/;\s*$/, '');
|
||||
|
||||
// 3. Append LIMIT to the end
|
||||
cleanSql += ` LIMIT ${limitValue}`;
|
||||
}
|
||||
|
||||
// 1. Compatibility Fixes (Optional but helpful)
|
||||
// Replace 'GETDATE()' with SQLite's "datetime('now')"
|
||||
cleanSql = cleanSql.replace(/GETDATE\(\)/gi, "datetime('now', 'localtime')")
|
||||
// MS SQL: SYSUTCDATETIME() -> SQLite: datetime('now') (Already UTC)
|
||||
.replace(/SYSUTCDATETIME\(\)/gi, "datetime('now')")
|
||||
// --- FIX 3: Clean up Square Brackets ---
|
||||
.replace(/\[/g, '"').replace(/\]/g, '"')
|
||||
|
||||
// --- FIX 4: Handle String Concatenation in LIKE clauses ---
|
||||
// MSSQL: LIKE '%' + @param + '%'
|
||||
// SQLite: LIKE '%' || @param || '%'
|
||||
// This regex looks for: LIKE '%' + @anything + '%'
|
||||
.replace(/LIKE\s+'%'\s*\+\s*(@\w+)\s*\+\s*'%'/gi, "LIKE '%' || $1 || '%'");
|
||||
// 2. Determine if it's a SELECT or INSERT/UPDATE
|
||||
const stmt = this.db.prepare(cleanSql);
|
||||
|
||||
if (cleanSql.trim().toUpperCase().startsWith('SELECT')) {
|
||||
// READ: Use .all()
|
||||
const rows = stmt.all(this.params);
|
||||
return { recordset: rows, rowsAffected: [rows.length] };
|
||||
} else {
|
||||
// WRITE: Use .run()
|
||||
const info = stmt.run(this.params);
|
||||
return { recordset: [], rowsAffected: [info.changes] };
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("SQLite Error:", err.message);
|
||||
console.error("Query was:", sqlString);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mimic the main 'pool' object
|
||||
const pool = {
|
||||
connected: true,
|
||||
request: () => new FakeMssqlRequest(db),
|
||||
close: () => db.close()
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
// Mimic the sql.connect() function
|
||||
connect: async () => {
|
||||
console.log("Connected to SQLite (via Wrapper)");
|
||||
return pool;
|
||||
},
|
||||
// Export types to prevent "sql.Int is undefined" errors
|
||||
Int: 'Int',
|
||||
NVarChar: 'NVarChar',
|
||||
Bit: 'Bit',
|
||||
DateTime: 'DateTime'
|
||||
};
|
||||
|
||||
BIN
project.db-shm
BIN
project.db-shm
Binary file not shown.
BIN
project.db-wal
BIN
project.db-wal
Binary file not shown.
206
server.js
206
server.js
@@ -1,9 +1,10 @@
|
||||
const express = require("express");
|
||||
const sql = require("./mssql-wrapper");
|
||||
const sqlite = require("better-sqlite3");
|
||||
const bcrypt = require("bcrypt");
|
||||
const cors = require("cors");
|
||||
const jwt = require("jsonwebtoken")
|
||||
const dotenv = require("dotenv")
|
||||
const dotenv = require("dotenv");
|
||||
const Database = require("better-sqlite3");
|
||||
|
||||
const serverPort = 3001;
|
||||
|
||||
@@ -26,18 +27,8 @@ app.use(cors({
|
||||
]
|
||||
}));
|
||||
|
||||
let dbConfig = null;
|
||||
|
||||
dbConfig = {
|
||||
user: "server",
|
||||
password: "TorusField1*",
|
||||
server: "mssql.rochesterx.dev",
|
||||
database: "Project",
|
||||
options: { trustServerCertificate: true }
|
||||
};
|
||||
|
||||
let pool = null;
|
||||
setupPool();
|
||||
const db = new Database("project.db");
|
||||
db.pragma("journal_mode = WAL")
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@@ -46,20 +37,21 @@ if (!JWT_SECRET) {
|
||||
throw new Error("JWT_SECRET not set in environment.");
|
||||
}
|
||||
|
||||
async function setupPool() {
|
||||
pool = await sql.connect(dbConfig);
|
||||
}
|
||||
|
||||
app.post("/register", async (req, res) => {
|
||||
const { username, password, role } = req.body;
|
||||
try {
|
||||
const hash = await bcrypt.hash(password, 10);
|
||||
await pool.request()
|
||||
.input("username", sql.VarChar, username)
|
||||
.input("hash", sql.VarChar, hash)
|
||||
.input("role", sql.VarChar, role)
|
||||
.query("INSERT INTO Users (Username, PasswordHash, Role, CreatedAt) VALUES (@username, @hash, @role, SYSUTCDATETIME())");
|
||||
|
||||
const inputs = {
|
||||
username: username,
|
||||
hash: hash,
|
||||
role: role
|
||||
}
|
||||
const query = db.prepare("INSERT INTO Users (Username, PasswordHash, Role, CreatedAt) VALUES (@username, @hash, @role, datetime('now'))");
|
||||
query.run(inputs);
|
||||
|
||||
res.send({ success: true, message: "User registered" })
|
||||
|
||||
} catch (err) {
|
||||
if (err.message.includes("Violation of UNIQUE KEY constraint")) {
|
||||
res.status(500).send({ success: false, message: `Username "${username}" is already taken.` });
|
||||
@@ -71,14 +63,13 @@ app.post("/register", async (req, res) => {
|
||||
app.post("/login", async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
try {
|
||||
const result = await pool.request()
|
||||
.input("username", sql.VarChar, username)
|
||||
.query("SELECT * FROM Users WHERE Username = @username");
|
||||
const query = db.prepare("SELECT * FROM Users WHERE Username = @username");
|
||||
const results = query.all({ username: username });
|
||||
|
||||
if (result.recordset.length == 0) return res.status(400).send({ message: "User not found" });
|
||||
if (results.length == 0) return res.status(400).send({ message: "User not found" });
|
||||
|
||||
const hash = result.recordset[0].PasswordHash;
|
||||
const isDeleted = result.recordset[0].IsDeleted;
|
||||
const hash = results[0].PasswordHash;
|
||||
const isDeleted = results[0].IsDeleted;
|
||||
|
||||
if (isDeleted === true) {
|
||||
return res.status(400).json({ message: "User not found (deleted)" })
|
||||
@@ -87,15 +78,14 @@ app.post("/login", async (req, res) => {
|
||||
const match = await bcrypt.compare(password, hash);
|
||||
|
||||
if (match){
|
||||
const token = jwt.sign(result.recordset[0], JWT_SECRET, { expiresIn: "1h" });
|
||||
const token = jwt.sign(results[0], JWT_SECRET, { expiresIn: "1h" });
|
||||
res.send({
|
||||
success: true,
|
||||
message: "Login successful",
|
||||
token
|
||||
});
|
||||
await pool.request()
|
||||
.input("username", sql.VarChar, username)
|
||||
.query("UPDATE Users SET LastLogin = SYSUTCDATETIME() WHERE Username = @username");
|
||||
const update = db.prepare("UPDATE Users SET LastLogin = datetime('now') WHERE Username = @username");
|
||||
update.run({ username: username });
|
||||
|
||||
console.log("Issued token: " + JSON.stringify(token))
|
||||
}
|
||||
@@ -108,23 +98,23 @@ app.post("/login", async (req, res) => {
|
||||
app.post("/getWatchlist", authenticate, async (req, res) => {
|
||||
const { id } = req.body;
|
||||
|
||||
const watchlist = await pool.request()
|
||||
.input("userID", sql.Int, req.user.Id)
|
||||
.input("id", sql.Int, id)
|
||||
.query(`SELECT Player.PlayerName, Player.Team, Player.Position, Player.PlayerID FROM Watch JOIN Player ON Watch.PlayerID = Player.PlayerID WHERE UserID = @userID ORDER BY Player.PlayerName`);
|
||||
const query = db.prepare(`SELECT Player.PlayerName, Player.Team, Player.Position, Player.PlayerID FROM Watch JOIN Player ON Watch.PlayerID = Player.PlayerID WHERE UserID = @userID ORDER BY Player.PlayerName`);
|
||||
const watchlist = query.all({
|
||||
userID: req.user.Id,
|
||||
id: id
|
||||
});
|
||||
|
||||
res.status(200).json({ watchlist: watchlist.recordset });
|
||||
|
||||
res.status(200).json({ watchlist: watchlist });
|
||||
});
|
||||
|
||||
app.post("/isWatched", authenticate, async (req, res) => {
|
||||
const { id } = req.body;
|
||||
|
||||
const watchlist = await pool.request()
|
||||
.input("userID", sql.Int, req.user.Id)
|
||||
.input("id", sql.Int, id)
|
||||
.query(`SELECT PlayerID FROM Watch WHERE UserID = @userID`);
|
||||
const query = db.prepare(`SELECT PlayerID FROM Watch WHERE UserID = @userID`);
|
||||
const watchlist = query.all({ userID: req.user.Id, id: id});
|
||||
|
||||
const isWatched = watchlist.recordset.some(row => row.PlayerID === parseInt(id));
|
||||
const isWatched = watchlist.some(row => row.PlayerID === parseInt(id));
|
||||
|
||||
res.status(200).json({ isWatched: isWatched });
|
||||
});
|
||||
@@ -132,30 +122,22 @@ app.post("/isWatched", authenticate, async (req, res) => {
|
||||
app.post("/toggleWatched", authenticate, async (req, res) => {
|
||||
const { id } = req.body;
|
||||
|
||||
const watchlist = await pool.request()
|
||||
.input("userID", sql.Int, req.user.Id)
|
||||
.input("id", sql.Int, id)
|
||||
.query(`SELECT PlayerID FROM Watch WHERE UserID = @userID`);
|
||||
console.log(watchlist.recordset);
|
||||
const query = db.prepare(`SELECT PlayerID FROM Watch WHERE UserID = @userID`);
|
||||
const watchlist = query.all({ userID: req.user.Id, id: id });
|
||||
|
||||
const isWatched = watchlist.recordset.some(row => row.PlayerID === parseInt(id));
|
||||
console.log(isWatched);
|
||||
const isWatched = watchlist.some(row => row.PlayerID === parseInt(id));
|
||||
|
||||
if (isWatched) {
|
||||
const result = await pool.request()
|
||||
.input("userID", sql.Int, req.user.Id)
|
||||
.input("id", sql.Int, id)
|
||||
.query(`DELETE FROM Watch WHERE UserID = @userID AND PlayerID = @id`);
|
||||
const query = db.prepare(`DELETE FROM Watch WHERE UserID = @userID AND PlayerID = @id`);
|
||||
query.run({ userID: req.user.Id, id: id });
|
||||
|
||||
res.status(200).json({ message: "No longer watching player" });
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, watch the player
|
||||
const result = await pool.request()
|
||||
.input("userID", sql.Int, req.user.Id)
|
||||
.input("id", sql.Int, id)
|
||||
.query(`INSERT INTO Watch (UserID, PlayerID) VALUES (@userID, @id)`);
|
||||
const watchQuery = db.prepare(`INSERT INTO Watch (UserID, PlayerID) VALUES (@userID, @id)`);
|
||||
watchQuery.run({ userID: req.user.Id, id: id });
|
||||
|
||||
res.status(200).json({ message: "Watching Player" });
|
||||
});
|
||||
@@ -163,38 +145,37 @@ app.post("/toggleWatched", authenticate, async (req, res) => {
|
||||
app.post("/getPlayers", authenticate, async (req, res) => {
|
||||
const { player, positions } = req.body;
|
||||
|
||||
const result = await pool.request()
|
||||
.input("query", sql.VarChar, player)
|
||||
.input("one", sql.VarChar, positions[0])
|
||||
.input("two", sql.VarChar, positions[1])
|
||||
.input("three", sql.VarChar, positions[2])
|
||||
.input("four", sql.VarChar, positions[3])
|
||||
.query(`SELECT p.PlayerID, p.PlayerName, c.TotalValue, p.Team, p.Position FROM Player AS p JOIN Contract AS c ON p.PlayerID = c.PlayerID WHERE p.PlayerName LIKE '%' + @query + '%' AND p.Position IN (@one, @two, @three, @four) ORDER BY p.PlayerName;`);
|
||||
const query = db.prepare(`SELECT p.PlayerID, p.PlayerName, c.TotalValue, p.Team, p.Position FROM Player AS p JOIN Contract AS c ON p.PlayerID = c.PlayerID WHERE p.PlayerName LIKE '%' || @query || '%' AND p.Position IN (@one, @two, @three, @four) ORDER BY p.PlayerName;`);
|
||||
const matches = query.all({
|
||||
query: player,
|
||||
one: positions[0],
|
||||
two: positions[1],
|
||||
three: positions[2],
|
||||
four: positions[3]
|
||||
});
|
||||
|
||||
res.status(200).json({ query: player, matches: result.recordset });
|
||||
res.status(200).json({ query: player, matches: matches });
|
||||
});
|
||||
|
||||
app.post("/getHighest", authenticate, async (req, res) => {
|
||||
const { amount } = req.body;
|
||||
|
||||
const result = await pool.request()
|
||||
.input("amount", sql.Int, amount)
|
||||
.query(`
|
||||
SELECT TOP (@amount) p.PlayerID, p.PlayerName, p.[Position], p.Team, TotalValue, TrueAvgPerYear, Years
|
||||
const query = db.prepare(`
|
||||
SELECT p.PlayerID, p.PlayerName, p.[Position], p.Team, TotalValue, TrueAvgPerYear, Years
|
||||
FROM Player AS p JOIN Contract AS c ON p.PlayerID = c.PlayerID
|
||||
ORDER BY TotalValue DESC;
|
||||
ORDER BY TotalValue DESC
|
||||
LIMIT @amount;
|
||||
`);
|
||||
const matches = query.all({ amount: amount });
|
||||
|
||||
res.status(200).json({ matches: result.recordset });
|
||||
res.status(200).json({ matches: matches });
|
||||
});
|
||||
|
||||
app.post("/getHighestOffense", authenticate, async (req, res) => {
|
||||
const { amount } = req.body;
|
||||
|
||||
const result = await pool.request()
|
||||
.input("amount", sql.Int, amount)
|
||||
.query(`
|
||||
SELECT TOP (@amount) Player.PlayerID, Player.[Position], Player.PlayerName, Player.Team,
|
||||
const query = db.prepare(`
|
||||
SELECT Player.PlayerID, Player.[Position], Player.PlayerName, Player.Team,
|
||||
SUM(total_yards) AS TotalYards,
|
||||
SUM(passing_yards) AS PassingYards,
|
||||
SUM(rushing_yards) AS RushingYards,
|
||||
@@ -233,38 +214,36 @@ SUM(tackled_for_loss)
|
||||
)
|
||||
- (SUM(safety) * 100.0)) / AvgPerYear AS PaydirtScore
|
||||
|
||||
|
||||
FROM Player JOIN DatasetPlayerStats ON Player.PlayerID = DatasetPlayerStats.PlayerID JOIN Contract ON Player.PlayerID = Contract.PlayerID
|
||||
WHERE season = 2024 AND SeasonType = 'REG'
|
||||
GROUP BY Player.PlayerID, Player.PlayerName, Player.Team, Player.[Position], Contract.AvgPerYear
|
||||
ORDER BY OffenseScore DESC;
|
||||
ORDER BY OffenseScore DESC
|
||||
LIMIT @amount;
|
||||
`);
|
||||
const matches = query.all({ amount: amount });
|
||||
|
||||
res.status(200).json({ matches: result.recordset });
|
||||
res.status(200).json({ matches: matches });
|
||||
});
|
||||
|
||||
|
||||
app.post("/getPlayerStats", authenticate, async (req, res) => {
|
||||
const { playerID } = req.body;
|
||||
|
||||
const result = await pool.request()
|
||||
.input("playerID", sql.Int, playerID)
|
||||
.query(`
|
||||
const query = db.prepare(`
|
||||
SELECT player.playerid, player.playername, season, seasontype, week, pass_attempts, complete_pass, total_yards, total_tds, interception, receptions, receiving_yards, receiving_touchdown, rush_attempts, rushing_yards, rush_touchdown, fumble
|
||||
fROM Player JOIN DatasetPlayerStats ON Player.PlayerID = DatasetPlayerStats.PlayerID
|
||||
WHERE Player.PlayerID = @playerID
|
||||
ORDER BY Season, week;
|
||||
`);
|
||||
const matches = query.all({ playerID: playerID })
|
||||
|
||||
res.status(200).json({ matches: result.recordset });
|
||||
res.status(200).json({ matches: matches });
|
||||
});
|
||||
|
||||
app.post("/getPlayerScores", authenticate, async (req, res) => {
|
||||
const { playerID } = req.body;
|
||||
|
||||
const result = await pool.request()
|
||||
.input("playerID", sql.Int, playerID)
|
||||
.query(`
|
||||
const query = db.prepare(`
|
||||
SELECT Player.PlayerID, Player.[Position], Player.PlayerName, Player.Team,
|
||||
c.TotalValue, c.TrueAvgPerYear, c.Years, c.StartYear, c.EndYear, Player.Height, Player.Weight,
|
||||
SUM(total_yards) AS TotalYards,
|
||||
@@ -312,9 +291,9 @@ WHERE season = 2024 AND SeasonType = 'REG' AND Player.PlayerID = @playerID
|
||||
GROUP BY c.TotalValue, c.TrueAvgPerYear, c.Years, c.StartYear, Player.Height, Player.Weight, c.EndYear, Player.PlayerID, Player.PlayerName, Player.Team, Player.[Position], c.AvgPerYear
|
||||
ORDER BY PaydirtScore DESC;
|
||||
`);
|
||||
console.log(result.recordset);
|
||||
const matches = query.all({ playerID: playerID })
|
||||
|
||||
res.status(200).json({ match: result.recordset[0] });
|
||||
res.status(200).json({ match: matches[0] });
|
||||
});
|
||||
|
||||
|
||||
@@ -322,10 +301,8 @@ ORDER BY PaydirtScore DESC;
|
||||
app.post("/getHighestPaydirt", authenticate, async (req, res) => {
|
||||
const { amount } = req.body;
|
||||
|
||||
const result = await pool.request()
|
||||
.input("amount", sql.Int, amount)
|
||||
.query(`
|
||||
SELECT TOP (@amount) Player.PlayerID, Player.[Position], Player.PlayerName, Player.Team,
|
||||
const query = db.prepare(`
|
||||
SELECT Player.PlayerID, Player.[Position], Player.PlayerName, Player.Team,
|
||||
SUM(total_yards) AS TotalYards,
|
||||
SUM(passing_yards) AS PassingYards,
|
||||
SUM(rushing_yards) AS RushingYards,
|
||||
@@ -369,24 +346,25 @@ SUM(tackled_for_loss)
|
||||
FROM Player JOIN DatasetPlayerStats ON Player.PlayerID = DatasetPlayerStats.PlayerID JOIN Contract ON Player.PlayerID = Contract.PlayerID
|
||||
WHERE season = 2024 AND SeasonType = 'REG'
|
||||
GROUP BY Player.PlayerID, Player.PlayerName, Player.Team, Player.[Position], Contract.AvgPerYear
|
||||
ORDER BY PaydirtScore DESC;
|
||||
ORDER BY PaydirtScore DESC
|
||||
LIMIT @amount;
|
||||
`);
|
||||
const matches = query.all({ amount: amount });
|
||||
|
||||
res.status(200).json({ matches: result.recordset });
|
||||
res.status(200).json({ matches: matches });
|
||||
});
|
||||
|
||||
app.post("/getPlayer", authenticate, async (req, res) => {
|
||||
const { id } = req.body;
|
||||
|
||||
const result = await pool.request()
|
||||
.input("query", sql.VarChar, id)
|
||||
.query(`SELECT p.PlayerName, p.PlayerID, c.TotalValue, c.TrueAvgPerYear, c.Years, c.StartYear, c.EndYear, p.Team, p.Position FROM Player AS p JOIN Contract AS c ON p.PlayerID = c.PlayerID WHERE p.PlayerID = @query`);
|
||||
const query = db.prepare(`SELECT p.PlayerName, p.PlayerID, c.TotalValue, c.TrueAvgPerYear, c.Years, c.StartYear, c.EndYear, p.Team, p.Position FROM Player AS p JOIN Contract AS c ON p.PlayerID = c.PlayerID WHERE p.PlayerID = @query`);
|
||||
const matches = query.run({ query: id });
|
||||
|
||||
if (result.recordset.length !== 1) {
|
||||
if (matches.length !== 1) {
|
||||
res.status(400).json({ success: false })
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ success: true, match: result.recordset[0] });
|
||||
res.status(200).json({ success: true, match: matches[0] });
|
||||
});
|
||||
|
||||
app.post("/getInfo", authenticate, async (req, res) => {
|
||||
@@ -396,10 +374,8 @@ app.post("/getInfo", authenticate, async (req, res) => {
|
||||
});
|
||||
|
||||
app.post("/getCourses", authenticate, async (req, res) => {
|
||||
const result = await pool.request()
|
||||
.query("SELECT * FROM Courses");
|
||||
|
||||
const courses = result.recordset;
|
||||
const query = db.prepare("SELECT * FROM Courses");
|
||||
const courses = query.all();
|
||||
|
||||
res.status(200).json(courses);
|
||||
});
|
||||
@@ -408,18 +384,19 @@ app.post("/setInfo", authenticate, async (req, res) => {
|
||||
const { firstName, lastName, dob } = req.body;
|
||||
|
||||
try {
|
||||
await pool.request()
|
||||
.input("username", sql.VarChar, req.user.Username)
|
||||
.input("firstName", sql.NVarChar(50), firstName)
|
||||
.input("lastName", sql.NVarChar(50), lastName)
|
||||
.input("dob", sql.Date, dob || null)
|
||||
.query(`
|
||||
const query = db.prepare(`
|
||||
UPDATE Users
|
||||
SET FirstName = @firstName,
|
||||
LastName = @lastName,
|
||||
DOB = @dob
|
||||
WHERE Username = @username
|
||||
`);
|
||||
query.run({
|
||||
username: req.user.Username,
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
dob: dob || null
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
if (error.message.includes("failed for parameter 'dob'.")) {
|
||||
@@ -456,10 +433,11 @@ app.post("/delete", authenticate, async (req, res) => {
|
||||
|
||||
console.log(`Deleting user ${username}`);
|
||||
|
||||
await pool.request()
|
||||
.input("username", sql.VarChar, username)
|
||||
.input("actor", sql.VarChar, actor)
|
||||
.query("UPDATE Users SET IsDeleted = 1, DeletedAt = SYSUTCDATETIME(), DeletedBy = @actor WHERE Username = @username");
|
||||
const query = ("UPDATE Users SET IsDeleted = 1, DeletedAt = datetime('now'), DeletedBy = @actor WHERE Username = @username");
|
||||
query.run({
|
||||
username: username,
|
||||
actor: actor
|
||||
});
|
||||
|
||||
console.log(`User ${username} deleted`);
|
||||
res.status(200).json({ message: `User "${username}" deleted.` });
|
||||
@@ -511,4 +489,6 @@ app.get("/register", (req, res) => {
|
||||
app.get("/login", (req, res) => {
|
||||
res.sendFile(__dirname + "/public/login.html");
|
||||
})
|
||||
|
||||
app.listen(serverPort, "0.0.0.0", () => console.log(`Running ${dev ? "dev " : ""}server on port ${serverPort}`));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user