Skip to content

Commit

Permalink
Update user service to check for existing email and username (#247)
Browse files Browse the repository at this point in the history
* Update user service to check for existing email and username

* Refactor insertUserSchema to handle empty strings as null values
  • Loading branch information
diegoalzate authored Mar 7, 2024
1 parent 81443e5 commit 160d382
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 25 deletions.
74 changes: 53 additions & 21 deletions src/services/users.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
import * as db from '../db';
import type { Request, Response } from 'express';
import { eq } from 'drizzle-orm';
import { and, eq, ne, or } from 'drizzle-orm';
import { insertUserSchema } from '../types/users';
import { overwriteUsersToGroups } from './usersToGroups';
import { upsertUserAttributes } from './userAttributes';
Expand Down Expand Up @@ -77,25 +77,57 @@ export function updateUser(dbPool: PostgresJsDatabase<typeof db>) {
}

// update user
const user = await dbPool
.update(db.users)
.set({
email: body.data.email,
username: body.data.username,
name: body.data.name,
updatedAt: new Date(),
})
.where(eq(db.users.id, userId))
.returning();

const updatedGroups = await overwriteUsersToGroups(dbPool, userId, body.data.groupIds);

const updatedUserAttributes = await upsertUserAttributes(
dbPool,
userId,
body.data.userAttributes,
);

return res.json({ data: { user, updatedGroups, updatedUserAttributes } });
try {
// check if username or email already exists and is not the current user
if (body.data.email || body.data.username) {
const existingUser = await dbPool
.select()
.from(db.users)
.where(
or(
and(eq(db.users.email, body.data.email ?? ''), ne(db.users.id, userId)),
and(eq(db.users.username, body.data.username ?? ''), ne(db.users.id, userId)),
),
);

if (existingUser.length > 0) {
const errors = [];

if (existingUser[0]?.email === body.data.email) {
errors.push('Email already exists');
}

if (existingUser[0]?.username === body.data.username) {
errors.push('Username already exists');
}

return res.status(400).json({ errors });
}
}

const user = await dbPool
.update(db.users)
.set({
email: body.data.email,
username: body.data.username,
name: body.data.name,
updatedAt: new Date(),
})
.where(eq(db.users.id, userId))
.returning();

const updatedGroups = await overwriteUsersToGroups(dbPool, userId, body.data.groupIds);

const updatedUserAttributes = await upsertUserAttributes(
dbPool,
userId,
body.data.userAttributes,
);

return res.json({ data: { user, updatedGroups, updatedUserAttributes } });
} catch (e) {
console.error(`[ERROR] ${JSON.stringify(e)}`);
return res.sendStatus(500);
}
};
}
18 changes: 14 additions & 4 deletions src/types/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@ import { users } from '../db';
export const groupIdsSchema = z.string().array();
export const userAttributesSchema = z.record(z.string());

export const insertUserSchema = createInsertSchema(users).extend({
groupIds: groupIdsSchema,
userAttributes: userAttributesSchema,
});
export const insertUserSchema = createInsertSchema(users)
.extend({
groupIds: groupIdsSchema,
userAttributes: userAttributesSchema,
})
.transform((data) => {
// make empty strings null
return {
...data,
email: data.email || null,
username: data.username || null,
name: data.name || null,
};
});

0 comments on commit 160d382

Please sign in to comment.