Skip to content

Commit a6ce086

Browse files
committed
Audit
1 parent 4722339 commit a6ce086

File tree

2 files changed

+32
-10
lines changed

2 files changed

+32
-10
lines changed

apps/meteor/app/api/server/v1/users.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { Match, check } from 'meteor/check';
2525
import { Meteor } from 'meteor/meteor';
2626
import type { Filter } from 'mongodb';
2727

28+
import { UserChangedAuditStore } from '../../../../server/lib/auditServerEvents/userChanged';
2829
import { i18n } from '../../../../server/lib/i18n';
2930
import { resetUserE2EEncriptionKey } from '../../../../server/lib/resetUserE2EKey';
3031
import { sendWelcomeEmail } from '../../../../server/lib/sendWelcomeEmail';
@@ -101,10 +102,17 @@ API.v1.addRoute(
101102
if (userData.name && !validateNameChars(userData.name)) {
102103
return API.v1.failure('Name contains invalid characters');
103104
}
105+
const auditStore = new UserChangedAuditStore({
106+
_id: this.bodyParams.userId,
107+
ip: this.requestIp,
108+
useragent: this.request.headers['user-agent'] || '',
109+
username: (await Meteor.userAsync())?.username || '',
110+
});
104111

105-
const updater = Users.getUpdater();
106-
await saveUser(this.userId, userData, updater);
112+
const _updater = Users.getUpdater();
113+
await saveUser(this.userId, userData, { _updater, auditStore });
107114

115+
// Waiting for customfields refactor to be merged, then this will be audited within saveUser function
108116
if (this.bodyParams.data.customFields) {
109117
await saveCustomFields(this.bodyParams.userId, this.bodyParams.data.customFields);
110118
}
@@ -117,7 +125,20 @@ API.v1.addRoute(
117125
} = this.bodyParams;
118126

119127
await Meteor.callAsync('setUserActiveStatus', userId, active, Boolean(confirmRelinquish));
128+
// This has no other use than for auditing active status changes
129+
// 'setUserActiveStatus' has a lot of side effects making it difficult to use updater
130+
// This updater should have been already commited by this point
131+
_updater.set('active', active);
132+
}
133+
134+
if (this.bodyParams.data.password || this.bodyParams.data.setRandomPassword) {
135+
// Password is also not tracker by updater
136+
_updater.set('services', { password: {} });
120137
}
138+
139+
auditStore.setUpdateFilter(_updater._getUpdateFilter());
140+
void auditStore.commitAuditEvent();
141+
121142
const { fields } = await this.parseJsonQuery();
122143

123144
const user = await Users.findOneById(this.bodyParams.userId, { projection: fields });

apps/meteor/app/lib/server/functions/saveUser/saveUser.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { saveNewUser } from './saveNewUser';
2121
import { sendPasswordEmail } from './sendUserEmail';
2222
import { validateUserData } from './validateUserData';
2323
import { validateUserEditing } from './validateUserEditing';
24-
import { asyncLocalStorage } from '../../../../../server/lib/auditServerEvents/userChanged';
24+
import type { UserChangedAuditStore } from '../../../../../server/lib/auditServerEvents/userChanged';
2525

2626
export type SaveUserData = {
2727
_id?: IUser['_id'];
@@ -50,7 +50,12 @@ export type SaveUserData = {
5050
export type UpdateUserData = RequiredField<SaveUserData, '_id'>;
5151
export const isUpdateUserData = (params: SaveUserData): params is UpdateUserData => '_id' in params && !!params._id;
5252

53-
export const saveUser = async function (userId: IUser['_id'], userData: SaveUserData, _updater?: Updater<IUser>) {
53+
type SaveUserOptions = {
54+
_updater?: Updater<IUser>;
55+
auditStore?: UserChangedAuditStore;
56+
};
57+
58+
export const saveUser = async function (userId: IUser['_id'], userData: SaveUserData, options?: SaveUserOptions) {
5459
const oldUserData = userData._id && (await Users.findOneById(userData._id));
5560
if (oldUserData && isUserFederated(oldUserData)) {
5661
throw new Meteor.Error('Edit_Federated_User_Not_Allowed', 'Not possible to edit a federated user');
@@ -80,13 +85,12 @@ export const saveUser = async function (userId: IUser['_id'], userData: SaveUser
8085
return saveNewUser(userData, sendPassword);
8186
}
8287

83-
const store = asyncLocalStorage.getStore();
84-
store?.setOriginalUser(oldUserData);
88+
options?.auditStore?.setOriginalUser(oldUserData);
8589

8690
await validateUserEditing(userId, userData);
8791

8892
// update user
89-
const updater = _updater || Users.getUpdater();
93+
const updater = options?._updater || Users.getUpdater();
9094

9195
if (userData.hasOwnProperty('username') || userData.hasOwnProperty('name')) {
9296
if (
@@ -152,9 +156,6 @@ export const saveUser = async function (userId: IUser['_id'], userData: SaveUser
152156

153157
// App IPostUserUpdated event hook
154158
const userUpdated = await Users.findOneById(userData._id);
155-
if (userUpdated) {
156-
store?.setCurrentUser(userUpdated);
157-
}
158159

159160
await callbacks.run('afterSaveUser', {
160161
user: userUpdated,

0 commit comments

Comments
 (0)