mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -104,6 +104,46 @@ exports.getActiveAdvertisement = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
// ─── GET ACTIVE (list) ──────────────────────────────────────────────────────
|
||||
//
|
||||
// Resolves every live advertisement for a single placement, ordered by
|
||||
// priority — used by carousel-style slots (e.g. dashboard.hero) that rotate
|
||||
// through several ads instead of showing only the single highest-priority one.
|
||||
//
|
||||
// GET /api/client/advertisements/active-list?placement=dashboard.hero&limit=8
|
||||
//
|
||||
exports.getActiveAdvertisementList = async (req, res) => {
|
||||
try {
|
||||
const { placement } = req.query;
|
||||
|
||||
if (!placement) return R.error(res, "placement is required.", 400);
|
||||
if (!PLACEMENT_MAP[placement]) return R.error(res, "Invalid placement.", 400);
|
||||
|
||||
const limit = Math.min(Math.max(parseInt(req.query.limit, 10) || 8, 1), 20);
|
||||
|
||||
const advertisements = await Advertisement.findAll({
|
||||
where: liveWhere({ placement }),
|
||||
order: [["order", "ASC"], ["createdAt", "DESC"]],
|
||||
include: [AD_IMAGE_INCLUDE],
|
||||
attributes: { exclude: AD_CLIENT_EXCLUDE },
|
||||
limit,
|
||||
});
|
||||
|
||||
const data = [];
|
||||
for (const ad of advertisements) {
|
||||
const json = ad.toJSON();
|
||||
json.status = deriveStatus(json);
|
||||
if (json.image) await attachImageStreamToken(json.image, req);
|
||||
data.push(json);
|
||||
}
|
||||
|
||||
return R.success(res, "Active advertisements retrieved.", { data });
|
||||
} catch (err) {
|
||||
console.error("[CLIENT][ADVERTISEMENT][GET ACTIVE LIST]", err);
|
||||
return R.error(res, "Could not retrieve advertisements.", 500);
|
||||
}
|
||||
};
|
||||
|
||||
// ─── GET ACTIVE (batch) ─────────────────────────────────────────────────────
|
||||
//
|
||||
// Resolves the highest-priority live advertisement for each of several
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
const mdl_Users = require('../../models/users/users.mdl');
|
||||
const mdl_UserSessions = require('../../models/users/user_sessions.mdl');
|
||||
const mdl_Achievements = require('../../models/users/achievements.mdl');
|
||||
const trustedDevice = require('../../services/trustedDevice.service');
|
||||
const logActivity = require('../../utils/logActivity.util');
|
||||
const R = require('../../utils/response.util');
|
||||
const { uploadFile, deleteFile } = require('../../services/s3.service');
|
||||
@@ -94,6 +95,7 @@ exports.revokeSession = async (req, res) => {
|
||||
is_active: false,
|
||||
logout_info: { date: new Date().toISOString(), ip_address: req.ip },
|
||||
});
|
||||
await trustedDevice.revokeBySessionId(session.session_id);
|
||||
|
||||
logActivity(req.user.user_id, 'revoke_session', { entityType: 'session', entityId: session.session_id });
|
||||
|
||||
@@ -177,6 +179,7 @@ exports.deleteAccount = async (req, res) => {
|
||||
{ is_active: false, logout_info: { date: new Date().toISOString(), ip_address: req.ip, reason: 'account_deleted' } },
|
||||
{ where: { user_id: req.user.user_id, is_active: true } },
|
||||
);
|
||||
await trustedDevice.revokeAllForUser(req.user.user_id);
|
||||
|
||||
// Anonymize email before soft-delete so the unique slot is freed for re-registration
|
||||
await user.update({ email: `deleted_${req.user.user_id}@deleted.invalid`, deletedBy: req.user.user_id });
|
||||
|
||||
Reference in New Issue
Block a user