@hsuite/users-types - User Type Definitions
👥 Comprehensive TypeScript library for user management with full NestJS and MongoDB integration
Type-safe user entity definitions, interfaces, and models providing robust user data structures with built-in validation, authentication integration, and complete NestJS ecosystem support.
📚 Table of Contents
✨ Quick Start
Installation
npm install @hsuite/users-types
Basic Setup
import { User, IUser } from '@hsuite/users-types';
// Type-safe user entity
const user: User.Safe = {
email: "[email protected]",
username: "johndoe",
created_at: Date.now(),
updated_at: Date.now(),
confirmed: true,
type: "standard",
role: "user",
tags: ["premium", "beta"],
banned: false,
twoFactorAuth: {
enabled: false,
secret: null,
backupCodes: []
}
};
NestJS Integration
import { Schema, SchemaFactory } from '@nestjs/mongoose';
import { User } from '@hsuite/users-types';
@Schema({ collection: 'users', timestamps: true })
export class UserEntity extends User.Safe {
@Prop({ auto: true })
_id: string;
}
export const UserSchema = SchemaFactory.createForClass(UserEntity);
🏗️ Architecture
Type System Structure
The library is organized around two primary namespaces:
🔧 IUser Namespace
Interface Definitions - Foundation for user-related type definitions
Type Safety - Strict TypeScript interfaces for user entities
Extensibility - Framework for future interface additions
👤 User Namespace
Concrete Models - Implementation classes with full validation
MongoDB Integration - Ready-to-use Mongoose schemas
API Documentation - Complete Swagger/OpenAPI decorators
Core Components
🛡️ User.Safe Class
Public Properties - Safe user data representation
Full Validation - Built-in email and role validation
Auth Integration - Seamless compatibility with HSuite auth system
Database Ready - Complete Mongoose decorators and constraints
🔐 Authentication Types
Role-Based Access - User, admin, and owner role definitions
Two-Factor Auth - Complete 2FA type structures
User Types - Extensible user account type system
Permission Integration - Compatible with HSuite permission systems
Module Structure
src/
├── interfaces/
│ └── types.namespace.ts # IUser namespace definitions
├── models/
│ └── types.namespace.ts # User model implementations
└── index.ts # Main export file
🔧 API Reference
User.Safe Class
Core Properties
email
string
✅
User's email address
Unique, email format
username
string
✅
Unique username
Required
created_at
number
✅
Account creation timestamp
Unix timestamp
updated_at
number
✅
Last update timestamp
Unix timestamp
confirmed
boolean
✅
Account confirmation status
Boolean flag
type
IAuth.ICredentials.IUser.IType
✅
User account type
Auth type
role
'user' | 'admin' | 'owner'
✅
User system role
Role enum
tags
Array<Auth.Credentials.User.Tags>
❌
User categorization tags
Optional array
banned
boolean
❌
Ban status flag
Optional boolean
twoFactorAuth
Auth.TwoFactor.Auth
✅
2FA configuration
Auth object
Property Details
email: string
Validation: Email format validation using
validator/lib/isEmail
Constraints: Unique across the system
Usage: Primary user identification and communication
Example:
"[email protected]"
username: string
Validation: Required field validation
Constraints: Unique username requirement
Usage: User-friendly identification
Example:
"johndoe"
role: 'user' | 'admin' | 'owner'
Type Safety: Strict union type enforcement
Permissions: Determines system access levels
Integration: Compatible with HSuite RBAC system
Default:
"user"
twoFactorAuth: Auth.TwoFactor.Auth
Integration: Full compatibility with @hsuite/auth-types
Features: Secret management, backup codes, enabled status
Security: Enterprise-grade 2FA implementation
Structure: Complete authentication configuration
Namespaces
IUser Namespace
export namespace IUser {
// Foundation for future interface definitions
}
User Namespace
export namespace User {
export class Safe implements IAuth.ICredentials.IUser.IEntity {
// Complete implementation with decorators
}
}
Decorator Reference
Mongoose Decorators
@Prop({
unique: true,
required: true,
type: String,
validate: [isEmail, 'invalid email']
})
email: string;
Swagger Decorators
@ApiProperty({
type: String,
description: 'Email address used for user identification',
required: true,
example: '[email protected]'
})
email: string;
📖 Guides
User Schema Setup Guide
Configure MongoDB schemas using User.Safe class definitions. Comprehensive setup guide covering MongoDB schema configuration, type validation, data modeling, field mapping, and enterprise-grade user data management with complete type safety and validation.
Authentication Integration Guide
Integrate user types with HSuite authentication system. Advanced integration guide covering authentication workflows, user credential management, session handling, role-based access control, and secure user authentication with comprehensive security features.
API Documentation Guide
Generate comprehensive API documentation with Swagger. Detailed documentation guide covering Swagger integration, API endpoint documentation, type definitions, request/response examples, and enterprise-grade API documentation for user management systems.
🎯 Examples
Basic User Management
import { User } from '@hsuite/users-types';
import { IAuth } from '@hsuite/auth-types';
@Injectable()
export class UserManagementService {
async createUser(userData: Partial<User.Safe>): Promise<User.Safe> {
const user: User.Safe = {
email: userData.email,
username: userData.username,
created_at: Date.now(),
updated_at: Date.now(),
confirmed: false,
type: 'standard' as IAuth.ICredentials.IUser.IType,
role: 'user',
tags: [],
banned: false,
twoFactorAuth: {
enabled: false,
secret: null,
backupCodes: []
}
};
return user;
}
validateUserRole(user: User.Safe, requiredRole: 'user' | 'admin' | 'owner'): boolean {
const roleHierarchy = {
'user': 0,
'admin': 1,
'owner': 2
};
return roleHierarchy[user.role] >= roleHierarchy[requiredRole];
}
updateUserTags(user: User.Safe, newTags: string[]): User.Safe {
return {
...user,
tags: newTags,
updated_at: Date.now()
};
}
}
NestJS Service Implementation
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User } from '@hsuite/users-types';
@Schema({ collection: 'users', timestamps: true })
export class UserDocument extends User.Safe {
@Prop({ auto: true })
_id: string;
}
export const UserSchema = SchemaFactory.createForClass(UserDocument);
@Injectable()
export class UsersService {
constructor(
@InjectModel('User') private userModel: Model<UserDocument>
) {}
async createUser(createUserDto: Partial<User.Safe>): Promise<UserDocument> {
try {
const user = new this.userModel({
...createUserDto,
created_at: Date.now(),
updated_at: Date.now(),
confirmed: false,
banned: false,
twoFactorAuth: {
enabled: false,
secret: null,
backupCodes: []
}
});
const savedUser = await user.save();
return savedUser;
} catch (error) {
if (error.code === 11000) {
throw new Error('Email already exists');
}
throw error;
}
}
async findUserByEmail(email: string): Promise<UserDocument | null> {
return await this.userModel.findOne({ email }).exec();
}
async updateUser(
userId: string,
updateData: Partial<User.Safe>
): Promise<UserDocument> {
const updatedUser = await this.userModel.findByIdAndUpdate(
userId,
{
...updateData,
updated_at: Date.now()
},
{ new: true, runValidators: true }
).exec();
if (!updatedUser) {
throw new Error('User not found');
}
return updatedUser;
}
async banUser(userId: string): Promise<UserDocument> {
return await this.updateUser(userId, { banned: true });
}
async confirmUser(userId: string): Promise<UserDocument> {
return await this.updateUser(userId, { confirmed: true });
}
async getUsersByRole(role: 'user' | 'admin' | 'owner'): Promise<UserDocument[]> {
return await this.userModel.find({ role }).exec();
}
async searchUsersByTags(tags: string[]): Promise<UserDocument[]> {
return await this.userModel.find({
tags: { $in: tags }
}).exec();
}
}
API Controller with Swagger Documentation
import { Controller, Get, Post, Body, Param, Put } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiParam } from '@nestjs/swagger';
import { User } from '@hsuite/users-types';
import { UsersService } from './users.service';
@ApiTags('Users')
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Post()
@ApiOperation({ summary: 'Create new user' })
@ApiResponse({
status: 201,
description: 'User created successfully',
type: User.Safe
})
@ApiResponse({
status: 400,
description: 'Invalid user data or email already exists'
})
async createUser(@Body() userData: Partial<User.Safe>): Promise<User.Safe> {
return await this.usersService.createUser(userData);
}
@Get(':email')
@ApiOperation({ summary: 'Get user by email' })
@ApiParam({ name: 'email', description: 'User email address' })
@ApiResponse({
status: 200,
description: 'User found',
type: User.Safe
})
@ApiResponse({
status: 404,
description: 'User not found'
})
async getUserByEmail(@Param('email') email: string): Promise<User.Safe> {
const user = await this.usersService.findUserByEmail(email);
if (!user) {
throw new Error('User not found');
}
return user;
}
@Put(':id/ban')
@ApiOperation({ summary: 'Ban user account' })
@ApiParam({ name: 'id', description: 'User ID' })
@ApiResponse({
status: 200,
description: 'User banned successfully',
type: User.Safe
})
async banUser(@Param('id') userId: string): Promise<User.Safe> {
return await this.usersService.banUser(userId);
}
@Put(':id/confirm')
@ApiOperation({ summary: 'Confirm user account' })
@ApiParam({ name: 'id', description: 'User ID' })
@ApiResponse({
status: 200,
description: 'User confirmed successfully',
type: User.Safe
})
async confirmUser(@Param('id') userId: string): Promise<User.Safe> {
return await this.usersService.confirmUser(userId);
}
@Get('role/:role')
@ApiOperation({ summary: 'Get users by role' })
@ApiParam({
name: 'role',
description: 'User role',
enum: ['user', 'admin', 'owner']
})
@ApiResponse({
status: 200,
description: 'Users retrieved successfully',
type: [User.Safe]
})
async getUsersByRole(
@Param('role') role: 'user' | 'admin' | 'owner'
): Promise<User.Safe[]> {
return await this.usersService.getUsersByRole(role);
}
}
Authentication Integration
import { Injectable } from '@nestjs/common';
import { User } from '@hsuite/users-types';
import { IAuth } from '@hsuite/auth-types';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthenticationService {
constructor(private jwtService: JwtService) {}
/**
* Validates user authentication and returns safe user data
*/
validateUserCredentials(user: User.Safe): IAuth.ICredentials.IUser.IEntity {
if (user.banned) {
throw new Error('User account is banned');
}
if (!user.confirmed) {
throw new Error('User account not confirmed');
}
// User.Safe implements IAuth.ICredentials.IUser.IEntity
return user;
}
/**
* Generates JWT token with user information
*/
generateUserToken(user: User.Safe): string {
const payload = {
email: user.email,
username: user.username,
role: user.role,
type: user.type,
confirmed: user.confirmed
};
return this.jwtService.sign(payload);
}
/**
* Validates user permissions based on role
*/
validateUserPermissions(
user: User.Safe,
requiredPermissions: string[]
): boolean {
const rolePermissions = {
'user': ['read:own', 'update:own'],
'admin': ['read:all', 'update:all', 'create:all'],
'owner': ['read:all', 'update:all', 'create:all', 'delete:all']
};
const userPermissions = rolePermissions[user.role] || [];
return requiredPermissions.every(permission =>
userPermissions.includes(permission)
);
}
/**
* Enables two-factor authentication for user
*/
async enableTwoFactor(
user: User.Safe,
secret: string,
backupCodes: string[]
): Promise<User.Safe> {
return {
...user,
twoFactorAuth: {
enabled: true,
secret: secret,
backupCodes: backupCodes
},
updated_at: Date.now()
};
}
}
User Validation Utilities
import { User } from '@hsuite/users-types';
import { validate } from 'class-validator';
import isEmail from 'validator/lib/isEmail';
export class UserValidationUtils {
/**
* Validates user email format
*/
static validateEmail(email: string): boolean {
return isEmail(email);
}
/**
* Validates username format
*/
static validateUsername(username: string): boolean {
const usernameRegex = /^[a-zA-Z0-9_]{3,20}$/;
return usernameRegex.test(username);
}
/**
* Validates user role
*/
static validateRole(role: string): role is 'user' | 'admin' | 'owner' {
return ['user', 'admin', 'owner'].includes(role);
}
/**
* Validates complete user object
*/
static async validateUser(user: User.Safe): Promise<{
isValid: boolean;
errors: string[];
}> {
const errors: string[] = [];
// Email validation
if (!this.validateEmail(user.email)) {
errors.push('Invalid email format');
}
// Username validation
if (!this.validateUsername(user.username)) {
errors.push('Invalid username format (3-20 alphanumeric characters and underscores)');
}
// Role validation
if (!this.validateRole(user.role)) {
errors.push('Invalid user role');
}
// Required fields validation
if (!user.created_at || !user.updated_at) {
errors.push('Missing required timestamp fields');
}
if (user.confirmed === undefined || user.confirmed === null) {
errors.push('Missing confirmation status');
}
return {
isValid: errors.length === 0,
errors
};
}
/**
* Sanitizes user data for safe exposure
*/
static sanitizeUserForPublic(user: User.Safe): Partial<User.Safe> {
return {
email: user.email,
username: user.username,
role: user.role,
confirmed: user.confirmed,
tags: user.tags,
created_at: user.created_at
// Exclude sensitive fields like twoFactorAuth
};
}
}
Testing Utilities
import { User } from '@hsuite/users-types';
import { IAuth } from '@hsuite/auth-types';
export class UserTestingUtils {
/**
* Creates a mock user for testing
*/
static createMockUser(overrides: Partial<User.Safe> = {}): User.Safe {
const defaultUser: User.Safe = {
email: '[email protected]',
username: 'testuser',
created_at: Date.now(),
updated_at: Date.now(),
confirmed: true,
type: 'standard' as IAuth.ICredentials.IUser.IType,
role: 'user',
tags: [],
banned: false,
twoFactorAuth: {
enabled: false,
secret: null,
backupCodes: []
}
};
return { ...defaultUser, ...overrides };
}
/**
* Creates multiple mock users for testing
*/
static createMockUsers(count: number): User.Safe[] {
return Array.from({ length: count }, (_, index) =>
this.createMockUser({
email: `test${index}@example.com`,
username: `testuser${index}`
})
);
}
/**
* Creates admin user for testing
*/
static createMockAdmin(): User.Safe {
return this.createMockUser({
email: '[email protected]',
username: 'admin',
role: 'admin'
});
}
/**
* Creates owner user for testing
*/
static createMockOwner(): User.Safe {
return this.createMockUser({
email: '[email protected]',
username: 'owner',
role: 'owner'
});
}
}
🔗 Integration
Required Dependencies
{
"@nestjs/common": "^10.4.2",
"@nestjs/core": "^10.4.2",
"@hsuite/auth-types": "^2.1.2",
"@hsuite/nestjs-swagger": "^1.0.3",
"@nestjs/mongoose": "^10.0.0",
"mongoose": "^8.0.0",
"validator": "^13.0.0",
"class-validator": "^0.14.0"
}
TypeScript Configuration
{
"compilerOptions": {
"declaration": true,
"outDir": "../../dist/libs/users-types",
"types": ["node"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
}
Module Integration
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { User } from '@hsuite/users-types';
// Create schema from User.Safe class
@Schema({ collection: 'users', timestamps: true })
export class UserDocument extends User.Safe {}
export const UserSchema = SchemaFactory.createForClass(UserDocument);
@Module({
imports: [
MongooseModule.forFeature([
{ name: 'User', schema: UserSchema }
])
],
providers: [UsersService],
controllers: [UsersController],
exports: [UsersService]
})
export class UsersModule {}
Documentation Generation
# Generate comprehensive documentation
npm run compodoc
# Generate documentation with coverage report
npm run compodoc:coverage
Integration with HSuite Ecosystem
// Complete integration with other HSuite modules
import { User } from '@hsuite/users-types';
import { IAuth } from '@hsuite/auth-types';
import { AuthModule } from '@hsuite/auth';
import { SmartConfigModule } from '@hsuite/smart-config';
@Module({
imports: [
AuthModule,
SmartConfigModule,
MongooseModule.forFeature([
{ name: 'User', schema: UserSchema }
])
]
})
export class UserManagementModule {}
@Injectable()
export class IntegratedUserService {
constructor(
private authService: AuthService,
private usersService: UsersService
) {}
async createAuthenticatedUser(
userData: Partial<User.Safe>,
session: IAuth.ICredentials.IWeb3.IEntity
): Promise<User.Safe> {
// Validate session permissions
const hasPermission = await this.authService.validatePermission(
session,
'user:create'
);
if (!hasPermission) {
throw new Error('Insufficient permissions to create user');
}
// Create user with type safety
const user = await this.usersService.createUser(userData);
return user;
}
}
👥 Type-Safe User Management: Comprehensive TypeScript definitions with full validation and authentication integration.
🛡️ Enterprise Security: Role-based access control, two-factor authentication, and complete audit trail support.
🔧 Developer Experience: Full NestJS integration with Mongoose schemas and automatic API documentation generation.
Built with ❤️ by the HbarSuite Team Copyright © 2024 HbarSuite. All rights reserved.
Last updated