mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-03-03 19:11:22 +01:00
@@ -107,10 +107,10 @@
|
|||||||
"nodebb-plugin-spam-be-gone": "2.3.2",
|
"nodebb-plugin-spam-be-gone": "2.3.2",
|
||||||
"nodebb-plugin-web-push": "0.7.6",
|
"nodebb-plugin-web-push": "0.7.6",
|
||||||
"nodebb-rewards-essentials": "1.0.2",
|
"nodebb-rewards-essentials": "1.0.2",
|
||||||
"nodebb-theme-harmony": "2.2.15",
|
"nodebb-theme-harmony": "2.2.16",
|
||||||
"nodebb-theme-lavender": "7.1.21",
|
"nodebb-theme-lavender": "7.1.21",
|
||||||
"nodebb-theme-peace": "2.2.51",
|
"nodebb-theme-peace": "2.2.51",
|
||||||
"nodebb-theme-persona": "14.2.9",
|
"nodebb-theme-persona": "14.2.10",
|
||||||
"nodebb-widget-essentials": "7.0.42",
|
"nodebb-widget-essentials": "7.0.42",
|
||||||
"nodemailer": "8.0.1",
|
"nodemailer": "8.0.1",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
|
|||||||
@@ -194,6 +194,7 @@
|
|||||||
"sso.dissociate-confirm-title": "Confirm Dissociation",
|
"sso.dissociate-confirm-title": "Confirm Dissociation",
|
||||||
"sso.dissociate-confirm": "Are you sure you wish to dissociate your account from %1?",
|
"sso.dissociate-confirm": "Are you sure you wish to dissociate your account from %1?",
|
||||||
|
|
||||||
|
"info.invited-by": "Invited by",
|
||||||
"info.latest-flags": "Latest Flags",
|
"info.latest-flags": "Latest Flags",
|
||||||
"info.profile": "Profile",
|
"info.profile": "Profile",
|
||||||
"info.post": "Post",
|
"info.post": "Post",
|
||||||
|
|||||||
@@ -20,6 +20,23 @@ get:
|
|||||||
- $ref: ../../../components/schemas/UserObject.yaml#/UserObjectFull
|
- $ref: ../../../components/schemas/UserObject.yaml#/UserObjectFull
|
||||||
- type: object
|
- type: object
|
||||||
properties:
|
properties:
|
||||||
|
invitedBy:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
properties:
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
userslug:
|
||||||
|
type: string
|
||||||
|
picture:
|
||||||
|
type: string
|
||||||
|
uid:
|
||||||
|
type: number
|
||||||
|
icon:text:
|
||||||
|
type: string
|
||||||
|
icon:bgColor:
|
||||||
|
type: string
|
||||||
|
|
||||||
history:
|
history:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|||||||
@@ -11,6 +11,14 @@ define('forum/account/info', ['forum/account/header', 'alerts', 'forum/account/s
|
|||||||
};
|
};
|
||||||
|
|
||||||
function handleModerationNote() {
|
function handleModerationNote() {
|
||||||
|
const noteList = $('[component="account/moderation-note/list"]');
|
||||||
|
|
||||||
|
function adjustTextareaHeight(textarea) {
|
||||||
|
textarea.css({
|
||||||
|
height: textarea.prop('scrollHeight') + 'px',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
$('[component="account/save-moderation-note"]').on('click', function () {
|
$('[component="account/save-moderation-note"]').on('click', function () {
|
||||||
const noteEl = $('[component="account/moderation-note"]');
|
const noteEl = $('[component="account/moderation-note"]');
|
||||||
const note = noteEl.val();
|
const note = noteEl.val();
|
||||||
@@ -24,23 +32,24 @@ define('forum/account/info', ['forum/account/header', 'alerts', 'forum/account/s
|
|||||||
noteEl.val('');
|
noteEl.val('');
|
||||||
|
|
||||||
app.parseAndTranslate('account/info', 'moderationNotes', { moderationNotes: notes }, function (html) {
|
app.parseAndTranslate('account/info', 'moderationNotes', { moderationNotes: notes }, function (html) {
|
||||||
$('[component="account/moderation-note/list"]').prepend(html);
|
noteList.prepend(html);
|
||||||
html.find('.timeago').timeago();
|
html.find('.timeago').timeago();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
$('[component="account/moderation-note/edit"]').on('click', function () {
|
noteList.on('click', '[component="account/moderation-note/edit"]', function () {
|
||||||
const parent = $(this).parents('[data-id]');
|
const parent = $(this).parents('[data-id]');
|
||||||
const contentArea = parent.find('[component="account/moderation-note/content-area"]');
|
const contentArea = parent.find('[component="account/moderation-note/content-area"]');
|
||||||
const editArea = parent.find('[component="account/moderation-note/edit-area"]');
|
const editArea = parent.find('[component="account/moderation-note/edit-area"]');
|
||||||
contentArea.addClass('hidden');
|
contentArea.addClass('hidden');
|
||||||
editArea.removeClass('hidden');
|
editArea.removeClass('hidden');
|
||||||
|
adjustTextareaHeight(editArea.find('textarea'));
|
||||||
editArea.find('textarea').trigger('focus').putCursorAtEnd();
|
editArea.find('textarea').trigger('focus').putCursorAtEnd();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('[component="account/moderation-note/save-edit"]').on('click', function () {
|
noteList.on('click', '[component="account/moderation-note/save-edit"]', function () {
|
||||||
const parent = $(this).parents('[data-id]');
|
const parent = $(this).parents('[data-id]');
|
||||||
const contentArea = parent.find('[component="account/moderation-note/content-area"]');
|
const contentArea = parent.find('[component="account/moderation-note/content-area"]');
|
||||||
const editArea = parent.find('[component="account/moderation-note/edit-area"]');
|
const editArea = parent.find('[component="account/moderation-note/edit-area"]');
|
||||||
@@ -63,20 +72,13 @@ define('forum/account/info', ['forum/account/header', 'alerts', 'forum/account/s
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('[component="account/moderation-note/cancel-edit"]').on('click', function () {
|
noteList.on('click', '[component="account/moderation-note/cancel-edit"]', function () {
|
||||||
const parent = $(this).parents('[data-id]');
|
const parent = $(this).parents('[data-id]');
|
||||||
const contentArea = parent.find('[component="account/moderation-note/content-area"]');
|
const contentArea = parent.find('[component="account/moderation-note/content-area"]');
|
||||||
const editArea = parent.find('[component="account/moderation-note/edit-area"]');
|
const editArea = parent.find('[component="account/moderation-note/edit-area"]');
|
||||||
contentArea.removeClass('hidden');
|
contentArea.removeClass('hidden');
|
||||||
editArea.addClass('hidden');
|
editArea.addClass('hidden');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('[component="account/moderation-note/edit-area"] textarea').each((i, el) => {
|
|
||||||
const $el = $(el);
|
|
||||||
$el.css({
|
|
||||||
height: $el.prop('scrollHeight') + 'px',
|
|
||||||
}).parent().addClass('hidden');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Info;
|
return Info;
|
||||||
|
|||||||
@@ -15,12 +15,13 @@ infoController.get = async function (req, res) {
|
|||||||
|
|
||||||
const payload = res.locals.userData;
|
const payload = res.locals.userData;
|
||||||
const { username, userslug } = payload;
|
const { username, userslug } = payload;
|
||||||
const [isPrivileged, history, sessions, usernames, emails] = await Promise.all([
|
const [isPrivileged, history, sessions, usernames, emails, invitedBy] = await Promise.all([
|
||||||
user.isPrivileged(req.uid),
|
user.isPrivileged(req.uid),
|
||||||
user.getModerationHistory(res.locals.uid),
|
user.getModerationHistory(res.locals.uid),
|
||||||
user.auth.getSessions(res.locals.uid, req.sessionID),
|
user.auth.getSessions(res.locals.uid, req.sessionID),
|
||||||
user.getHistory(`user:${res.locals.uid}:usernames`),
|
user.getHistory(`user:${res.locals.uid}:usernames`),
|
||||||
user.getHistory(`user:${res.locals.uid}:emails`),
|
user.getHistory(`user:${res.locals.uid}:emails`),
|
||||||
|
getInvitedBy(res.locals.uid),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const notes = await getNotes({ uid: res.locals.uid, isPrivileged }, start, stop);
|
const notes = await getNotes({ uid: res.locals.uid, isPrivileged }, start, stop);
|
||||||
@@ -29,6 +30,7 @@ infoController.get = async function (req, res) {
|
|||||||
payload.sessions = sessions;
|
payload.sessions = sessions;
|
||||||
payload.usernames = usernames;
|
payload.usernames = usernames;
|
||||||
payload.emails = emails;
|
payload.emails = emails;
|
||||||
|
payload.invitedBy = invitedBy;
|
||||||
|
|
||||||
if (isPrivileged) {
|
if (isPrivileged) {
|
||||||
payload.moderationNotes = notes.notes;
|
payload.moderationNotes = notes.notes;
|
||||||
@@ -51,3 +53,12 @@ async function getNotes({ uid, isPrivileged }, start, stop) {
|
|||||||
]);
|
]);
|
||||||
return { notes: notes, count: count };
|
return { notes: notes, count: count };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getInvitedBy(uid) {
|
||||||
|
const invitedBy = await user.getUserField(uid, 'invitedBy');
|
||||||
|
if (!invitedBy) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const inviterData = await user.getUserFields(invitedBy, ['uid', 'username', 'userslug', 'picture']);
|
||||||
|
return inviterData.userslug ? inviterData : null;
|
||||||
|
};
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ async function registerAndLoginUser(req, res, userData) {
|
|||||||
await Promise.all([
|
await Promise.all([
|
||||||
user.confirmIfInviteEmailIsUsed(userData.token, userData.email, uid),
|
user.confirmIfInviteEmailIsUsed(userData.token, userData.email, uid),
|
||||||
user.joinGroupsFromInvitation(uid, userData.token),
|
user.joinGroupsFromInvitation(uid, userData.token),
|
||||||
|
user.setInviterUid(uid, userData.token),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
await user.deleteInvitationKey(userData.email, userData.token);
|
await user.deleteInvitationKey(userData.email, userData.token);
|
||||||
|
|||||||
@@ -83,6 +83,16 @@ module.exports = function (User) {
|
|||||||
return await db.getObjectField(`invitation:token:${token}`, 'email');
|
return await db.getObjectField(`invitation:token:${token}`, 'email');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
User.setInviterUid = async function (uid, token) {
|
||||||
|
if (!token) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const inviterUid = await db.getObjectField(`invitation:token:${token}`, 'inviter');
|
||||||
|
if (inviterUid) {
|
||||||
|
await User.setUserField(uid, 'invitedBy', inviterUid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
User.confirmIfInviteEmailIsUsed = async function (token, enteredEmail, uid) {
|
User.confirmIfInviteEmailIsUsed = async function (token, enteredEmail, uid) {
|
||||||
if (!enteredEmail) {
|
if (!enteredEmail) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user