v1.0.0
This commit is contained in:
@@ -2,392 +2,272 @@ const crypto = require('crypto');
|
||||
const db = require("../config/db");
|
||||
|
||||
class SheepService {
|
||||
getSheep(uuid, sheepRole) {
|
||||
getSheep(id, mode) {
|
||||
return new Promise((res, rej) => {
|
||||
let sql = `
|
||||
const sql = `
|
||||
SELECT
|
||||
sheeps.*,
|
||||
groups.group_number AS group_id,
|
||||
administrators.id AS administrators_id,
|
||||
administrators.uuid AS administrators_uuid,
|
||||
moderators.id AS moderators_id,
|
||||
moderators.uuid AS moderators_uuid,
|
||||
moderators.can_add_sheeps,
|
||||
moderators.can_add_territory,
|
||||
moderators.can_manager_territory,
|
||||
moderators.can_add_stand,
|
||||
moderators.can_manager_stand,
|
||||
moderators.can_add_schedule
|
||||
possibilities.can_add_sheeps,
|
||||
possibilities.can_view_sheeps,
|
||||
possibilities.can_add_territory,
|
||||
possibilities.can_view_territory,
|
||||
possibilities.can_manager_territory,
|
||||
possibilities.can_add_stand,
|
||||
possibilities.can_view_stand,
|
||||
possibilities.can_manager_stand,
|
||||
possibilities.can_add_schedule,
|
||||
possibilities.can_view_schedule
|
||||
FROM
|
||||
sheeps
|
||||
LEFT JOIN
|
||||
groups ON groups.group_number = sheeps.group_id
|
||||
LEFT JOIN
|
||||
administrators ON administrators.sheep_id = sheeps.id
|
||||
LEFT JOIN
|
||||
moderators ON moderators.sheep_id = sheeps.id
|
||||
possibilities ON possibilities.sheep_id = sheeps.id
|
||||
WHERE
|
||||
sheeps.uuid = ?
|
||||
LIMIT 1;
|
||||
`
|
||||
db.get(sql, [uuid], (err, sheep) => {
|
||||
sheeps.id = ?
|
||||
`;
|
||||
|
||||
db.get(sql, [id], (err, sheep) => {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
return res(false);
|
||||
} else if (!sheep) {
|
||||
console.log({ "error": "uuid not found" });
|
||||
return res(false);
|
||||
} else {
|
||||
let data = {
|
||||
"id": Number(sheep.id),
|
||||
"group_id": Number(sheep.group_id),
|
||||
"name": sheep.name,
|
||||
"icon": sheep.icon,
|
||||
"uuid": sheep.uuid,
|
||||
"appointment": sheep.appointment,
|
||||
"can_view_stand": sheep.can_view_stand == 0 ? false : true,
|
||||
"can_view_schedule": sheep.can_view_schedule == 0 ? false : true,
|
||||
"can_view_territory": sheep.can_view_territory == 0 ? false : true,
|
||||
"administrator": {
|
||||
"id": sheep.administrators_id ? sheep.administrators_id : false,
|
||||
"uuid": null
|
||||
},
|
||||
"moderator": {
|
||||
"id": sheep.moderators_id ? sheep.moderators_id : false,
|
||||
"uuid": null,
|
||||
"can_add_sheeps": sheep.can_add_sheeps == 1 ? true : false,
|
||||
"can_add_territory": sheep.can_add_territory == 1 ? true : false,
|
||||
"can_manager_territory": sheep.can_manager_territory == 1 ? true : false,
|
||||
"can_add_stand": sheep.can_add_stand == 1 ? true : false,
|
||||
"can_manager_stand": sheep.can_manager_stand == 1 ? true : false,
|
||||
"can_add_schedule": sheep.can_add_schedule == 1 ? true : false
|
||||
}
|
||||
}
|
||||
|
||||
if (sheepRole == "administrator") {
|
||||
if (sheep.administrators_id) {
|
||||
data.administrator.uuid = sheep.administrators_uuid;
|
||||
}
|
||||
if (sheep.moderators_id) {
|
||||
data.moderator.uuid = sheep.moderators_uuid;
|
||||
}
|
||||
}
|
||||
|
||||
return res(data);
|
||||
}
|
||||
if (!sheep) {
|
||||
console.log({ error: "id not found" });
|
||||
return res(false);
|
||||
}
|
||||
|
||||
const fields = [
|
||||
"can_add_sheeps",
|
||||
"can_view_sheeps",
|
||||
"can_add_territory",
|
||||
"can_view_territory",
|
||||
"can_manager_territory",
|
||||
"can_add_stand",
|
||||
"can_view_stand",
|
||||
"can_manager_stand",
|
||||
"can_add_schedule",
|
||||
"can_view_schedule"
|
||||
];
|
||||
|
||||
const data = {
|
||||
id: sheep.id,
|
||||
group_id: sheep.group_id,
|
||||
name: sheep.name,
|
||||
icon: sheep.icon,
|
||||
uuid: sheep.uuid,
|
||||
uuid_manager: mode && mode === 2 ? sheep.uuid_manager : null,
|
||||
appointment: sheep.appointment,
|
||||
mode: mode ? Number(sheep.mode) : 0,
|
||||
mode_title: sheep.mode_title,
|
||||
possibilities: {}
|
||||
};
|
||||
|
||||
fields.forEach(f => {
|
||||
data.possibilities[f] = false;
|
||||
});
|
||||
|
||||
|
||||
if (mode && (mode === 1 || mode === 2)) {
|
||||
fields.forEach(f => {
|
||||
data.possibilities[f] = !!sheep[f];
|
||||
});
|
||||
}
|
||||
|
||||
return res(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
getList(sheepRole) {
|
||||
getList(mode) {
|
||||
return new Promise((res, rej) => {
|
||||
let sql = `
|
||||
SELECT
|
||||
sheeps.*,
|
||||
groups.group_number AS group_id,
|
||||
administrators.id AS administrators_id,
|
||||
administrators.uuid AS administrators_uuid,
|
||||
moderators.id AS moderators_id,
|
||||
moderators.uuid AS moderators_uuid,
|
||||
moderators.can_add_sheeps,
|
||||
moderators.can_add_territory,
|
||||
moderators.can_manager_territory,
|
||||
moderators.can_add_stand,
|
||||
moderators.can_manager_stand,
|
||||
moderators.can_add_schedule
|
||||
FROM
|
||||
sheeps
|
||||
LEFT JOIN
|
||||
groups ON groups.group_number = sheeps.group_id
|
||||
LEFT JOIN
|
||||
administrators ON administrators.sheep_id = sheeps.id
|
||||
LEFT JOIN
|
||||
moderators ON moderators.sheep_id = sheeps.id
|
||||
ORDER BY
|
||||
id
|
||||
`;
|
||||
|
||||
db.all(sql, (err, sheeps) => {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
return res(false);
|
||||
} else {
|
||||
let result = sheeps.map((sheep) => {
|
||||
let data = {
|
||||
"id": Number(sheep.id),
|
||||
"group_id": Number(sheep.group_id),
|
||||
"name": sheep.name,
|
||||
"icon": sheep.icon,
|
||||
"uuid": sheep.uuid,
|
||||
"appointment": sheep.appointment,
|
||||
"can_view_stand": sheep.can_view_stand == 0 ? false : true,
|
||||
"can_view_schedule": sheep.can_view_schedule == 0 ? false : true,
|
||||
"can_view_territory": sheep.can_view_territory == 0 ? false : true,
|
||||
"administrator": {
|
||||
"id": sheep.administrators_id ? sheep.administrators_id : false,
|
||||
"uuid": null
|
||||
},
|
||||
"moderator": {
|
||||
"id": sheep.moderators_id ? sheep.moderators_id : false,
|
||||
"uuid": null,
|
||||
"can_add_sheeps": sheep.can_add_sheeps == 1 ? true : false,
|
||||
"can_add_territory": sheep.can_add_territory == 1 ? true : false,
|
||||
"can_manager_territory": sheep.can_manager_territory == 1 ? true : false,
|
||||
"can_add_stand": sheep.can_add_stand == 1 ? true : false,
|
||||
"can_manager_stand": sheep.can_manager_stand == 1 ? true : false,
|
||||
"can_add_schedule": sheep.can_add_schedule == 1 ? true : false
|
||||
}
|
||||
}
|
||||
|
||||
if (sheepRole == "administrator") {
|
||||
if (sheep.administrators_id) {
|
||||
data.administrator.uuid = sheep.administrators_uuid;
|
||||
}
|
||||
if (sheep.moderators_id) {
|
||||
data.moderator.uuid = sheep.moderators_uuid;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
})
|
||||
|
||||
return res(result);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
getAdministrator(uuid) {
|
||||
return new Promise((res, rej) => {
|
||||
let sql = `
|
||||
const sql = `
|
||||
SELECT
|
||||
sheeps.*,
|
||||
groups.group_number AS group_id,
|
||||
administrators.id AS administrators_id,
|
||||
administrators.uuid AS administrators_uuid
|
||||
possibilities.can_add_sheeps,
|
||||
possibilities.can_view_sheeps,
|
||||
possibilities.can_add_territory,
|
||||
possibilities.can_view_territory,
|
||||
possibilities.can_manager_territory,
|
||||
possibilities.can_add_stand,
|
||||
possibilities.can_view_stand,
|
||||
possibilities.can_manager_stand,
|
||||
possibilities.can_add_schedule,
|
||||
possibilities.can_view_schedule
|
||||
FROM
|
||||
sheeps
|
||||
JOIN
|
||||
administrators ON sheeps.id = administrators.sheep_id
|
||||
LEFT JOIN
|
||||
groups ON groups.group_number = sheeps.group_id
|
||||
WHERE
|
||||
administrators.uuid = ?
|
||||
LIMIT 1;
|
||||
`
|
||||
db.get(sql, [uuid], (err, sheep) => {
|
||||
possibilities ON possibilities.sheep_id = sheeps.id
|
||||
ORDER BY
|
||||
sheeps.group_id
|
||||
`;
|
||||
|
||||
db.all(sql, (err, rows) => {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
return res(false);
|
||||
} else if (!sheep) {
|
||||
console.log({ "error": "uuid not found" });
|
||||
return res(false);
|
||||
} else {
|
||||
let data = {
|
||||
"id": Number(sheep.id),
|
||||
"group_id": Number(sheep.group_id),
|
||||
"name": sheep.name,
|
||||
"icon": sheep.icon,
|
||||
"uuid": sheep.uuid,
|
||||
"appointment": sheep.appointment,
|
||||
"can_view_stand": sheep.can_view_stand == 0 ? false : true,
|
||||
"can_view_schedule": sheep.can_view_schedule == 0 ? false : true,
|
||||
"can_view_territory": sheep.can_view_territory == 0 ? false : true,
|
||||
"administrator": {
|
||||
"id": sheep.administrators_id,
|
||||
"uuid": sheep.administrators_uuid
|
||||
},
|
||||
"moderator": false
|
||||
}
|
||||
|
||||
const fields = [
|
||||
"can_add_sheeps",
|
||||
"can_view_sheeps",
|
||||
"can_add_territory",
|
||||
"can_view_territory",
|
||||
"can_manager_territory",
|
||||
"can_add_stand",
|
||||
"can_view_stand",
|
||||
"can_manager_stand",
|
||||
"can_add_schedule",
|
||||
"can_view_schedule"
|
||||
];
|
||||
|
||||
const result = rows.map(sheep => {
|
||||
const data = {
|
||||
id: sheep.id,
|
||||
group_id: sheep.group_id,
|
||||
name: sheep.name,
|
||||
icon: sheep.icon,
|
||||
uuid: sheep.uuid,
|
||||
uuid_manager: (mode && mode == 2) ? sheep.uuid_manager : null,
|
||||
appointment: sheep.appointment,
|
||||
mode: mode ? Number(sheep.mode) : 0,
|
||||
mode_title: sheep.mode_title,
|
||||
possibilities: {}
|
||||
};
|
||||
|
||||
fields.forEach(f => {
|
||||
data.possibilities[f] = false;
|
||||
});
|
||||
|
||||
if (mode && (mode == 1 || mode == 2)) {
|
||||
fields.forEach(f => {
|
||||
data.possibilities[f] = !!sheep[f];
|
||||
});
|
||||
}
|
||||
|
||||
return res(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
getModerator(uuid) {
|
||||
return new Promise((res, rej) => {
|
||||
let sql = `
|
||||
SELECT
|
||||
sheeps.*,
|
||||
groups.group_number AS group_id,
|
||||
moderators.id AS moderators_id,
|
||||
moderators.uuid AS moderators_uuid,
|
||||
moderators.can_add_sheeps AS can_add_sheeps,
|
||||
moderators.can_add_territory AS can_add_territory,
|
||||
moderators.can_manager_territory AS can_manager_territory,
|
||||
moderators.can_add_stand AS can_add_stand,
|
||||
moderators.can_manager_stand AS can_manager_stand,
|
||||
moderators.can_add_schedule AS can_add_schedule
|
||||
FROM
|
||||
sheeps
|
||||
JOIN
|
||||
moderators ON sheeps.id = moderators.sheep_id
|
||||
LEFT JOIN
|
||||
groups ON groups.group_number = sheeps.group_id
|
||||
WHERE
|
||||
moderators.uuid = ?
|
||||
LIMIT 1;
|
||||
`
|
||||
db.get(sql, [uuid], (err, sheep) => {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
return res(false);
|
||||
} else if (!sheep) {
|
||||
console.log({ "error": "uuid not found" });
|
||||
return res(false);
|
||||
} else {
|
||||
let data = {
|
||||
"id": Number(sheep.id),
|
||||
"group_id": Number(sheep.group_id),
|
||||
"name": sheep.name,
|
||||
"icon": sheep.icon,
|
||||
"uuid": sheep.uuid,
|
||||
"appointment": sheep.appointment,
|
||||
"can_view_stand": sheep.can_view_stand == 0 ? false : true,
|
||||
"can_view_schedule": sheep.can_view_schedule == 0 ? false : true,
|
||||
"can_view_territory": sheep.can_view_territory == 0 ? false : true,
|
||||
"administrator": false,
|
||||
"moderator": {
|
||||
"id": sheep.moderators_id,
|
||||
"uuid": sheep.moderators_uuid,
|
||||
"can_add_sheeps": sheep.can_add_sheeps == 0 ? false : true,
|
||||
"can_add_territory": sheep.can_add_territory == 0 ? false : true,
|
||||
"can_manager_territory": sheep.can_manager_territory == 0 ? false : true,
|
||||
"can_add_stand": sheep.can_add_stand == 0 ? false : true,
|
||||
"can_manager_stand": sheep.can_manager_stand == 0 ? false : true,
|
||||
"can_add_schedule": sheep.can_add_schedule == 0 ? false : true
|
||||
}
|
||||
}
|
||||
return data;
|
||||
});
|
||||
|
||||
return res(data);
|
||||
}
|
||||
res(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
createSheep(data) {
|
||||
const stmt1 = db.prepare('INSERT INTO sheeps(name, group_id, appointment, uuid) VALUES (?, ?, ?, ?)');
|
||||
const stmt2 = db.prepare('INSERT INTO possibilities(can_view_territory, sheep_id) VALUES (?, ?)');
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
let sql = 'INSERT INTO sheeps(name, group_id, appointment, uuid) VALUES (?, ?, ?, ?)';
|
||||
db.serialize(() => {
|
||||
let uuid = crypto.randomUUID();
|
||||
|
||||
let uuid = crypto.randomUUID();
|
||||
stmt1.run([
|
||||
data.name,
|
||||
Number(data.group_id),
|
||||
data.appointment,
|
||||
uuid
|
||||
], function (err) {
|
||||
if (err) return rej(err);
|
||||
|
||||
db.run(sql, [
|
||||
data.name,
|
||||
Number(data.group_id),
|
||||
data.appointment,
|
||||
uuid
|
||||
], function (err) {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
return res(false);
|
||||
} else if (this.changes === 0) {
|
||||
return res(false);
|
||||
} else {
|
||||
res({ "status": "ok", "id": this.lastID, "uuid": uuid });
|
||||
}
|
||||
const newSheepId = this.lastID;
|
||||
|
||||
stmt2.run([
|
||||
1,
|
||||
newSheepId
|
||||
], (err2) => {
|
||||
if (err2) return rej(err2);
|
||||
res({ status: "ok", id: newSheepId, uuid: uuid });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
updateSheep(data) {
|
||||
return new Promise(async (res, rej) => {
|
||||
try {
|
||||
let sql = `
|
||||
UPDATE sheeps
|
||||
SET name = ?, group_id = ?, appointment = ?,
|
||||
can_view_stand = ?, can_view_schedule = ?, can_view_territory = ?
|
||||
WHERE uuid = ?
|
||||
`;
|
||||
const stmt1 = db.prepare(`
|
||||
UPDATE
|
||||
sheeps
|
||||
SET
|
||||
name = ?,
|
||||
group_id = ?,
|
||||
appointment = ?,
|
||||
mode = ?,
|
||||
mode_title = ?,
|
||||
uuid_manager = ?
|
||||
WHERE
|
||||
uuid = ?
|
||||
`);
|
||||
|
||||
await db.run(sql, [
|
||||
const stmt2 = db.prepare(`
|
||||
UPDATE
|
||||
possibilities
|
||||
SET
|
||||
can_add_sheeps = ?,
|
||||
can_view_sheeps = ?,
|
||||
can_add_territory = ?,
|
||||
can_view_territory = ?,
|
||||
can_manager_territory = ?,
|
||||
can_add_stand = ?,
|
||||
can_view_stand = ?,
|
||||
can_manager_stand = ?,
|
||||
can_add_schedule = ?,
|
||||
can_view_schedule = ?
|
||||
WHERE
|
||||
sheep_id = (SELECT id FROM sheeps WHERE uuid = ? LIMIT 1)
|
||||
`);
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
db.serialize(() => {
|
||||
let uuid_manager = crypto.randomUUID();
|
||||
|
||||
stmt1.run([
|
||||
data.name,
|
||||
Number(data.group_id),
|
||||
data.appointment,
|
||||
data.can_view_stand ? 1 : 0,
|
||||
data.can_view_schedule ? 1 : 0,
|
||||
data.can_view_territory ? 1 : 0,
|
||||
Number(data.mode),
|
||||
data.mode_title,
|
||||
Number(data.mode) == 0 ? null : (data.uuid_manager ? data.uuid_manager : uuid_manager),
|
||||
data.uuid
|
||||
]);
|
||||
], (err) => {
|
||||
if (err) return rej(err);
|
||||
|
||||
if (data.role === "administrator") {
|
||||
if (!data.administrator?.id) {
|
||||
await db.run(
|
||||
'INSERT INTO administrators(sheep_id, uuid) VALUES (?, ?)',
|
||||
[data.id, crypto.randomUUID()]
|
||||
);
|
||||
console.log({ insert: "ok" });
|
||||
}
|
||||
if (data.moderator?.id) {
|
||||
await db.run('DELETE FROM moderators WHERE id = ?', [data.moderator.id]);
|
||||
console.log({ delete: "ok" });
|
||||
}
|
||||
} else if (data.role === "moderator") {
|
||||
if (!data.moderator?.id) {
|
||||
await db.run(
|
||||
`INSERT INTO moderators(sheep_id, can_add_sheeps, can_add_territory,
|
||||
can_manager_territory, can_add_stand, can_manager_stand,
|
||||
can_add_schedule, uuid) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
data.id,
|
||||
data.moderator.can_add_sheeps ? 1 : 0,
|
||||
data.moderator.can_add_territory ? 1 : 0,
|
||||
data.moderator.can_manager_territory ? 1 : 0,
|
||||
data.moderator.can_add_stand ? 1 : 0,
|
||||
data.moderator.can_manager_stand ? 1 : 0,
|
||||
data.moderator.can_add_schedule ? 1 : 0,
|
||||
crypto.randomUUID()
|
||||
]
|
||||
);
|
||||
console.log({ insert: "ok" });
|
||||
} else {
|
||||
await db.run(
|
||||
`UPDATE moderators
|
||||
SET can_add_sheeps = ?, can_add_territory = ?,
|
||||
can_manager_territory = ?, can_add_stand = ?,
|
||||
can_manager_stand = ?, can_add_schedule = ?
|
||||
WHERE id = ?`,
|
||||
[
|
||||
data.moderator.can_add_sheeps ? 1 : 0,
|
||||
data.moderator.can_add_territory ? 1 : 0,
|
||||
data.moderator.can_manager_territory ? 1 : 0,
|
||||
data.moderator.can_add_stand ? 1 : 0,
|
||||
data.moderator.can_manager_stand ? 1 : 0,
|
||||
data.moderator.can_add_schedule ? 1 : 0,
|
||||
data.moderator.id
|
||||
]
|
||||
);
|
||||
console.log({ update: "ok" });
|
||||
}
|
||||
if (data.administrator?.id) {
|
||||
await db.run('DELETE FROM administrators WHERE id = ?', [data.administrator.id]);
|
||||
console.log({ delete: "ok" });
|
||||
}
|
||||
} else if (data.role === "sheep") {
|
||||
if (data.moderator?.id) {
|
||||
await db.run('DELETE FROM moderators WHERE id = ?', [data.moderator.id]);
|
||||
console.log({ delete: "ok" });
|
||||
}
|
||||
if (data.administrator?.id) {
|
||||
await db.run('DELETE FROM administrators WHERE id = ?', [data.administrator.id]);
|
||||
console.log({ delete: "ok" });
|
||||
}
|
||||
}
|
||||
|
||||
res({ status: "ok", id: data.id });
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
rej(false);
|
||||
}
|
||||
stmt2.run([
|
||||
data.possibilities.can_add_sheeps,
|
||||
data.possibilities.can_view_sheeps,
|
||||
data.possibilities.can_add_territory,
|
||||
data.possibilities.can_view_territory,
|
||||
data.possibilities.can_manager_territory,
|
||||
data.possibilities.can_add_stand,
|
||||
data.possibilities.can_view_stand,
|
||||
data.possibilities.can_manager_stand,
|
||||
data.possibilities.can_add_schedule,
|
||||
data.possibilities.can_view_schedule,
|
||||
data.uuid
|
||||
], (err2) => {
|
||||
if (err2) return rej(err2);
|
||||
res({ status: "ok", id: data.id });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
deleteSheep(data) {
|
||||
const stmtSelect = db.prepare('SELECT id FROM sheeps WHERE uuid = ?');
|
||||
const stmtDeletePoss = db.prepare('DELETE FROM possibilities WHERE sheep_id = ?');
|
||||
const stmtDeleteSheep = db.prepare('DELETE FROM sheeps WHERE uuid = ?');
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
db.run('DELETE FROM sheeps WHERE uuid = ?', [data.uuid], function (err) {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
return res(false);
|
||||
} else if (this.changes === 0) {
|
||||
return res(false);
|
||||
} else {
|
||||
res({ "dellete": "ok" });
|
||||
}
|
||||
db.serialize(() => {
|
||||
stmtSelect.get([data.uuid], (err, row) => {
|
||||
if (err) return rej(err);
|
||||
if (!row) return rej(new Error("Sheep not found"));
|
||||
|
||||
const sheepId = row.id;
|
||||
|
||||
stmtDeletePoss.run([sheepId], (err2) => {
|
||||
if (err2) return rej(err2);
|
||||
|
||||
stmtDeleteSheep.run([data.uuid], (err3) => {
|
||||
if (err3) return rej(err3);
|
||||
res({ status: "ok", deletedSheepId: sheepId });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user