cube-ms
Version:
Production-ready microservice framework with health monitoring, validation, error handling, and Docker Swarm support
263 lines (243 loc) • 4.94 kB
JavaScript
import { Schema } from 'cube-ms';
export const UserSchema = new Schema({
name: {
type: 'string',
required: true,
min: 2,
max: 100,
trim: true
},
email: {
type: 'email',
required: true,
unique: true,
lowercase: true,
trim: true
},
password: {
type: 'string',
required: true,
min: 6,
max: 128
},
role: {
type: 'string',
enum: ['user', 'admin', 'moderator'],
default: 'user'
},
isActive: {
type: 'boolean',
default: true
},
profile: {
firstName: {
type: 'string',
min: 1,
max: 50,
trim: true
},
lastName: {
type: 'string',
min: 1,
max: 50,
trim: true
},
avatar: {
type: 'url',
optional: true
},
bio: {
type: 'string',
max: 500,
optional: true
},
dateOfBirth: {
type: 'date',
optional: true
},
location: {
country: {
type: 'string',
max: 100,
optional: true
},
city: {
type: 'string',
max: 100,
optional: true
}
}
},
settings: {
notifications: {
email: {
type: 'boolean',
default: true
},
push: {
type: 'boolean',
default: true
}
},
privacy: {
profilePublic: {
type: 'boolean',
default: true
}
},
language: {
type: 'string',
enum: ['en', 'id', 'es', 'fr', 'de'],
default: 'en'
},
timezone: {
type: 'string',
default: 'UTC'
}
},
metadata: {
lastLoginAt: {
type: 'date',
optional: true
},
loginCount: {
type: 'number',
min: 0,
default: 0
},
emailVerifiedAt: {
type: 'date',
optional: true
},
passwordChangedAt: {
type: 'date',
optional: true
}
},
createdAt: {
type: 'date',
default: () => new Date()
},
updatedAt: {
type: 'date',
default: () => new Date()
}
});
export class UserModel {
constructor(data = {}) {
this.data = this.setDefaults(data);
}
setDefaults(data) {
return {
name: '',
email: '',
password: '',
role: 'user',
isActive: true,
profile: {
firstName: '',
lastName: '',
location: {}
},
settings: {
notifications: {
email: true,
push: true
},
privacy: {
profilePublic: true
},
language: 'en',
timezone: 'UTC'
},
metadata: {
loginCount: 0
},
...data,
createdAt: data.createdAt || new Date(),
updatedAt: data.updatedAt || new Date()
};
}
validate() {
return UserSchema.validate(this.data);
}
toJSON() {
const { password, ...userWithoutPassword } = this.data;
return {
...userWithoutPassword,
id: this.data._id?.toString() || this.data.id
};
}
toPublicJSON() {
const publicFields = {
id: this.data._id?.toString() || this.data.id,
name: this.data.name,
profile: {
firstName: this.data.profile?.firstName,
lastName: this.data.profile?.lastName,
avatar: this.data.profile?.avatar,
bio: this.data.profile?.bio
},
createdAt: this.data.createdAt
};
// Only include public fields based on privacy settings
if (this.data.settings?.privacy?.profilePublic !== false) {
publicFields.profile.location = this.data.profile?.location;
}
return publicFields;
}
updatePassword(newPassword) {
this.data.password = newPassword;
this.data.metadata.passwordChangedAt = new Date();
this.data.updatedAt = new Date();
}
updateLastLogin() {
this.data.metadata.lastLoginAt = new Date();
this.data.metadata.loginCount = (this.data.metadata.loginCount || 0) + 1;
this.data.updatedAt = new Date();
}
verifyEmail() {
this.data.metadata.emailVerifiedAt = new Date();
this.data.updatedAt = new Date();
}
isEmailVerified() {
return !!this.data.metadata.emailVerifiedAt;
}
hasRole(role) {
if (Array.isArray(role)) {
return role.includes(this.data.role);
}
return this.data.role === role;
}
isAdmin() {
return this.data.role === 'admin';
}
isModerator() {
return this.hasRole(['admin', 'moderator']);
}
getFullName() {
const { firstName, lastName } = this.data.profile || {};
if (firstName && lastName) {
return `${firstName} ${lastName}`;
}
return this.data.name || '';
}
static fromJSON(json) {
return new UserModel(json);
}
static createSchema() {
return UserSchema;
}
static getPublicFields() {
return [
'id',
'name',
'profile.firstName',
'profile.lastName',
'profile.avatar',
'profile.bio',
'createdAt'
];
}
}
export default UserModel;