|
1 | 1 | 'use strict'; |
2 | 2 |
|
3 | 3 | const { v4: uuidv4 } = require('uuid'); |
4 | | -const invariant = require('tiny-invariant'); |
5 | 4 |
|
6 | 5 | const { userTable, passwordTable, profileTable } = require('../../schema/schema'); |
7 | 6 | const { db } = require('../drizzle'); |
8 | | -const { createProfile } = require('../profile/profile'); |
9 | 7 | const { eq } = require('drizzle-orm'); |
10 | 8 | const ModelError = require('../modelError'); |
11 | 9 | const { checkPassword, validatePassword, passwordHasher } = require('../password/utils'); |
12 | 10 | const IsEmail = require('isemail'); |
| 11 | +const { validateField } = require('../utils/validation'); |
13 | 12 |
|
14 | 13 | const userNameRequirementsText = 'Parameter name must consist of at least 3 and up to 40 alphanumerics (a-zA-Z0-9), dot (.), dash (-), underscore (_) and spaces.'; |
15 | 14 | const nameValidRegex = |
16 | 15 | /^[^~`!@#$%^&*()+=£€{}[\]|\\:;"'<>,?/\n\r\t\s][^~`!@#$%^&*()+=£€{}[\]|\\:;"'<>,?/\n\r\t]{1,39}[^~`!@#$%^&*()+=£€{}[\]|\\:;"'<>,?/\n\r\t\s]$/; |
17 | 16 |
|
18 | | -const validateField = function validateField (field, expr, msg) { |
19 | | - try { |
20 | | - invariant(expr, msg); |
21 | | - } catch (error) { |
22 | | - const err = new Error(msg); |
23 | | - err.name = 'ValidationError'; |
24 | | - err.errors = { |
25 | | - [field]: { message: msg } |
26 | | - }; |
27 | | - throw err; |
28 | | - } |
29 | | -}; |
30 | | - |
31 | 17 | const findUserByNameOrEmail = async function findUserByNameOrEmail ( |
32 | 18 | emailOrName |
33 | 19 | ) { |
@@ -69,30 +55,44 @@ const createUser = async function createUser (name, email, password, language) { |
69 | 55 |
|
70 | 56 | const hashedPassword = await passwordHasher(password); |
71 | 57 |
|
72 | | - const user = await db.transaction(async (tx) => { |
73 | | - const user = await tx |
74 | | - .insert(userTable) |
75 | | - .values({ name, email, language }) |
76 | | - .returning(); |
77 | | - |
78 | | - await tx.insert(passwordTable).values({ |
79 | | - hash: hashedPassword, |
80 | | - userId: user[0].id |
81 | | - }); |
82 | | - |
83 | | - await tx.insert(profileTable).values({ |
84 | | - username: name, |
85 | | - public: false, |
86 | | - userId: user[0].id |
| 58 | + try { |
| 59 | + const user = await db.transaction(async (tx) => { |
| 60 | + const user = await tx |
| 61 | + .insert(userTable) |
| 62 | + .values({ name, email, language }) |
| 63 | + .returning(); |
| 64 | + |
| 65 | + await tx.insert(passwordTable).values({ |
| 66 | + hash: hashedPassword, |
| 67 | + userId: user[0].id |
| 68 | + }); |
| 69 | + |
| 70 | + await tx.insert(profileTable).values({ |
| 71 | + username: name, |
| 72 | + public: false, |
| 73 | + userId: user[0].id |
| 74 | + }); |
| 75 | + |
| 76 | + return user[0]; |
87 | 77 | }); |
88 | 78 |
|
89 | | - return user[0]; |
90 | | - }); |
91 | | - |
92 | | - // Delete not needed properties |
93 | | - delete user.emailConfirmationToken; |
| 79 | + // Delete not needed properties |
| 80 | + delete user.emailConfirmationToken; |
94 | 81 |
|
95 | | - return user; |
| 82 | + return user; |
| 83 | + } catch (error) { |
| 84 | + // Catch and transform database errors |
| 85 | + console.log(error); |
| 86 | + /** |
| 87 | + * { |
| 88 | + "code": "BadRequest", |
| 89 | + "message": "Duplicate user detected" |
| 90 | + } |
| 91 | + */ |
| 92 | + if (error.code === '23505') { |
| 93 | + throw new ModelError('Duplicate user detected', { type: 'BadRequest' }); |
| 94 | + } |
| 95 | + } |
96 | 96 | }; |
97 | 97 |
|
98 | 98 | const destroyUser = async function destroyUser (user) { |
|
0 commit comments