All checks were successful
Deploy to production / deploy (push) Successful in 2m59s
- Implemented `getUserVocabCourses` and `getVocabCourseForAdmin` methods in `AdminController` to allow admins to retrieve enrolled vocab courses for users and specific course details, respectively. - Updated `adminRouter` to include new routes for accessing user vocab courses and course details. - Enhanced `AdminService` with methods to list user-enrolled vocab courses and retrieve course information with lessons, ensuring proper access control. - Improved `VocabService` to support the new functionalities, including attaching language names to course data. - Updated UI components in `UsersView` to reflect changes, including error handling and loading states for course retrieval, along with localization updates for new features.
1155 lines
46 KiB
JavaScript
1155 lines
46 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.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.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 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 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;
|