All checks were successful
Deploy to production / deploy (push) Successful in 1m52s
- Implemented `adminCleanupCharacterDeathArtifacts` method in AdminService to remove stale character-bound data after death/inheritance, including knowledge, debtors prism, and political offices. - Added corresponding route in AdminRouter for triggering the cleanup process via an API endpoint. - Enhanced AdminController to handle requests for the new cleanup feature, ensuring proper error handling and response formatting. - Updated frontend components to include a user interface for initiating the cleanup, with localization support in both English and German for improved user experience.
1200 lines
48 KiB
JavaScript
1200 lines
48 KiB
JavaScript
import AdminService from '../services/adminService.js';
|
|
import Joi from 'joi';
|
|
|
|
class AdminController {
|
|
// --- Chat Room Admin ---
|
|
constructor() {
|
|
this.getOpenInterests = this.getOpenInterests.bind(this);
|
|
this.changeInterest = this.changeInterest.bind(this);
|
|
this.deleteInterest = this.deleteInterest.bind(this);
|
|
this.changeTranslation = this.changeTranslation.bind(this);
|
|
this.getOpenContacts = this.getOpenContacts.bind(this);
|
|
this.answerContact = this.answerContact.bind(this);
|
|
this.searchUser = this.searchUser.bind(this);
|
|
this.getFalukantUserById = this.getFalukantUserById.bind(this);
|
|
this.changeFalukantUser = this.changeFalukantUser.bind(this);
|
|
this.adminForceFalukantPregnancy = this.adminForceFalukantPregnancy.bind(this);
|
|
this.adminClearFalukantPregnancy = this.adminClearFalukantPregnancy.bind(this);
|
|
this.adminForceFalukantBirth = this.adminForceFalukantBirth.bind(this);
|
|
this.adminCleanupCharacterDeathArtifacts = this.adminCleanupCharacterDeathArtifacts.bind(this);
|
|
this.adminGetPotentialFathersForCharacter = this.adminGetPotentialFathersForCharacter.bind(this);
|
|
this.getFalukantUserBranches = this.getFalukantUserBranches.bind(this);
|
|
this.updateFalukantStock = this.updateFalukantStock.bind(this);
|
|
this.addFalukantStock = this.addFalukantStock.bind(this);
|
|
this.getFalukantStockTypes = this.getFalukantStockTypes.bind(this);
|
|
this.getRoomTypes = this.getRoomTypes.bind(this);
|
|
this.getGenderRestrictions = this.getGenderRestrictions.bind(this);
|
|
this.getUserRights = this.getUserRights.bind(this);
|
|
this.getRooms = this.getRooms.bind(this);
|
|
this.createRoom = this.createRoom.bind(this);
|
|
this.deleteRoom = this.deleteRoom.bind(this);
|
|
|
|
// User administration
|
|
this.searchUsers = this.searchUsers.bind(this);
|
|
this.getUser = this.getUser.bind(this);
|
|
this.getUsers = this.getUsers.bind(this);
|
|
this.updateUser = this.updateUser.bind(this);
|
|
this.resetUserVocabLessonProgress = this.resetUserVocabLessonProgress.bind(this);
|
|
this.markUserVocabLessonsCompleteThrough = this.markUserVocabLessonsCompleteThrough.bind(this);
|
|
this.getUserVocabCourses = this.getUserVocabCourses.bind(this);
|
|
this.getVocabCourseForAdmin = this.getVocabCourseForAdmin.bind(this);
|
|
this.getAdultVerificationRequests = this.getAdultVerificationRequests.bind(this);
|
|
this.setAdultVerificationStatus = this.setAdultVerificationStatus.bind(this);
|
|
this.getAdultVerificationDocument = this.getAdultVerificationDocument.bind(this);
|
|
this.getEroticModerationReports = this.getEroticModerationReports.bind(this);
|
|
this.applyEroticModerationAction = this.applyEroticModerationAction.bind(this);
|
|
this.getEroticModerationPreview = this.getEroticModerationPreview.bind(this);
|
|
|
|
// Rights
|
|
this.listRightTypes = this.listRightTypes.bind(this);
|
|
this.listUserRights = this.listUserRights.bind(this);
|
|
this.addUserRight = this.addUserRight.bind(this);
|
|
this.removeUserRight = this.removeUserRight.bind(this);
|
|
|
|
// Statistics
|
|
this.getUserStatistics = this.getUserStatistics.bind(this);
|
|
this.getFalukantRegions = this.getFalukantRegions.bind(this);
|
|
this.updateFalukantRegionMap = this.updateFalukantRegionMap.bind(this);
|
|
this.getRegionDistances = this.getRegionDistances.bind(this);
|
|
this.upsertRegionDistance = this.upsertRegionDistance.bind(this);
|
|
this.deleteRegionDistance = this.deleteRegionDistance.bind(this);
|
|
this.createNPCs = this.createNPCs.bind(this);
|
|
this.getTitlesOfNobility = this.getTitlesOfNobility.bind(this);
|
|
this.getNPCsCreationStatus = this.getNPCsCreationStatus.bind(this);
|
|
}
|
|
|
|
async getOpenInterests(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const openInterests = await AdminService.getOpenInterests(userId);
|
|
res.status(200).json(openInterests);
|
|
} catch (error) {
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
// --- User Administration ---
|
|
async searchUsers(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { q } = req.query;
|
|
const result = await AdminService.searchUsers(requester, q || '');
|
|
res.status(200).json(result);
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : 500;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getUser(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const result = await AdminService.getUserByHashedId(requester, id);
|
|
res.status(200).json(result);
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : (error.message === 'notfound' ? 404 : 500);
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getUsers(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
let { ids } = req.query;
|
|
if (!ids) {
|
|
return res.status(400).json({ error: 'ids query parameter is required' });
|
|
}
|
|
// Unterstütze sowohl Array-Format (ids[]=...) als auch komma-separierten String (ids=...)
|
|
let hashedIds;
|
|
if (Array.isArray(ids)) {
|
|
hashedIds = ids;
|
|
} else if (typeof ids === 'string') {
|
|
hashedIds = ids.split(',').map(id => id.trim()).filter(id => id.length > 0);
|
|
} else {
|
|
return res.status(400).json({ error: 'ids must be an array or comma-separated string' });
|
|
}
|
|
const result = await AdminService.getUsersByHashedIds(requester, hashedIds);
|
|
res.status(200).json(result);
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : 500;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async updateUser(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const result = await AdminService.updateUser(requester, id, req.body || {});
|
|
res.status(200).json(result);
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : (error.message === 'notfound' ? 404 : 500);
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async resetUserVocabLessonProgress(req, res) {
|
|
const schema = Joi.object({
|
|
lessonId: Joi.number().integer().positive().required()
|
|
});
|
|
const { error, value } = schema.validate(req.body || {});
|
|
if (error) {
|
|
return res.status(400).json({ error: error.details[0].message });
|
|
}
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const result = await AdminService.adminResetUserVocabLessonProgress(requester, id, value.lessonId);
|
|
res.status(200).json(result);
|
|
} catch (err) {
|
|
const status = err.message === 'noaccess' ? 403 : (err.message === 'lessonnotfound' ? 404 : 500);
|
|
res.status(status).json({ error: err.message });
|
|
}
|
|
}
|
|
|
|
async markUserVocabLessonsCompleteThrough(req, res) {
|
|
const schema = Joi.object({
|
|
courseId: Joi.number().integer().positive().required(),
|
|
throughLessonNumber: Joi.number().integer().positive().required()
|
|
});
|
|
const { error, value } = schema.validate(req.body || {});
|
|
if (error) {
|
|
return res.status(400).json({ error: error.details[0].message });
|
|
}
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const result = await AdminService.adminMarkUserVocabLessonsCompleteThrough(
|
|
requester,
|
|
id,
|
|
value.courseId,
|
|
value.throughLessonNumber
|
|
);
|
|
res.status(200).json(result);
|
|
} catch (err) {
|
|
let status = 500;
|
|
if (err.message === 'noaccess') status = 403;
|
|
else if (err.message === 'notenrolled') status = 403;
|
|
else if (err.message === 'badrequest') status = 400;
|
|
res.status(status).json({ error: err.message });
|
|
}
|
|
}
|
|
|
|
async getUserVocabCourses(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const result = await AdminService.adminListUserEnrolledVocabCourses(requester, id);
|
|
res.status(200).json(result);
|
|
} catch (err) {
|
|
const status = err.message === 'noaccess' ? 403 : (err.message === 'notfound' ? 404 : 500);
|
|
res.status(status).json({ error: err.message });
|
|
}
|
|
}
|
|
|
|
async getVocabCourseForAdmin(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { courseId } = req.params;
|
|
const result = await AdminService.adminGetVocabCourseWithLessons(requester, courseId);
|
|
res.status(200).json(result);
|
|
} catch (err) {
|
|
const status = err.message === 'noaccess' ? 403 : (err.message === 'coursenotfound' ? 404 : 500);
|
|
res.status(status).json({ error: err.message });
|
|
}
|
|
}
|
|
|
|
async getAdultVerificationRequests(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { status = 'pending' } = req.query;
|
|
const result = await AdminService.getAdultVerificationRequests(requester, status);
|
|
res.status(200).json(result);
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : 500;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async setAdultVerificationStatus(req, res) {
|
|
const schema = Joi.object({
|
|
status: Joi.string().valid('approved', 'rejected', 'pending').required()
|
|
});
|
|
const { error, value } = schema.validate(req.body || {});
|
|
if (error) {
|
|
return res.status(400).json({ error: error.details[0].message });
|
|
}
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const result = await AdminService.setAdultVerificationStatus(requester, id, value.status);
|
|
res.status(200).json(result);
|
|
} catch (err) {
|
|
const status = err.message === 'noaccess' ? 403 : (['notfound', 'notadult', 'wrongstatus', 'missingparamtype'].includes(err.message) ? 400 : 500);
|
|
res.status(status).json({ error: err.message });
|
|
}
|
|
}
|
|
|
|
async getAdultVerificationDocument(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const result = await AdminService.getAdultVerificationDocument(requester, id);
|
|
res.setHeader('Content-Type', result.mimeType);
|
|
res.setHeader('Content-Disposition', `inline; filename="${encodeURIComponent(result.originalName)}"`);
|
|
res.sendFile(result.filePath);
|
|
} catch (err) {
|
|
const status = err.message === 'noaccess' ? 403 : (['notfound', 'norequest', 'nofile'].includes(err.message) ? 404 : 500);
|
|
res.status(status).json({ error: err.message });
|
|
}
|
|
}
|
|
|
|
async getEroticModerationReports(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { status = 'open' } = req.query;
|
|
const result = await AdminService.getEroticModerationReports(requester, status);
|
|
res.status(200).json(result);
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : 500;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async applyEroticModerationAction(req, res) {
|
|
const schema = Joi.object({
|
|
action: Joi.string().valid('dismiss', 'hide_content', 'restore_content', 'delete_content', 'block_uploads', 'revoke_access').required(),
|
|
note: Joi.string().allow('', null).max(2000).optional()
|
|
});
|
|
const { error, value } = schema.validate(req.body || {});
|
|
if (error) {
|
|
return res.status(400).json({ error: error.details[0].message });
|
|
}
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const result = await AdminService.applyEroticModerationAction(requester, Number(id), value.action, value.note || null);
|
|
res.status(200).json(result);
|
|
} catch (err) {
|
|
const status = err.message === 'noaccess' ? 403 : (['notfound', 'targetnotfound', 'wrongaction'].includes(err.message) ? 400 : 500);
|
|
res.status(status).json({ error: err.message });
|
|
}
|
|
}
|
|
|
|
async getEroticModerationPreview(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { type, targetId } = req.params;
|
|
const result = await AdminService.getEroticModerationPreview(requester, type, Number(targetId));
|
|
res.setHeader('Content-Type', result.mimeType);
|
|
res.setHeader('Content-Disposition', `inline; filename="${encodeURIComponent(result.originalName)}"`);
|
|
res.sendFile(result.filePath);
|
|
} catch (err) {
|
|
const status = err.message === 'noaccess' ? 403 : (['notfound', 'nofile', 'wrongtype'].includes(err.message) ? 404 : 500);
|
|
res.status(status).json({ error: err.message });
|
|
}
|
|
}
|
|
|
|
// --- Rights ---
|
|
async listRightTypes(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const types = await AdminService.listUserRightTypes(requester);
|
|
res.status(200).json(types);
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : 500;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async listUserRights(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const rights = await AdminService.listUserRightsForUser(requester, id);
|
|
res.status(200).json(rights);
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : (error.message === 'notfound' ? 404 : 500);
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async addUserRight(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const { rightTypeId } = req.body || {};
|
|
const result = await AdminService.addUserRight(requester, id, rightTypeId);
|
|
res.status(201).json({ status: 'ok' });
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : (error.message === 'notfound' || error.message === 'wrongtype' ? 404 : 500);
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async removeUserRight(req, res) {
|
|
try {
|
|
const { userid: requester } = req.headers;
|
|
const { id } = req.params;
|
|
const { rightTypeId } = req.body || {};
|
|
await AdminService.removeUserRight(requester, id, rightTypeId);
|
|
res.status(204).send();
|
|
} catch (error) {
|
|
const status = error.message === 'noaccess' ? 403 : (error.message === 'notfound' ? 404 : 500);
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async changeInterest(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { id: interestId, active, adult: adultOnly } = req.body;
|
|
await AdminService.changeInterest(userId, interestId, active, adultOnly);
|
|
const updatedInterests = await AdminService.getOpenInterests(userId);
|
|
res.status(200).json(updatedInterests);
|
|
} catch (error) {
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async deleteInterest(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { id: interestId } = req.params;
|
|
await AdminService.deleteInterest(userId, interestId);
|
|
const updatedInterests = await AdminService.getOpenInterests(userId);
|
|
res.status(200).json(updatedInterests);
|
|
} catch (error) {
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async changeTranslation(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { id: interestId, translations } = req.body;
|
|
await AdminService.changeTranslation(userId, interestId, translations);
|
|
const updatedInterests = await AdminService.getOpenInterests(userId);
|
|
res.status(200).json(updatedInterests);
|
|
} catch (error) {
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getOpenContacts(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const openContacts = await AdminService.getOpenContacts(userId);
|
|
res.status(200).json(openContacts);
|
|
} catch (error) {
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async answerContact(req, res) {
|
|
try {
|
|
const schema = Joi.object({
|
|
id: Joi.number().integer().required(),
|
|
answer: Joi.string().min(1).required(),
|
|
});
|
|
|
|
const { error, value } = schema.validate(req.body);
|
|
|
|
if (error) {
|
|
return res.status(400).json({ error: error.details[0].message });
|
|
}
|
|
|
|
const { id, answer } = value;
|
|
|
|
await AdminService.answerContact(id, answer);
|
|
res.status(200).json({ status: 'ok' });
|
|
} catch (error) {
|
|
console.error('Error in answerContact:', error);
|
|
res.status(error.status || 500).json({ error: error.message || 'Internal Server Error' });
|
|
}
|
|
}
|
|
|
|
async searchUser(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { userName, characterName } = req.body;
|
|
const response = await AdminService.getFalukantUser(userId, userName, characterName);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getFalukantUserById(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { id: hashedId } = req.params;
|
|
const response = await AdminService.getFalukantUserById(userId, hashedId);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async changeFalukantUser(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const data = req.body;
|
|
const { id: falukantUserId, } = req.body;
|
|
const response = await AdminService.changeFalukantUser(userId, falukantUserId, data);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async adminForceFalukantPregnancy(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { characterId, fatherCharacterId, dueInDays } = req.body;
|
|
const response = await AdminService.adminForceFalukantPregnancy(userId, characterId, {
|
|
fatherCharacterId,
|
|
dueInDays,
|
|
});
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(400).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async adminGetPotentialFathersForCharacter(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { characterId } = req.params;
|
|
const response = await AdminService.adminGetPotentialFathersForCharacter(userId, characterId);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(400).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async adminClearFalukantPregnancy(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { characterId } = req.body;
|
|
const response = await AdminService.adminClearFalukantPregnancy(userId, characterId);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(400).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async adminForceFalukantBirth(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { motherCharacterId, fatherCharacterId, birthContext, legitimacy, gender } = req.body;
|
|
const response = await AdminService.adminForceFalukantBirth(userId, motherCharacterId, {
|
|
fatherCharacterId,
|
|
birthContext,
|
|
legitimacy,
|
|
gender,
|
|
});
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(400).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async adminCleanupCharacterDeathArtifacts(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { characterId } = req.params;
|
|
const response = await AdminService.adminCleanupCharacterDeathArtifacts(userId, characterId);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
const status = error.message === 'noaccess'
|
|
? 403
|
|
: (['invalidCharacter', 'notfound'].includes(error.message) ? 400 : 500);
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getFalukantUserBranches(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { falukantUserId } = req.params;
|
|
const response = await AdminService.getFalukantUserBranches(userId, falukantUserId);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async updateFalukantStock(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { stockId } = req.params;
|
|
const { quantity } = req.body;
|
|
const response = await AdminService.updateFalukantStock(userId, stockId, quantity);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async addFalukantStock(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { branchId, stockTypeId, quantity } = req.body;
|
|
const response = await AdminService.addFalukantStock(userId, branchId, stockTypeId, quantity);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getFalukantStockTypes(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const response = await AdminService.getFalukantStockTypes(userId);
|
|
res.status(200).json(response);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(403).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getFalukantRegions(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const regions = await AdminService.getFalukantRegions(userId);
|
|
res.status(200).json(regions);
|
|
} catch (error) {
|
|
console.log(error);
|
|
const status = error.message === 'noaccess' ? 403 : 500;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async updateFalukantRegionMap(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { id } = req.params;
|
|
const { map } = req.body || {};
|
|
const region = await AdminService.updateFalukantRegionMap(userId, id, map);
|
|
res.status(200).json(region);
|
|
} catch (error) {
|
|
console.log(error);
|
|
const status = error.message === 'noaccess' ? 403 : (error.message === 'regionNotFound' ? 404 : 500);
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getRegionDistances(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const distances = await AdminService.getRegionDistances(userId);
|
|
res.status(200).json(distances);
|
|
} catch (error) {
|
|
console.log(error);
|
|
const status = error.message === 'noaccess' ? 403 : 500;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async upsertRegionDistance(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const record = await AdminService.upsertRegionDistance(userId, req.body || {});
|
|
res.status(200).json(record);
|
|
} catch (error) {
|
|
console.log(error);
|
|
const status = error.message === 'noaccess' ? 403 : 400;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async deleteRegionDistance(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { id } = req.params;
|
|
const result = await AdminService.deleteRegionDistance(userId, id);
|
|
res.status(200).json(result);
|
|
} catch (error) {
|
|
console.log(error);
|
|
const status = error.message === 'noaccess' ? 403 : (error.message === 'notfound' ? 404 : 500);
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async createNPCs(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { regionIds, minAge, maxAge, minTitleId, maxTitleId, count } = req.body;
|
|
const countValue = parseInt(count) || 1;
|
|
if (countValue < 1 || countValue > 500) {
|
|
return res.status(400).json({ error: 'Count must be between 1 and 500' });
|
|
}
|
|
console.log('[createNPCs] Request received:', { userId, regionIds, minAge, maxAge, minTitleId, maxTitleId, count: countValue });
|
|
const result = await AdminService.createNPCs(userId, {
|
|
regionIds: regionIds && regionIds.length > 0 ? regionIds : null,
|
|
minAge: parseInt(minAge) || 0,
|
|
maxAge: parseInt(maxAge) || 100,
|
|
minTitleId: parseInt(minTitleId) || 1,
|
|
maxTitleId: parseInt(maxTitleId) || 19,
|
|
count: countValue
|
|
});
|
|
console.log('[createNPCs] Job created:', result);
|
|
res.status(200).json(result);
|
|
} catch (error) {
|
|
console.error('[createNPCs] Error:', error);
|
|
console.error('[createNPCs] Error stack:', error.stack);
|
|
const status = error.message === 'noaccess' ? 403 : 500;
|
|
res.status(status).json({ error: error.message || 'Internal server error' });
|
|
}
|
|
}
|
|
|
|
async getTitlesOfNobility(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const titles = await AdminService.getTitlesOfNobility(userId);
|
|
res.status(200).json(titles);
|
|
} catch (error) {
|
|
console.log(error);
|
|
const status = error.message === 'noaccess' ? 403 : 500;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getNPCsCreationStatus(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const { jobId } = req.params;
|
|
const status = await AdminService.getNPCsCreationStatus(userId, jobId);
|
|
res.status(200).json(status);
|
|
} catch (error) {
|
|
console.log(error);
|
|
const status = error.message === 'noaccess' || error.message === 'Access denied' ? 403 :
|
|
error.message === 'Job not found' ? 404 : 500;
|
|
res.status(status).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async getRoomTypes(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const types = await AdminService.getRoomTypes(userId);
|
|
res.status(200).json(types);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.log(error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async getGenderRestrictions(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const restrictions = await AdminService.getGenderRestrictions(userId);
|
|
res.status(200).json(restrictions);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.log(error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async getUserRights(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const rights = await AdminService.getUserRights(userId);
|
|
res.status(200).json(rights);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.log(error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async getRooms(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const rooms = await AdminService.getRooms(userId);
|
|
res.status(200).json(rooms);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.log(error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async updateRoom(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId || !(await AdminService.hasUserAccess(userId, 'chatrooms'))) {
|
|
return res.status(403).json({ error: 'Keine Berechtigung.' });
|
|
}
|
|
const schema = Joi.object({
|
|
title: Joi.string().min(1).max(255).required(),
|
|
roomTypeId: Joi.number().integer().required(),
|
|
isPublic: Joi.boolean().required(),
|
|
isAdultOnly: Joi.boolean().allow(null),
|
|
genderRestrictionId: Joi.number().integer().allow(null),
|
|
minAge: Joi.number().integer().min(0).allow(null),
|
|
maxAge: Joi.number().integer().min(0).allow(null),
|
|
password: Joi.string().allow('', null),
|
|
friendsOfOwnerOnly: Joi.boolean().allow(null),
|
|
requiredUserRightId: Joi.number().integer().allow(null)
|
|
});
|
|
const { error, value } = schema.validate(req.body);
|
|
if (error) {
|
|
return res.status(400).json({ error: error.details[0].message });
|
|
}
|
|
const room = await AdminService.updateRoom(userId, req.params.id, value);
|
|
res.status(200).json(room);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
|
|
async createRoom(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId || !(await AdminService.hasUserAccess(userId, 'chatrooms'))) {
|
|
return res.status(403).json({ error: 'Keine Berechtigung.' });
|
|
}
|
|
const schema = Joi.object({
|
|
title: Joi.string().min(1).max(255).required(),
|
|
roomTypeId: Joi.number().integer().required(),
|
|
isPublic: Joi.boolean().required(),
|
|
isAdultOnly: Joi.boolean().allow(null),
|
|
genderRestrictionId: Joi.number().integer().allow(null),
|
|
minAge: Joi.number().integer().min(0).allow(null),
|
|
maxAge: Joi.number().integer().min(0).allow(null),
|
|
password: Joi.string().allow('', null),
|
|
friendsOfOwnerOnly: Joi.boolean().allow(null),
|
|
requiredUserRightId: Joi.number().integer().allow(null)
|
|
});
|
|
const { error, value } = schema.validate(req.body);
|
|
if (error) {
|
|
return res.status(400).json({ error: error.details[0].message });
|
|
}
|
|
value.ownerId = parseInt(userId, 10);
|
|
const room = await AdminService.createRoom(userId, value);
|
|
res.status(201).json(room);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
async deleteRoom(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId || !(await AdminService.hasUserAccess(userId, 'chatrooms'))) {
|
|
return res.status(403).json({ error: 'Keine Berechtigung.' });
|
|
}
|
|
await AdminService.deleteRoom(userId, req.params.id);
|
|
res.sendStatus(204);
|
|
} catch (error) {
|
|
console.log(error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
|
|
// --- Match3 Admin Methods ---
|
|
async getMatch3Campaigns(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const campaigns = await AdminService.getMatch3Campaigns(userId);
|
|
res.status(200).json(campaigns);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in getMatch3Campaigns:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async getMatch3Campaign(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const campaign = await AdminService.getMatch3Campaign(userId, req.params.id);
|
|
res.status(200).json(campaign);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in getMatch3Campaign:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async createMatch3Campaign(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const campaign = await AdminService.createMatch3Campaign(userId, req.body);
|
|
res.status(201).json(campaign);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in createMatch3Campaign:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async updateMatch3Campaign(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const campaign = await AdminService.updateMatch3Campaign(userId, req.params.id, req.body);
|
|
res.status(200).json(campaign);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in updateMatch3Campaign:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async deleteMatch3Campaign(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
await AdminService.deleteMatch3Campaign(userId, req.params.id);
|
|
res.sendStatus(204);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in deleteMatch3Campaign:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async getMatch3Levels(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const levels = await AdminService.getMatch3Levels(userId);
|
|
res.status(200).json(levels);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in getMatch3Levels:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async getMatch3Level(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const level = await AdminService.getMatch3Level(userId, req.params.id);
|
|
res.status(200).json(level);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in getMatch3Level:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async createMatch3Level(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const level = await AdminService.createMatch3Level(userId, req.body);
|
|
res.status(201).json(level);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in createMatch3Level:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async updateMatch3Level(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const level = await AdminService.updateMatch3Level(userId, req.params.id, req.body);
|
|
res.status(200).json(level);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in updateMatch3Level:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async deleteMatch3Level(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
await AdminService.deleteMatch3Level(userId, req.params.id);
|
|
res.sendStatus(204);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in deleteMatch3Level:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
// Match3 Objectives
|
|
async getMatch3Objectives(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const objectives = await AdminService.getMatch3Objectives(userId);
|
|
res.status(200).json(objectives);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in getMatch3Objectives:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async getMatch3Objective(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const objective = await AdminService.getMatch3Objective(userId, req.params.id);
|
|
res.status(200).json(objective);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in getMatch3Objective:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async createMatch3Objective(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const objective = await AdminService.createMatch3Objective(userId, req.body);
|
|
res.status(201).json(objective);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in createMatch3Objective:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async updateMatch3Objective(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const objective = await AdminService.updateMatch3Objective(userId, req.params.id, req.body);
|
|
res.status(200).json(objective);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in updateMatch3Objective:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async deleteMatch3Objective(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
await AdminService.deleteMatch3Objective(userId, req.params.id);
|
|
res.sendStatus(204);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in deleteMatch3Objective:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async getMatch3TileTypes(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const tileTypes = await AdminService.getMatch3TileTypes(userId);
|
|
res.status(200).json(tileTypes);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in getMatch3TileTypes:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async createMatch3TileType(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const tileType = await AdminService.createMatch3TileType(userId, req.body);
|
|
res.status(201).json(tileType);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in createMatch3TileType:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async updateMatch3TileType(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
const tileType = await AdminService.updateMatch3TileType(userId, req.params.id, req.body);
|
|
res.status(200).json(tileType);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in updateMatch3TileType:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async deleteMatch3TileType(req, res) {
|
|
try {
|
|
const userId = req.headers.userid;
|
|
if (!userId) {
|
|
return res.status(401).json({ error: 'User ID fehlt' });
|
|
}
|
|
await AdminService.deleteMatch3TileType(userId, req.params.id);
|
|
res.sendStatus(204);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
|
|
} else {
|
|
console.error('Error in deleteMatch3TileType:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async getUserStatistics(req, res) {
|
|
try {
|
|
const { userid: userId } = req.headers;
|
|
const statistics = await AdminService.getUserStatistics(userId);
|
|
res.status(200).json(statistics);
|
|
} catch (error) {
|
|
if (error.message === 'noaccess') {
|
|
res.status(403).json({ error: 'Keine Berechtigung' });
|
|
} else {
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export default AdminController;
|