Skip to content

Commit

Permalink
Use explicit field value masking on delete user
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikearaya committed Nov 23, 2024
1 parent 804c3e6 commit 43552e8
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 53 deletions.
23 changes: 7 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Context } from '../../../types.js';
import { log } from '@unchainedshop/logger';
import { InvalidIdError, UserNotFoundError } from '../../../errors.js';
import { Context } from '../../../context.js';

export default async function deleteUserProductReviews(
root: never,
Expand Down
2 changes: 1 addition & 1 deletion packages/api/src/resolvers/mutations/users/deleteUser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { log } from '@unchainedshop/logger';
import { Context } from '../../../types.js';
import { InvalidIdError, UserNotFoundError } from '../../../errors.js';
import { Context } from '../../../context.js';

const deleteUser = async (_, { userId }, context: Context) => {
const { modules, userAgent, userId: currentUserId } = context;
Expand Down
57 changes: 22 additions & 35 deletions packages/core-users/src/module/configureUsersModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,29 @@ import { userSettings, UserSettingsOptions } from '../users-settings.js';
import { configureUsersWebAuthnModule, UsersWebAuthnModule } from './configureUsersWebAuthnModule.js';
import * as pbkdf2 from './pbkdf2.js';
import * as sha256 from './sha256.js';
import type { Address, Contact } from '@unchainedshop/mongodb';
import crypto from 'crypto';
import { UnchainedCore } from '@unchainedshop/core';
import { UserServices } from '../users-index.js';
import { FileServices, FilesModule } from '@unchainedshop/core-files';
import { Context } from 'vm';

const isDate = (value) => {
const date = new Date(value);
return !Number.isNaN(date.getTime());
};

function maskString(value) {
if (isDate(value)) return value;
return crypto
.createHash('sha256')
.update(JSON.stringify([value, new Date().getTime()]))
.digest('hex');
}

const maskUserPropertyValues = (user) => {
if (typeof user !== 'object' || user === null) {
return user;
const maskUserPropertyValues = (user, deletedById: string): User => {
if (!user || typeof user !== 'object') {
throw new Error('Invalid user object');
}
if (Array.isArray(user)) {
return user.map((item) => maskUserPropertyValues(item));
}
const maskedUser = {};
Object.keys(user).forEach((key) => {
if (typeof user[key] === 'string' || isDate(user[key])) {
maskedUser[key] = maskString(user[key]);
} else {
maskedUser[key] = maskUserPropertyValues(user[key]);
}
});

return maskedUser;
return {
...user,
username: `deleted-${Date.now()}`,
deleted: new Date(),
deletedBy: deletedById,
emails: null,
roles: null,
profile: null,
lastBillingAddress: {},
services: {},
pushSubscriptions: [],
avatarId: null,
initialPassword: null,
lastContact: null,
};
};

export type UsersModule = {
Expand Down Expand Up @@ -147,6 +134,7 @@ const USER_EVENTS = [
'USER_UPDATE_BILLING_ADDRESS',
'USER_UPDATE_LAST_CONTACT',
'USER_REMOVE',
'USER_PURGE',
];
export const removeConfidentialServiceHashes = (rawUser: User): User => {
const user = rawUser;
Expand Down Expand Up @@ -848,11 +836,10 @@ export const configureUsersModule = async ({
{},
);
},
deleteUser: async ({ userId }, context) => {
deleteUser: async ({ userId }, context: Context) => {
const { modules } = context;
const { _id, ...user } = await findUserById(userId);
delete user?.services;
const maskedUserData = maskUserPropertyValues({ ...user, meta: null });
const maskedUserData = maskUserPropertyValues(user, context.userId);
await modules.bookmarks.deleteByUserId(userId);
await updateUser({ _id }, { $set: { ...maskedUserData, deleted: new Date() } }, {});
return true;
Expand Down
1 change: 1 addition & 0 deletions packages/core-users/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export type User = {
pushSubscriptions: Array<PushSubscriptionObject>;
username?: string;
meta?: any;
deletedBy?: string;
} & TimestampFields;

export type UserQuery = mongodb.Filter<User> & {
Expand Down

0 comments on commit 43552e8

Please sign in to comment.