diff --git a/configs/properties.ts b/configs/properties.ts
index e3b2c78..8d6a963 100644
--- a/configs/properties.ts
+++ b/configs/properties.ts
@@ -12,7 +12,11 @@ export const FOOTER_LINKS = [
];
export const MIN_USER_NAME_LENGTH = 3;
+export const MAX_USER_NAME_LENGTH = 100;
+export const MAX_USER_DESCRIPTION_LENGTH = 500;
+export const MAX_USER_ADDRESS_LENGTH = 100;
export const MAX_USER_SOCIALS = 4;
+export const MAX_USER_SOCIAL_LENGTH = 100;
export const MAX_USER_AVATAR_SIZE = 3 * 1024 * 1024;
export const USER_AVATAR_FILE_TYPES = 'image/*' as const;
diff --git a/pages/profile/index.vue b/pages/profile/index.vue
index 00797e8..3ea0d9e 100644
--- a/pages/profile/index.vue
+++ b/pages/profile/index.vue
@@ -13,9 +13,11 @@
@@ -26,7 +28,9 @@
>
@@ -37,7 +41,9 @@
>
@@ -82,6 +88,8 @@
:model-value="model.socials[idx]"
:rules="socialRules"
:label="`social #${social}`"
+ :maxlength="MAX_USER_SOCIAL_LENGTH"
+ counter
@update:model-value="changeSocial(idx, $event)"
/>
@@ -106,7 +114,11 @@
import { cloneDeep, isEqual, isUndefined, omit } from 'lodash-es';
import {
MIN_USER_NAME_LENGTH,
+ MAX_USER_NAME_LENGTH,
+ MAX_USER_DESCRIPTION_LENGTH,
+ MAX_USER_ADDRESS_LENGTH,
MAX_USER_SOCIALS,
+ MAX_USER_SOCIAL_LENGTH,
USER_AVATAR_FILE_TYPES,
MAX_USER_AVATAR_SIZE,
} from '~/configs/properties';
diff --git a/server/api/auth/login.post.ts b/server/api/auth/login.post.ts
index 295a005..eea1143 100644
--- a/server/api/auth/login.post.ts
+++ b/server/api/auth/login.post.ts
@@ -11,10 +11,13 @@ const anotherAuthProviderMessage =
'You tried signing in with a different authentication method than the one you used during signup. ' +
'Please try again using your original authentication method.';
-const loginPayloadSchema = z.object({
- email: emailValidator,
- password: passwordValidator,
-});
+const loginPayloadSchema = z
+ .object({
+ email: emailValidator,
+ password: passwordValidator,
+ })
+ .strict()
+ .required();
type Payload = z.infer;
@@ -34,7 +37,7 @@ export default defineEventHandler(async (event) => {
}
if (user.auth_provider !== AUTH_PROVIDERS.Email_And_Password) {
- throw createError({ statusCode: 404, statusMessage: anotherAuthProviderMessage });
+ throw createError({ statusCode: 400, statusMessage: anotherAuthProviderMessage });
}
if (user.password !== payload.password) {
diff --git a/server/api/auth/signup.post.ts b/server/api/auth/signup.post.ts
index 6d6ff70..d112dbd 100644
--- a/server/api/auth/signup.post.ts
+++ b/server/api/auth/signup.post.ts
@@ -1,19 +1,26 @@
import { z } from 'zod';
-import { AUTH_PROVIDERS, COOKIE_NAMES, MIN_USER_NAME_LENGTH, USER_IDENTITY_MAX_AGE } from '~/configs/properties';
+import {
+ AUTH_PROVIDERS,
+ COOKIE_NAMES,
+ MAX_USER_NAME_LENGTH,
+ MIN_USER_NAME_LENGTH,
+ USER_IDENTITY_MAX_AGE,
+} from '~/configs/properties';
import Profile from '~/server/models/user/profile.model';
import { jwtGenerator } from '~/server/services';
import type { Profile as IProfile } from '~/types/user';
import { stringToBase64 } from '~/utils/converters';
import { isZodError } from '~/utils/helpers';
-import { emailValidator } from '~/utils/validators';
+import { emailValidator, passwordValidator } from '~/utils/validators';
const signupPayloadSchema = z
.object({
- name: z.string().min(MIN_USER_NAME_LENGTH),
+ name: z.string().min(MIN_USER_NAME_LENGTH).max(MAX_USER_NAME_LENGTH),
email: emailValidator,
- password: z.string(),
+ password: passwordValidator,
})
+ .strict()
.required();
type Payload = z.infer;
@@ -39,7 +46,7 @@ export default defineEventHandler(async (event) => {
throw createError({ statusCode: 404, statusMessage: 'User with the provided email already exists' });
}
- const user = await Profile.create({ ...payload, provider: AUTH_PROVIDERS.Email_And_Password });
+ const user = await Profile.create({ ...payload, auth_provider: AUTH_PROVIDERS.Email_And_Password });
Object.assign(profile, user.toObject());
} catch (error) {
return sendError(
diff --git a/server/models/user/profile.model.ts b/server/models/user/profile.model.ts
index a07438b..faaf6ec 100644
--- a/server/models/user/profile.model.ts
+++ b/server/models/user/profile.model.ts
@@ -1,7 +1,14 @@
import { Schema, model } from 'mongoose';
-import { AUTH_PROVIDERS, MAX_USER_SOCIALS, MIN_USER_NAME_LENGTH } from '~/configs/properties';
-import { emailValidator, passwordValidator, dataURIValidator } from '~/utils/validators';
+import {
+ AUTH_PROVIDERS,
+ MAX_USER_ADDRESS_LENGTH,
+ MAX_USER_DESCRIPTION_LENGTH,
+ MAX_USER_NAME_LENGTH,
+ MAX_USER_SOCIALS,
+ MIN_USER_NAME_LENGTH,
+} from '~/configs/properties';
+import { emailValidator, passwordValidator, dataURIValidator, phoneValidator } from '~/utils/validators';
const favouritesSubschema = new Schema(
{
@@ -28,6 +35,7 @@ const schema = new Schema(
type: String,
required: true,
minLength: MIN_USER_NAME_LENGTH,
+ maxLength: MAX_USER_NAME_LENGTH,
},
email: {
type: String,
@@ -39,29 +47,36 @@ const schema = new Schema(
},
password: {
type: String,
+ required: true,
validate: {
validator: (value: string) => passwordValidator.safeParse(value).success,
},
},
avatar: {
type: String,
+ default: '',
validate: {
validator: (value?: string) => !dataURIValidator.safeParse(value).success,
message: 'Avatar in base64 format is forbidden.',
},
- default: '',
},
description: {
type: String,
default: '',
+ maxLength: MAX_USER_DESCRIPTION_LENGTH,
},
address: {
type: String,
default: '',
+ maxLength: MAX_USER_ADDRESS_LENGTH,
},
phone: {
type: String,
default: '',
+ validate: {
+ validator: (value: string) => !value || phoneValidator.safeParse(value).success,
+ message: 'Phone value is incorrect',
+ },
},
socials: {
type: Array,
@@ -74,6 +89,8 @@ const schema = new Schema(
auth_provider: {
type: String,
enum: Object.values(AUTH_PROVIDERS),
+ immutable: true,
+ required: true,
},
favourites: [favouritesSubschema],
},
diff --git a/server/schemas.ts b/server/schemas.ts
index 90dc07d..ba32923 100644
--- a/server/schemas.ts
+++ b/server/schemas.ts
@@ -1,6 +1,14 @@
import { z } from 'zod';
-import { AUTH_PROVIDERS, MAX_USER_SOCIALS, MIN_USER_NAME_LENGTH } from '~/configs/properties';
+import {
+ AUTH_PROVIDERS,
+ MAX_USER_ADDRESS_LENGTH,
+ MAX_USER_DESCRIPTION_LENGTH,
+ MAX_USER_NAME_LENGTH,
+ MAX_USER_SOCIAL_LENGTH,
+ MAX_USER_SOCIALS,
+ MIN_USER_NAME_LENGTH,
+} from '~/configs/properties';
import { dataURIValidator, phoneValidator, urlValidator } from '~/utils/validators';
export const userIdentitySchema = z
@@ -21,15 +29,15 @@ export const userFavouriteSchema = z
export const userUpdateProfileSchema = z
.object({
- name: z.string().min(MIN_USER_NAME_LENGTH),
+ name: z.string().min(MIN_USER_NAME_LENGTH).max(MAX_USER_NAME_LENGTH),
avatar: z
.string()
.refine((value) => !dataURIValidator.safeParse(value).success)
.or(z.literal('')),
- description: z.string(),
- address: z.string(),
+ description: z.string().max(MAX_USER_DESCRIPTION_LENGTH),
+ address: z.string().max(MAX_USER_ADDRESS_LENGTH),
phone: phoneValidator.or(z.literal('')),
- socials: z.array(urlValidator.or(z.literal(''))).max(MAX_USER_SOCIALS),
+ socials: z.array(urlValidator.max(MAX_USER_SOCIAL_LENGTH).or(z.literal(''))).max(MAX_USER_SOCIALS),
createdAt: z.string().optional(),
updatedAt: z.string().optional(),
favourites: z.array(userFavouriteSchema).optional(),