diff --git a/Dockerfile b/Dockerfile
index d9688ab63..ddb04c98d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:16
+FROM node:20
 
 #Set working directory
 WORKDIR /var/src/
diff --git a/src/.env.sample b/src/.env.sample
index 8c94049f4..88f9ff893 100644
--- a/src/.env.sample
+++ b/src/.env.sample
@@ -176,5 +176,11 @@ DOWNLOAD_URL_EXPIRATION_DURATION = 120000
 #database url
 DATABASE_URL=postgres://postgres:postgres@localhost:5432/elevate-user
 
+#allowed idle time
+ALLOWED_IDLE_TIME=300000
+
 # Expiry time for the signed urls
-SIGNED_URL_EXPIRY_IN_MILLISECONDS = 120000
\ No newline at end of file
+SIGNED_URL_EXPIRY_IN_MILLISECONDS = 120000
+
+# Allowed active sessions
+ALLOWED_ACTIVE_SESSIONS = 5
diff --git a/src/constants/common.js b/src/constants/common.js
index 9724f558a..5170a5d68 100644
--- a/src/constants/common.js
+++ b/src/constants/common.js
@@ -26,6 +26,7 @@ module.exports = {
 		'/user/v1/account/search',
 		'/user/v1/organization/list',
 		'/user/v1/user-role/default',
+		'/user/v1/account/validateUserSession',
 	],
 	notificationEmailType: 'email',
 	accessTokenExpiry: process.env.ACCESS_TOKEN_EXPIRY,
@@ -59,6 +60,7 @@ module.exports = {
 	roleAssociationName: 'user_roles',
 	ACTIVE_STATUS: 'ACTIVE',
 	INACTIVE_STATUS: 'INACTIVE',
+	EXPIRED_STATUS: 'EXPIRED',
 	MENTOR_ROLE: 'mentor',
 	MENTEE_ROLE: 'mentee',
 	SESSION_MANAGER_ROLE: 'session_manager',
diff --git a/src/controllers/v1/account.js b/src/controllers/v1/account.js
index b5fa81738..071aca529 100644
--- a/src/controllers/v1/account.js
+++ b/src/controllers/v1/account.js
@@ -7,7 +7,7 @@
 
 // Dependencies
 const accountService = require('@services/account')
-
+const userSessionsService = require('@services/user-sessions')
 module.exports = class Account {
 	/**
 	 * create mentee account
@@ -24,8 +24,9 @@ module.exports = class Account {
 
 	async create(req) {
 		const params = req.body
+		const device_info = req.headers && req.headers['device-info'] ? JSON.parse(req.headers['device-info']) : {}
 		try {
-			const createdAccount = await accountService.create(params)
+			const createdAccount = await accountService.create(params, device_info)
 			return createdAccount
 		} catch (error) {
 			return error
@@ -45,8 +46,9 @@ module.exports = class Account {
 
 	async login(req) {
 		const params = req.body
+		const device_info = req.headers && req.headers['device-info'] ? JSON.parse(req.headers['device-info']) : {}
 		try {
-			const loggedInAccount = await accountService.login(params)
+			const loggedInAccount = await accountService.login(params, device_info)
 			return loggedInAccount
 		} catch (error) {
 			return error
@@ -69,7 +71,8 @@ module.exports = class Account {
 			const loggedOutAccount = await accountService.logout(
 				req.body,
 				req.decodedToken.id,
-				req.decodedToken.organization_id
+				req.decodedToken.organization_id,
+				req.decodedToken.session_id
 			)
 			return loggedOutAccount
 		} catch (error) {
@@ -128,7 +131,8 @@ module.exports = class Account {
 	async resetPassword(req) {
 		const params = req.body
 		try {
-			const result = await accountService.resetPassword(params)
+			const deviceInfo = req.headers && req.headers['device-info'] ? JSON.parse(req.headers['device-info']) : {}
+			const result = await accountService.resetPassword(params, deviceInfo)
 			return result
 		} catch (error) {
 			return error
@@ -266,4 +270,42 @@ module.exports = class Account {
 			return error
 		}
 	}
+
+	/**
+	 * Retrieve user sessions based on the request parameters.
+	 * @param {Object} req - The request object containing query parameters and decoded token.
+	 * @returns {Promise<Object>} - A promise that resolves to the user session details.
+	 */
+
+	async sessions(req) {
+		try {
+			const filter = req.query && req.query.status ? req.query.status.toUpperCase() : ''
+			const userSessionDetails = await userSessionsService.list(
+				req.decodedToken.id,
+				filter,
+				req.pageSize,
+				req.pageNo
+			)
+			return userSessionDetails
+		} catch (error) {
+			return error
+		}
+	}
+
+	/**
+	 * Validate a user session based on the provided token.
+	 * @param {Object} req - The request object containing the token in the request body.
+	 * @param {string} req.body.token - The token to validate the user session.
+	 * @returns {Promise<Object>} - A promise that resolves to the validation result of the user session.
+	 */
+
+	async validateUserSession(req) {
+		try {
+			const token = req.body.token
+			const validateUserSession = await userSessionsService.validateUserSession(token)
+			return validateUserSession
+		} catch (error) {
+			return error
+		}
+	}
 }
diff --git a/src/controllers/v1/admin.js b/src/controllers/v1/admin.js
index 46f10fea5..73c432403 100644
--- a/src/controllers/v1/admin.js
+++ b/src/controllers/v1/admin.js
@@ -78,7 +78,8 @@ module.exports = class Admin {
 
 	async login(req) {
 		try {
-			const loggedInAccount = await adminService.login(req.body)
+			const device_info = req.headers && req.headers['device-info'] ? req.headers['device-info'] : {}
+			const loggedInAccount = await adminService.login(req.body, device_info)
 			return loggedInAccount
 		} catch (error) {
 			return error
diff --git a/src/database/migrations/20240326110128-create-user-sessions-table.js b/src/database/migrations/20240326110128-create-user-sessions-table.js
new file mode 100644
index 000000000..2a558fff6
--- /dev/null
+++ b/src/database/migrations/20240326110128-create-user-sessions-table.js
@@ -0,0 +1,54 @@
+'use strict'
+
+/** @type {import('sequelize-cli').Migration} */
+module.exports = {
+	async up(queryInterface, Sequelize) {
+		await queryInterface.createTable('user_sessions', {
+			id: {
+				type: Sequelize.INTEGER,
+				allowNull: false,
+				primaryKey: true,
+				autoIncrement: true,
+			},
+			user_id: {
+				type: Sequelize.INTEGER,
+				allowNull: false,
+			},
+			started_at: {
+				type: Sequelize.BIGINT,
+				allowNull: false,
+			},
+			ended_at: {
+				type: Sequelize.BIGINT,
+				allowNull: true,
+			},
+			token: {
+				type: Sequelize.TEXT,
+				allowNull: true,
+			},
+			device_info: {
+				type: Sequelize.JSONB,
+				allowNull: true,
+			},
+			refresh_token: {
+				type: Sequelize.TEXT,
+				allowNull: true,
+			},
+			created_at: {
+				allowNull: false,
+				type: Sequelize.DATE,
+			},
+			updated_at: {
+				allowNull: false,
+				type: Sequelize.DATE,
+			},
+			deleted_at: {
+				type: Sequelize.DATE,
+			},
+		})
+	},
+
+	async down(queryInterface, Sequelize) {
+		await queryInterface.dropTable('user_sessions')
+	},
+}
diff --git a/src/database/migrations/20240328084048-update-session-permissions.js b/src/database/migrations/20240328084048-update-session-permissions.js
new file mode 100644
index 000000000..a6f3df195
--- /dev/null
+++ b/src/database/migrations/20240328084048-update-session-permissions.js
@@ -0,0 +1,48 @@
+'use strict'
+
+/** @type {import('sequelize-cli').Migration} */
+module.exports = {
+	async up(queryInterface, Sequelize) {
+		try {
+			const permissionsData = [
+				{
+					code: 'get_user_sessions',
+					module: 'account',
+					request_type: ['GET'],
+					api_path: '/user/v1/account/sessions',
+					status: 'ACTIVE',
+				},
+				{
+					code: 'validate_user_sessions',
+					module: 'account',
+					request_type: ['POST'],
+					api_path: '/user/v1/account/validateUserSession',
+					status: 'ACTIVE',
+				},
+			]
+
+			// Batch insert permissions
+			await queryInterface.bulkInsert(
+				'permissions',
+				permissionsData.map((permission) => ({
+					...permission,
+					created_at: new Date(),
+					updated_at: new Date(),
+				}))
+			)
+		} catch (error) {
+			console.error('Error in migration:', error)
+			throw error
+		}
+	},
+
+	async down(queryInterface, Sequelize) {
+		try {
+			// Rollback migration by deleting all permissions
+			await queryInterface.bulkDelete('permissions', null, {})
+		} catch (error) {
+			console.error('Error in rollback migration:', error)
+			throw error
+		}
+	},
+}
diff --git a/src/database/migrations/20240328084246-update-session-role-permission.js b/src/database/migrations/20240328084246-update-session-role-permission.js
new file mode 100644
index 000000000..f86db8dd8
--- /dev/null
+++ b/src/database/migrations/20240328084246-update-session-role-permission.js
@@ -0,0 +1,139 @@
+'use strict'
+
+require('module-alias/register')
+require('dotenv').config()
+const common = require('@constants/common')
+const Permissions = require('@database/models/index').Permission
+
+const getPermissionId = async (module, request_type, api_path) => {
+	try {
+		const permission = await Permissions.findOne({
+			where: { module, request_type, api_path },
+		})
+		if (!permission) {
+			throw new Error(
+				`Permission not found for module: ${module}, request_type: ${request_type}, api_path: ${api_path}`
+			)
+		}
+		return permission.id
+	} catch (error) {
+		throw new Error(`Error while fetching permission: ${error.message}`)
+	}
+}
+
+module.exports = {
+	up: async (queryInterface, Sequelize) => {
+		try {
+			const rolePermissionsData = await Promise.all([
+				{
+					role_title: common.MENTOR_ROLE,
+					permission_id: await getPermissionId('account', ['GET'], '/user/v1/account/sessions'),
+					module: 'account',
+					request_type: ['GET'],
+					api_path: '/user/v1/account/sessions',
+				},
+				{
+					role_title: common.ORG_ADMIN_ROLE,
+					permission_id: await getPermissionId('account', ['GET'], '/user/v1/account/sessions'),
+					module: 'account',
+					request_type: ['GET'],
+					api_path: '/user/v1/account/sessions',
+				},
+				{
+					role_title: common.USER_ROLE,
+					permission_id: await getPermissionId('account', ['GET'], '/user/v1/account/sessions'),
+					module: 'account',
+					request_type: ['GET'],
+					api_path: '/user/v1/account/sessions',
+				},
+				{
+					role_title: common.ADMIN_ROLE,
+					permission_id: await getPermissionId('account', ['GET'], '/user/v1/account/sessions'),
+					module: 'account',
+					request_type: ['GET'],
+					api_path: '/user/v1/account/sessions',
+				},
+				{
+					role_title: common.SESSION_MANAGER_ROLE,
+					permission_id: await getPermissionId('account', ['GET'], '/user/v1/account/sessions'),
+					module: 'account',
+					request_type: ['GET'],
+					api_path: '/user/v1/account/sessions',
+				},
+				{
+					role_title: common.MENTEE_ROLE,
+					permission_id: await getPermissionId('account', ['GET'], '/user/v1/account/sessions'),
+					module: 'account',
+					request_type: ['GET'],
+					api_path: '/user/v1/account/sessions',
+				},
+
+				{
+					role_title: common.MENTOR_ROLE,
+					permission_id: await getPermissionId('account', ['POST'], '/user/v1/account/validateUserSession'),
+					module: 'account',
+					request_type: ['POST'],
+					api_path: '/user/v1/account/validateUserSession',
+				},
+				{
+					role_title: common.MENTEE_ROLE,
+					permission_id: await getPermissionId('account', ['POST'], '/user/v1/account/validateUserSession'),
+					module: 'account',
+					request_type: ['POST'],
+					api_path: '/user/v1/account/validateUserSession',
+				},
+				{
+					role_title: common.ORG_ADMIN_ROLE,
+					permission_id: await getPermissionId('account', ['POST'], '/user/v1/account/validateUserSession'),
+					module: 'account',
+					request_type: ['POST'],
+					api_path: '/user/v1/account/validateUserSession',
+				},
+				{
+					role_title: common.USER_ROLE,
+					permission_id: await getPermissionId('account', ['POST'], '/user/v1/account/validateUserSession'),
+					module: 'account',
+					request_type: ['POST'],
+					api_path: '/user/v1/account/validateUserSession',
+				},
+				{
+					role_title: common.ADMIN_ROLE,
+					permission_id: await getPermissionId('account', ['POST'], '/user/v1/account/validateUserSession'),
+					module: 'account',
+					request_type: ['POST'],
+					api_path: '/user/v1/account/validateUserSession',
+				},
+				{
+					role_title: common.SESSION_MANAGER_ROLE,
+					permission_id: await getPermissionId('account', ['POST'], '/user/v1/account/validateUserSession'),
+					module: 'account',
+					request_type: ['POST'],
+					api_path: '/user/v1/account/validateUserSession',
+				},
+			])
+
+			await queryInterface.bulkInsert(
+				'role_permission_mapping',
+				rolePermissionsData.map((data) => ({
+					...data,
+					created_at: new Date(),
+					updated_at: new Date(),
+					created_by: 0,
+				}))
+			)
+		} catch (error) {
+			console.log(error)
+			console.error(`Migration error: ${error.message}`)
+			throw error
+		}
+	},
+
+	down: async (queryInterface, Sequelize) => {
+		try {
+			await queryInterface.bulkDelete('role_permission_mapping', null, {})
+		} catch (error) {
+			console.error(`Rollback migration error: ${error.message}`)
+			throw error
+		}
+	},
+}
diff --git a/src/database/migrations/20240329082324-remove-refresh-token-and-login-time-column-from-users.js b/src/database/migrations/20240329082324-remove-refresh-token-and-login-time-column-from-users.js
new file mode 100644
index 000000000..c8ed62cf4
--- /dev/null
+++ b/src/database/migrations/20240329082324-remove-refresh-token-and-login-time-column-from-users.js
@@ -0,0 +1,22 @@
+'use strict'
+
+module.exports = {
+	up: async (queryInterface, Sequelize) => {
+		// Drop the materialized view
+		await queryInterface.sequelize.query('DROP MATERIALIZED VIEW IF EXISTS m_users')
+
+		// Remove the columns from the users table
+		await queryInterface.removeColumn('users', 'last_logged_in_at')
+		await queryInterface.removeColumn('users', 'refresh_tokens')
+	},
+
+	down: async (queryInterface, Sequelize) => {
+		// Add back the columns to the users table
+		await queryInterface.addColumn('users', 'last_logged_in_at', {
+			type: Sequelize.DATE,
+		})
+		await queryInterface.addColumn('users', 'refresh_tokens', {
+			type: Sequelize.ARRAY(Sequelize.JSONB),
+		})
+	},
+}
diff --git a/src/database/migrations/20240401123752-make-user-id-primary-key-in-user-sessions-table.js b/src/database/migrations/20240401123752-make-user-id-primary-key-in-user-sessions-table.js
new file mode 100644
index 000000000..6786b39a9
--- /dev/null
+++ b/src/database/migrations/20240401123752-make-user-id-primary-key-in-user-sessions-table.js
@@ -0,0 +1,27 @@
+'use strict'
+
+module.exports = {
+	async up(queryInterface, Sequelize) {
+		// Remove the primary key constraint from 'id'
+		await queryInterface.removeConstraint('user_sessions', 'user_sessions_pkey')
+
+		// Add a unique constraint for the combination of 'id' and 'user_id'
+		await queryInterface.addConstraint('user_sessions', {
+			fields: ['id', 'user_id'],
+			type: 'primary key',
+			name: 'user_sessions_pkey',
+		})
+	},
+
+	async down(queryInterface, Sequelize) {
+		// Remove the unique constraint for the combination of 'id' and 'user_id'
+		await queryInterface.removeConstraint('user_sessions', 'user_sessions_pkey')
+
+		// Add back the primary key constraint on 'id'
+		await queryInterface.addConstraint('user_sessions', {
+			type: 'primary key',
+			fields: ['id'],
+			name: 'user_sessions_pkey',
+		})
+	},
+}
diff --git a/src/database/models/user-sessions.js b/src/database/models/user-sessions.js
new file mode 100644
index 000000000..7b961e137
--- /dev/null
+++ b/src/database/models/user-sessions.js
@@ -0,0 +1,47 @@
+'use strict'
+module.exports = (sequelize, DataTypes) => {
+	const UserSessions = sequelize.define(
+		'UserSessions',
+		{
+			id: {
+				type: DataTypes.INTEGER,
+				allowNull: false,
+				primaryKey: true,
+				autoIncrement: true,
+			},
+			user_id: {
+				type: DataTypes.INTEGER,
+				allowNull: false,
+				primaryKey: true,
+			},
+			started_at: {
+				type: DataTypes.BIGINT,
+				allowNull: false,
+			},
+			ended_at: {
+				type: DataTypes.BIGINT,
+				allowNull: true,
+			},
+			token: {
+				type: DataTypes.TEXT,
+				allowNull: true,
+			},
+			device_info: {
+				type: DataTypes.JSONB,
+				allowNull: true,
+			},
+			refresh_token: {
+				type: DataTypes.TEXT,
+				allowNull: true,
+			},
+		},
+		{
+			sequelize,
+			modelName: 'UserSessions',
+			tableName: 'user_sessions',
+			freezeTableName: true,
+			paranoid: true,
+		}
+	)
+	return UserSessions
+}
diff --git a/src/database/models/users.js b/src/database/models/users.js
index 0f110e0de..aea7ed740 100644
--- a/src/database/models/users.js
+++ b/src/database/models/users.js
@@ -35,12 +35,10 @@ module.exports = (sequelize, DataTypes) => {
 				defaultValue: 'ACTIVE',
 			},
 			image: DataTypes.STRING,
-			last_logged_in_at: DataTypes.DATE,
 			has_accepted_terms_and_conditions: {
 				type: DataTypes.BOOLEAN,
 				defaultValue: false,
 			},
-			refresh_tokens: DataTypes.ARRAY(DataTypes.JSONB),
 			languages: DataTypes.ARRAY(DataTypes.STRING),
 			preferred_language: {
 				type: DataTypes.STRING,
diff --git a/src/database/queries/user-sessions.js b/src/database/queries/user-sessions.js
new file mode 100644
index 000000000..37abb8762
--- /dev/null
+++ b/src/database/queries/user-sessions.js
@@ -0,0 +1,91 @@
+/**
+ * name         : queries/user-sessions.js
+ * author       : Vishnu
+ * created-date : 26-Mar-2024
+ * Description  : user-sessions table query methods.
+ */
+
+// Dependencies
+'use strict'
+const UserSessions = require('@database/models/index').UserSessions
+const { Op } = require('sequelize')
+
+/**
+ * Find one record based on the provided filter.
+ * @param {Object} filter       - The filter object to specify the condition for selecting the record.
+ * @param {Object} options      - Additional options for the query (optional).
+ * @returns {Promise<Object>}   - A promise that resolves to the found record or an error.
+ */
+exports.findOne = async (filter, options = {}) => {
+	try {
+		return await UserSessions.findOne({
+			where: filter,
+			...options,
+			raw: true,
+		})
+	} catch (error) {
+		return error
+	}
+}
+
+/**
+ * Find a record by its primary key.
+ * @param {number|string} id    - The primary key value of the record.
+ * @returns {Promise<Object>}   - A promise that resolves to the found record or an error.
+ */
+exports.findByPk = async (id) => {
+	try {
+		return await UserSessions.findByPk(id, { raw: true })
+	} catch (error) {
+		return error
+	}
+}
+
+/**
+ * Find all records based on the provided filter.
+ * @param {Object} filter       - The filter object to specify the condition for selecting records.
+ * @param {Object} options      - Additional options for the query (optional).
+ * @returns {Promise<Array>}    - A promise that resolves to an array of found records or an error.
+ */
+exports.findAll = async (filter, options = {}) => {
+	try {
+		return await UserSessions.findAll({
+			where: filter,
+			...options,
+			raw: true,
+		})
+	} catch (error) {
+		return error
+	}
+}
+
+/**
+ * Update records based on the provided filter and update data.
+ * @param {Object} filter       - The filter object to specify the condition for updating records.
+ * @param {Object} update       - The update data to be applied to matching records.
+ * @param {Object} options      - Additional options for the update operation (optional).
+ * @returns {Promise<number>}   - A promise that resolves to the number of updated records or an error.
+ */
+exports.update = async (filter, update, options = {}) => {
+	try {
+		return await await UserSessions.update(update, {
+			where: filter,
+			...options,
+		})
+	} catch (error) {
+		return error
+	}
+}
+
+/**
+ * Create a new record with the provided data.
+ * @param {Object} data         - The data object representing the record to be created.
+ * @returns {Promise<Object>}   - A promise that resolves to the created record or an error.
+ */
+exports.create = async (data) => {
+	try {
+		return await UserSessions.create(data, { returning: true })
+	} catch (error) {
+		throw error
+	}
+}
diff --git a/src/envVariables.js b/src/envVariables.js
index e7d8410a4..a6c24db4d 100644
--- a/src/envVariables.js
+++ b/src/envVariables.js
@@ -256,6 +256,11 @@ let enviromentVariables = {
 		optional: true,
 		default: 3600000,
 	},
+	ALLOWED_IDLE_TIME: {
+		message: 'Require allowed idle time',
+		optional: true,
+		default: 0,
+	},
 	CHANGE_PASSWORD_TEMPLATE_CODE: {
 		message: 'Required change password email template code',
 		optional: false,
@@ -288,6 +293,11 @@ let enviromentVariables = {
 		optional: true,
 		default: 3600000,
 	},
+	ALLOWED_ACTIVE_SESSIONS: {
+		message: 'Require allowed active sessions',
+		optional: true,
+		default: 0,
+	},
 }
 
 let success = true
diff --git a/src/generics/utils.js b/src/generics/utils.js
index 2e45d706f..843f85218 100644
--- a/src/generics/utils.js
+++ b/src/generics/utils.js
@@ -434,6 +434,29 @@ const getRoleTitlesFromId = (roleIds = [], roleList = []) => {
 	})
 }
 
+const convertDurationToSeconds = (duration) => {
+	const timeUnits = {
+		s: 1,
+		m: 60,
+		h: 3600,
+		d: 86400,
+	}
+
+	const match = /^(\d*\.?\d*)([smhd])$/.exec(duration)
+	if (!match) {
+		throw new Error('Invalid duration format')
+	}
+
+	const value = parseFloat(match[1])
+	const unit = match[2]
+
+	if (!(unit in timeUnits)) {
+		throw new Error('Invalid duration unit')
+	}
+
+	return value * timeUnits[unit]
+}
+
 module.exports = {
 	generateToken,
 	hashPassword,
@@ -464,4 +487,5 @@ module.exports = {
 	isValidName,
 	generateWhereClause,
 	getRoleTitlesFromId,
+	convertDurationToSeconds,
 }
diff --git a/src/locales/en.json b/src/locales/en.json
index ec5ae542f..7eda9ffad 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -117,5 +117,11 @@
 	"INAVLID_ORG_ROLE_REQ": "Invalid organisation request",
 	"INCORRECT_OLD_PASSWORD": "Invalid old password",
 	"SAME_PASSWORD_ERROR": "New password cannot be same as old password",
-	"PASSWORD_CHANGED_SUCCESSFULLY": "Your password has been changed successfully. Please log-in to continue."
+	"USER_SESSION_CREATED_SUCCESSFULLY": "User session created successfully",
+	"USER_SESSION_UPDATED_CESSFULLY": "User session updated successfully",
+	"USER_SESSION_VALIDATED_SUCCESSFULLY": "User session validated successfully",
+	"USER_SESSION_FETCHED_SUCCESSFULLY": "User sessions fetched successfully",
+	"USER_SESSIONS_REMOVED_SUCCESSFULLY": "User sesions removed successfully",
+	"PASSWORD_CHANGED_SUCCESSFULLY": "Your password has been changed successfully. Please log-in to continue.",
+	"ACTIVE_SESSION_LIMIT_EXCEEDED": "Sorry! Your allowed active session limi exceeded. Please log-off from other sessions to continue"
 }
diff --git a/src/middlewares/authenticator.js b/src/middlewares/authenticator.js
index 5f303c345..c80443f22 100644
--- a/src/middlewares/authenticator.js
+++ b/src/middlewares/authenticator.js
@@ -14,6 +14,7 @@ const roleQueries = require('@database/queries/user-role')
 const rolePermissionMappingQueries = require('@database/queries/role-permission-mapping')
 const { Op } = require('sequelize')
 const responses = require('@helpers/responses')
+const utilsHelper = require('@generics/utils')
 const { verifyCaptchaToken } = require('@utils/captcha')
 
 async function checkPermissions(roleTitle, requestPath, requestMethod) {
@@ -116,6 +117,20 @@ module.exports = async function (req, res, next) {
 
 		try {
 			decodedToken = jwt.verify(authHeaderArray[1], process.env.ACCESS_TOKEN_SECRET)
+			// Get redis key for session
+			const sessionId = decodedToken.data.session_id.toString()
+			// Get data from redis
+			const redisData = await utilsHelper.redisGet(sessionId)
+
+			// If data is not in redis, token is invalid
+			if (!redisData || redisData.accessToken !== authHeaderArray[1]) {
+				throw unAuthorizedResponse
+			}
+
+			// Renew the TTL if allowed idle time is greater than zero
+			if (process.env.ALLOWED_IDLE_TIME != null) {
+				await utilsHelper.redisSet(sessionId, redisData, process.env.ALLOWED_IDLE_TIME)
+			}
 		} catch (err) {
 			if (err.name === 'TokenExpiredError') {
 				throw responses.failureResponse({
diff --git a/src/services/account.js b/src/services/account.js
index d3fd8cc71..ef1d6b84b 100644
--- a/src/services/account.js
+++ b/src/services/account.js
@@ -28,6 +28,7 @@ const { removeDefaultOrgEntityTypes } = require('@generics/utils')
 const UserCredentialQueries = require('@database/queries/userCredential')
 const emailEncryption = require('@utils/emailEncryption')
 const responses = require('@helpers/responses')
+const userSessionsService = require('@services/user-sessions')
 module.exports = class AccountHelper {
 	/**
 	 * create account
@@ -39,11 +40,12 @@ module.exports = class AccountHelper {
 	 * @param {Boolean} bodyData.isAMentor - is a mentor or not .
 	 * @param {String} bodyData.email - user email.
 	 * @param {String} bodyData.password - user password.
+	 * @param {Object} deviceInfo - Device information
 	 * @returns {JSON} - returns account creation details.
 	 */
 
-	static async create(bodyData) {
-		const projection = ['password', 'refresh_tokens']
+	static async create(bodyData, deviceInfo) {
+		const projection = ['password']
 
 		try {
 			const plaintextEmailId = bodyData.email.toLowerCase()
@@ -228,10 +230,22 @@ module.exports = class AccountHelper {
 				}
 			)
 
+			/**
+			 * create user session entry and add session_id to token data
+			 * Entry should be created first, the session_id has to be added to token creation data
+			 */
+			const userSessionDetails = await userSessionsService.createUserSession(
+				user.id, // userid
+				'', // refresh token
+				'', // Access token
+				deviceInfo
+			)
+
 			const tokenDetail = {
 				data: {
 					id: user.id,
 					name: user.name,
+					session_id: userSessionDetails.result.id,
 					organization_id: user.organization_id,
 					roles: roleData,
 				},
@@ -261,25 +275,23 @@ module.exports = class AccountHelper {
 				process.env.ACCESS_TOKEN_SECRET,
 				common.accessTokenExpiry
 			)
+
 			const refreshToken = utilsHelper.generateToken(
 				tokenDetail,
 				process.env.REFRESH_TOKEN_SECRET,
 				common.refreshTokenExpiry
 			)
 
-			let refresh_token = new Array()
-			refresh_token.push({
-				token: refreshToken,
-				exp: new Date().getTime() + common.refreshTokenExpiryInMs,
-				userId: user.id,
-			})
-
-			const update = {
-				refresh_tokens: refresh_token,
-				last_logged_in_at: new Date().getTime(),
-			}
-
-			await userQueries.updateUser({ id: user.id, organization_id: user.organization_id }, update)
+			/**
+			 * This function call will do below things
+			 * 1: create redis entry for the session
+			 * 2: update user-session with token and refresh_token
+			 */
+			await userSessionsService.updateUserSessionAndsetRedisData(
+				userSessionDetails.result.id,
+				accessToken,
+				refreshToken
+			)
 			await utilsHelper.redisDel(encryptedEmailId)
 
 			//make the user as org admin
@@ -358,10 +370,11 @@ module.exports = class AccountHelper {
 	 * @param {Object} bodyData -request body contains user login deatils.
 	 * @param {String} bodyData.email - user email.
 	 * @param {String} bodyData.password - user password.
+	 * @param {Object} deviceInformation - device information
 	 * @returns {JSON} - returns susccess or failure of login details.
 	 */
 
-	static async login(bodyData) {
+	static async login(bodyData, deviceInformation) {
 		try {
 			const plaintextEmailId = bodyData.email.toLowerCase()
 			const encryptedEmailId = emailEncryption.encrypt(plaintextEmailId)
@@ -391,6 +404,17 @@ module.exports = class AccountHelper {
 					responseCode: 'CLIENT_ERROR',
 				})
 			}
+			// check if login is allowed or not
+			if (process.env.ALLOWED_ACTIVE_SESSIONS != null) {
+				const activeSessionCount = await userSessionsService.activeUserSessionCounts(user.id)
+				if (activeSessionCount >= process.env.ALLOWED_ACTIVE_SESSIONS) {
+					return responses.failureResponse({
+						message: 'ACTIVE_SESSION_LIMIT_EXCEEDED',
+						statusCode: httpStatusCode.not_acceptable,
+						responseCode: 'CLIENT_ERROR',
+					})
+				}
+			}
 
 			let roles = await roleQueries.findAll(
 				{ id: user.roles, status: common.ACTIVE_STATUS },
@@ -419,10 +443,19 @@ module.exports = class AccountHelper {
 				})
 			}
 
+			// create user session entry and add session_id to token data
+			const userSessionDetails = await userSessionsService.createUserSession(
+				user.id, // userid
+				'', // refresh token
+				'', // Access token
+				deviceInformation
+			)
+
 			const tokenDetail = {
 				data: {
 					id: user.id,
 					name: user.name,
+					session_id: userSessionDetails.result.id,
 					organization_id: user.organization_id,
 					roles: roles,
 				},
@@ -439,33 +472,7 @@ module.exports = class AccountHelper {
 				common.refreshTokenExpiry
 			)
 
-			let currentToken = {
-				token: refreshToken,
-				exp: new Date().getTime() + common.refreshTokenExpiryInMs,
-				userId: user.id,
-			}
-
-			let userTokens = user.refresh_tokens ? user.refresh_tokens : []
-			let noOfTokensToKeep = common.refreshTokenLimit - 1
-			let refreshTokens = []
-
-			if (userTokens && userTokens.length >= common.refreshTokenLimit) {
-				refreshTokens = userTokens.splice(-noOfTokensToKeep)
-			} else {
-				refreshTokens = userTokens
-			}
-
-			refreshTokens.push(currentToken)
-
-			const updateParams = {
-				refresh_tokens: refreshTokens,
-				last_logged_in_at: new Date().getTime(),
-			}
-
-			await userQueries.updateUser({ id: user.id, organization_id: user.organization_id }, updateParams)
-
 			delete user.password
-			delete user.refresh_tokens
 
 			//Change to
 			let defaultOrg = await organizationQueries.findOne(
@@ -492,6 +499,17 @@ module.exports = class AccountHelper {
 			user.email = plaintextEmailId
 			const result = { access_token: accessToken, refresh_token: refreshToken, user }
 
+			/**
+			 * This function call will do below things
+			 * 1: create redis entry for the session
+			 * 2: update user-session with token and refresh_token
+			 */
+			await userSessionsService.updateUserSessionAndsetRedisData(
+				userSessionDetails.result.id,
+				accessToken,
+				refreshToken
+			)
+
 			return responses.successResponse({
 				statusCode: httpStatusCode.ok,
 				message: 'LOGGED_IN_SUCCESSFULLY',
@@ -514,7 +532,7 @@ module.exports = class AccountHelper {
 	 * @returns {JSON} - returns accounts loggedout information.
 	 */
 
-	static async logout(bodyData, user_id, organization_id) {
+	static async logout(bodyData, user_id, organization_id, userSessionId) {
 		try {
 			const user = await userQueries.findOne({ id: user_id, organization_id })
 			if (!user) {
@@ -524,27 +542,18 @@ module.exports = class AccountHelper {
 					responseCode: 'UNAUTHORIZED',
 				})
 			}
-
-			let refreshTokens = user.refresh_tokens ? user.refresh_tokens : []
-			refreshTokens = refreshTokens.filter(function (tokenData) {
-				return tokenData.token !== bodyData.refresh_token
-			})
-
-			/* Destroy refresh token for user */
-			const [affectedRows, updatedData] = await userQueries.updateUser(
-				{ id: user.id, organization_id: user.organization_id },
-				{ refresh_tokens: refreshTokens }
-			)
-
-			/* If user doc not updated because of stored token does not matched with bodyData.refreshToken */
-			if (affectedRows == 0) {
-				return responses.failureResponse({
-					message: 'INVALID_REFRESH_TOKEN',
-					statusCode: httpStatusCode.unauthorized,
-					responseCode: 'UNAUTHORIZED',
-				})
+			/**
+			 * Aquire user session_id based on the requests
+			 */
+			let userSessions = []
+			if (bodyData.userSessionIds && bodyData.userSessionIds.length > 0) {
+				userSessions = bodyData.userSessionIds
+			} else {
+				userSessions.push(userSessionId)
 			}
 
+			await userSessionsService.removeUserSessions(userSessions)
+
 			return responses.successResponse({
 				statusCode: httpStatusCode.ok,
 				message: 'LOGGED_OUT_SUCCESSFULLY',
@@ -586,17 +595,36 @@ module.exports = class AccountHelper {
 			})
 		}
 
-		/* Check valid refresh token stored in db */
-		if (!user.refresh_tokens.length) {
-			return responses.failureResponse({
-				message: 'REFRESH_TOKEN_NOT_FOUND',
-				statusCode: httpStatusCode.unauthorized,
-				responseCode: 'CLIENT_ERROR',
-			})
+		/* check if redis data is present*/
+		// Get redis key for session
+		const sessionId = decodedToken.data.session_id.toString()
+
+		// Get data from redis
+		let redisData = {}
+		redisData = await utilsHelper.redisGet(sessionId)
+
+		// if idle time set to infinity then db check should be done
+		if (!redisData && process.env.ALLOWED_IDLE_TIME == null) {
+			const userSessionData = await userSessionsService.findUserSession(
+				{
+					id: decodedToken.data.session_id,
+				},
+				{
+					attributes: ['refresh_token'],
+				}
+			)
+			if (!userSessionData) {
+				return responses.failureResponse({
+					message: 'REFRESH_TOKEN_NOT_FOUND',
+					statusCode: httpStatusCode.unauthorized,
+					responseCode: 'CLIENT_ERROR',
+				})
+			}
+			redisData.refreshToken = userSessionData[0].refresh_token
 		}
 
-		const token = user.refresh_tokens.find((tokenData) => tokenData.token === bodyData.refresh_token)
-		if (!token) {
+		// If data is not in redis, token is invalid
+		if (!redisData || redisData.refreshToken !== bodyData.refresh_token) {
 			return responses.failureResponse({
 				message: 'REFRESH_TOKEN_NOT_FOUND',
 				statusCode: httpStatusCode.unauthorized,
@@ -611,6 +639,26 @@ module.exports = class AccountHelper {
 			common.accessTokenExpiry
 		)
 
+		/**
+		 * When idle tine is infinity set TTL to access token expiry
+		 * If not redis data won't expire and timeout session will show as active in listing
+		 */
+		let expiryTime = process.env.ALLOWED_IDLE_TIME
+		if (process.env.ALLOWED_IDLE_TIME == null) {
+			expiryTime = utilsHelper.convertDurationToSeconds(common.accessTokenExpiry)
+		}
+		redisData.accessToken = accessToken
+		const res = await utilsHelper.redisSet(sessionId, redisData, expiryTime)
+
+		// update user-sessions with access token
+		let check = await userSessionsService.updateUserSession(
+			{
+				id: decodedToken.data.id,
+			},
+			{
+				token: accessToken,
+			}
+		)
 		return responses.successResponse({
 			statusCode: httpStatusCode.ok,
 			message: 'ACCESS_TOKEN_GENERATED_SUCCESSFULLY',
@@ -785,7 +833,7 @@ module.exports = class AccountHelper {
 	 * @returns {JSON} - returns password reset response
 	 */
 
-	static async resetPassword(bodyData) {
+	static async resetPassword(bodyData, deviceInfo) {
 		const projection = ['location']
 		try {
 			const plaintextEmailId = bodyData.email.toLowerCase()
@@ -845,43 +893,35 @@ module.exports = class AccountHelper {
 				})
 			}
 			bodyData.password = utilsHelper.hashPassword(bodyData.password)
+
+			// create user session entry and add session_id to token data
+			const userSessionDetails = await userSessionsService.createUserSession(
+				user.id, // userid
+				'', // refresh token
+				'', // Access token
+				deviceInfo
+			)
 			const tokenDetail = {
 				data: {
 					id: user.id,
 					name: user.name,
+					session_id: userSessionDetails.result.id,
 					organization_id: user.organization_id,
 					roles,
 				},
 			}
 
-			const accessToken = utilsHelper.generateToken(tokenDetail, process.env.ACCESS_TOKEN_SECRET, '1d')
-			const refreshToken = utilsHelper.generateToken(tokenDetail, process.env.REFRESH_TOKEN_SECRET, '183d')
-
-			let currentToken = {
-				token: refreshToken,
-				exp: new Date().getTime() + common.refreshTokenExpiryInMs,
-				userId: user.id,
-			}
-
-			let userTokens = user.refresh_tokens ? user.refresh_tokens : []
-			let noOfTokensToKeep = common.refreshTokenLimit - 1
-			let refreshTokens = []
-
-			if (userTokens && userTokens.length >= common.refreshTokenLimit)
-				refreshTokens = userTokens.splice(-noOfTokensToKeep)
-			else refreshTokens = userTokens
-
-			refreshTokens.push(currentToken)
-			const updateParams = {
-				refresh_tokens: refreshTokens,
-				lastLoggedInAt: new Date().getTime(),
-				password: bodyData.password,
-			}
-
-			await userQueries.updateUser(
-				{ id: user.id, organization_id: userCredentials.organization_id },
-				updateParams
+			const accessToken = utilsHelper.generateToken(
+				tokenDetail,
+				process.env.ACCESS_TOKEN_SECRET,
+				common.accessTokenExpiry
 			)
+			const refreshToken = utilsHelper.generateToken(
+				tokenDetail,
+				process.env.REFRESH_TOKEN_SECRET,
+				common.refreshTokenExpiry
+			)
+
 			await UserCredentialQueries.updateUser(
 				{
 					email: encryptedEmailId,
@@ -917,6 +957,18 @@ module.exports = class AccountHelper {
 			}
 			user.email = plaintextEmailId
 
+			/**update a new session entry with redis insert */
+			/**
+			 * This function call will do below things
+			 * 1: create redis entry for the session
+			 * 2: update user-session with token and refresh_token
+			 */
+			await userSessionsService.updateUserSessionAndsetRedisData(
+				userSessionDetails.result.id,
+				accessToken,
+				refreshToken
+			)
+
 			const result = { access_token: accessToken, refresh_token: refreshToken, user }
 			return responses.successResponse({
 				statusCode: httpStatusCode.ok,
@@ -1311,7 +1363,7 @@ module.exports = class AccountHelper {
 			}
 			bodyData.newPassword = utilsHelper.hashPassword(bodyData.newPassword)
 
-			const updateParams = { password: bodyData.newPassword }
+			const updateParams = { password: bodyData.newPassword, refresh_tokens: [] }
 
 			await userQueries.updateUser(
 				{ id: user.id, organization_id: userCredentials.organization_id },
@@ -1320,6 +1372,23 @@ module.exports = class AccountHelper {
 			await UserCredentialQueries.updateUser({ email: userCredentials.email }, { password: bodyData.newPassword })
 			await utilsHelper.redisDel(userCredentials.email)
 
+			// Find active sessions of user and remove them
+			const userSessionData = await userSessionsService.findUserSession(
+				{
+					user_id: userId,
+					ended_at: null,
+				},
+				{
+					attributes: ['id'],
+				}
+			)
+			const userSessionIds = userSessionData.map(({ id }) => id)
+			/**
+			 * 1: Remove redis data
+			 * 2: Update ended_at in user-sessions
+			 */
+			await userSessionsService.removeUserSessions(userSessionIds)
+
 			const templateData = await notificationTemplateQueries.findOneEmailTemplate(
 				process.env.CHANGE_PASSWORD_TEMPLATE_CODE
 			)
diff --git a/src/services/admin.js b/src/services/admin.js
index f367d071d..42a5276d7 100644
--- a/src/services/admin.js
+++ b/src/services/admin.js
@@ -20,6 +20,7 @@ const UserCredentialQueries = require('@database/queries/userCredential')
 const adminService = require('../generics/materializedViews')
 const emailEncryption = require('@utils/emailEncryption')
 const responses = require('@helpers/responses')
+const userSessionsService = require('@services/user-sessions')
 
 module.exports = class AdminHelper {
 	/**
@@ -49,6 +50,21 @@ module.exports = class AdminHelper {
 
 			await utils.redisDel(common.redisUserPrefix + userId.toString())
 
+			/**
+			 * Using userId get his active sessions
+			 */
+			const userSessionData = await userSessionsService.findUserSession(
+				{
+					user_id: userId,
+					ended_at: null,
+				},
+				{
+					attributes: ['id'],
+				}
+			)
+			const userSessionIds = userSessionData.map(({ id }) => id)
+			await userSessionsService.removeUserSessions(userSessionIds)
+
 			//code for remove user folder from cloud
 
 			return responses.successResponse({
@@ -136,9 +152,10 @@ module.exports = class AdminHelper {
 	 * @param {Object} bodyData - user login data.
 	 * @param {string} bodyData.email - email.
 	 * @param {string} bodyData.password - email.
+	 * @param {string} deviceInformation - device information.
 	 * @returns {JSON} - returns login response
 	 */
-	static async login(bodyData) {
+	static async login(bodyData, deviceInformation) {
 		try {
 			const plaintextEmailId = bodyData.email.toLowerCase()
 			const encryptedEmailId = emailEncryption.encrypt(plaintextEmailId)
@@ -187,10 +204,19 @@ module.exports = class AdminHelper {
 				})
 			}
 
+			// create user session entry and add session_id to token data
+			const userSessionDetails = await userSessionsService.createUserSession(
+				user.id, // userid
+				'', // refresh token
+				'', // Access token
+				deviceInformation
+			)
+
 			const tokenDetail = {
 				data: {
 					id: user.id,
 					name: user.name,
+					session_id: userSessionDetails.result.id,
 					organization_id: user.organization_id,
 					roles: roles,
 				},
@@ -198,8 +224,27 @@ module.exports = class AdminHelper {
 
 			user.user_roles = roles
 
-			const accessToken = utils.generateToken(tokenDetail, process.env.ACCESS_TOKEN_SECRET, '1d')
-			const refreshToken = utils.generateToken(tokenDetail, process.env.REFRESH_TOKEN_SECRET, '183d')
+			const accessToken = utils.generateToken(
+				tokenDetail,
+				process.env.ACCESS_TOKEN_SECRET,
+				common.accessTokenExpiry
+			)
+			const refreshToken = utils.generateToken(
+				tokenDetail,
+				process.env.REFRESH_TOKEN_SECRET,
+				common.refreshTokenExpiry
+			)
+
+			/**
+			 * This function call will do below things
+			 * 1: create redis entry for the session
+			 * 2: update user-session with token and refresh_token
+			 */
+			await userSessionsService.updateUserSessionAndsetRedisData(
+				userSessionDetails.result.id,
+				accessToken,
+				refreshToken
+			)
 
 			delete user.password
 			const result = { access_token: accessToken, refresh_token: refreshToken, user }
@@ -551,11 +596,9 @@ function _removeUserKeys() {
 		'gender',
 		'about',
 		'share_link',
-		'last_logged_in_at',
 		'preferred_language',
 		'location',
 		'languages',
-		'refresh_tokens',
 		'image',
 		'roles',
 	]
diff --git a/src/services/user-sessions.js b/src/services/user-sessions.js
new file mode 100644
index 000000000..64b60a058
--- /dev/null
+++ b/src/services/user-sessions.js
@@ -0,0 +1,346 @@
+/**
+ * name         : services/user-sessions.js
+ * author       : Vishnu
+ * created-date : 26-Mar-2024
+ * Description  : user-sessions business logic.
+ */
+
+// Dependencies
+const userSessionsQueries = require('@database/queries/user-sessions')
+const utilsHelper = require('@generics/utils')
+const httpStatusCode = require('@generics/http-status')
+const responses = require('@helpers/responses')
+const common = require('@constants/common')
+const jwt = require('jsonwebtoken')
+
+// create user-session
+module.exports = class UserSessionsHelper {
+	/**
+	 * Create a user session.
+	 * @param {number} userId - The ID of the user.
+	 * @param {string} [refreshToken=''] - Optional. The refresh token associated with the session.
+	 * @param {string} [accessToken=''] - Optional. The access token associated with the session.
+	 * @param {Object} deviceInfo - Information about the device used for the session.
+	 * @returns {Promise<Object>} - A promise that resolves to a success response with the created session details.
+	 * @throws {Error} - Throws an error if any issue occurs during the process.
+	 */
+
+	static async createUserSession(userId, refreshToken = '', accessToken = '', deviceInfo) {
+		try {
+			/**
+			 * data for user-session creation
+			 */
+			const userSessionDetails = {
+				user_id: userId,
+				device_info: deviceInfo,
+				started_at: Math.floor(new Date().getTime() / 1000),
+			}
+			if (accessToken !== '') {
+				userSessionDetails.token = accessToken
+			}
+			if (accessToken !== '') {
+				userSessionDetails.refresh_token = refreshToken
+			}
+
+			// create userSession
+			const userSession = await userSessionsQueries.create(userSessionDetails)
+
+			return responses.successResponse({
+				statusCode: httpStatusCode.created,
+				message: 'USER_SESSION_CREATED_SUCCESSFULLY',
+				result: userSession,
+			})
+		} catch (error) {
+			console.log(error)
+			throw error
+		}
+	}
+
+	/**
+	 * Update a user session.
+	 * @param {Object} filter - The filter criteria to select the user session(s) to update.
+	 * @param {Object} update - The data to be updated for the user session(s).
+	 * @param {Object} [options={}] - Optional. Additional options for the update operation.
+	 * @returns {Promise<Object>} - A promise that resolves to a success response with the updated session details.
+	 * @throws {Error} - Throws an error if any issue occurs during the process.
+	 */
+
+	static async updateUserSession(filter, update, options = {}) {
+		try {
+			const result = await userSessionsQueries.update(filter, update, options)
+			return responses.successResponse({
+				statusCode: httpStatusCode.ok,
+				message: 'USER_SESSION_UPDATED_SUCCESSFULLY',
+				result: result,
+			})
+		} catch (error) {
+			throw error
+		}
+	}
+
+	/**
+	 * Retrieve user sessions based on user ID, status, limit, and page.
+	 * @param {number} userId - The ID of the user.
+	 * @param {string} status - The status of the user sessions (e.g., 'ACTIVE', '').
+	 * @param {number} limit - The maximum number of user sessions to retrieve per page.
+	 * @param {number} page - The page number for pagination.
+	 * @returns {Promise<Object>} - A promise that resolves to the user session details.
+	 */
+
+	static async list(userId, status, limit, page) {
+		try {
+			const filter = {
+				user_id: userId,
+			}
+			const offset = (page - 1) * limit
+
+			// If ended at is null, the status can be active. after verification with redis we can confirm
+			if (status === common.ACTIVE_STATUS) {
+				filter.ended_at = null
+			}
+
+			// create userSession
+			const userSessions = await userSessionsQueries.findAll(filter)
+			const activeSessions = []
+			const inActiveSessions = []
+			for (const session of userSessions) {
+				const id = session.id.toString() // Convert ID to string
+				const redisData = await utilsHelper.redisGet(id)
+				let statusToSend = status
+				if (redisData === null) {
+					if (status === common.ACTIVE_STATUS) {
+						continue // Skip this element if data is not in Redis and status is active
+					} else {
+						session.ended_at == null
+							? (statusToSend = common.EXPIRED_STATUS)
+							: (statusToSend = common.INACTIVE_STATUS)
+					}
+				} else {
+					statusToSend = common.ACTIVE_STATUS
+				}
+
+				if (status === common.ACTIVE_STATUS && statusToSend === common.ACTIVE_STATUS) {
+					const responseObj = {
+						id: session.id,
+						device_info: session.device_info,
+						status: statusToSend,
+						login_time: session.started_at,
+						logout_time: session.ended_at,
+					}
+					activeSessions.push(responseObj)
+				} else if (status === '') {
+					const responseObj = {
+						id: session.id,
+						device_info: session.device_info,
+						status: statusToSend,
+						login_time: session.started_at,
+						logout_time: session.ended_at,
+					}
+					responseObj.status === common.ACTIVE_STATUS
+						? activeSessions.push(responseObj)
+						: inActiveSessions.push(responseObj)
+				}
+			}
+
+			const result = [...activeSessions, ...inActiveSessions]
+
+			// Paginate the result array
+			// The response is accumulated from two places. db and redis. So pagination is not possible on the fly
+			const paginatedResult = result.slice(offset, offset + limit)
+
+			return responses.successResponse({
+				statusCode: httpStatusCode.created,
+				message: 'USER_SESSION_FETCHED_SUCCESSFULLY',
+				result: {
+					data: paginatedResult,
+					count: result.length,
+				},
+			})
+		} catch (error) {
+			throw error
+		}
+	}
+
+	/**
+	 * Remove user sessions from both database and Redis.
+	 * @param {number[]} userSessionIds - An array of user session IDs to be removed.
+	 * @returns {Promise<Object>} - A promise that resolves to a success response upon successful removal.
+	 */
+
+	static async removeUserSessions(userSessionIds) {
+		try {
+			// Delete user sessions from Redis
+			for (const sessionId of userSessionIds) {
+				await utilsHelper.redisDel(sessionId.toString())
+			}
+
+			// Update ended_at of user sessions in the database
+			const currentTime = Math.floor(Date.now() / 1000) // Current epoch time in seconds
+			const updateResult = await userSessionsQueries.update({ id: userSessionIds }, { ended_at: currentTime })
+
+			// Check if the update was successful
+			if (updateResult instanceof Error) {
+				throw updateResult // Throw error if update failed
+			}
+
+			// Return success response
+			const result = {}
+			return responses.successResponse({
+				statusCode: httpStatusCode.ok,
+				message: 'USER_SESSIONS_REMOVED_SUCCESSFULLY',
+				result,
+			})
+		} catch (error) {
+			throw error
+		}
+	}
+
+	/**
+	 * Find user sessions based on the provided filter and options.
+	 * @param {Object} filter - The filter criteria to find user sessions.
+	 * @param {Object} [options={}] - Optional. Additional options for the query.
+	 * @returns {Promise<Object[]>} - A promise that resolves to an array of user session objects.
+	 * @throws {Error} - Throws an error if any issue occurs during the process.
+	 */
+	static async findUserSession(filter, options = {}) {
+		try {
+			return await userSessionsQueries.findAll(filter, options)
+		} catch (error) {
+			throw error
+		}
+	}
+
+	/**
+	 * Validate the user session token.
+	 * @param {string} token - The token to validate.
+	 * @returns {Promise<Object>} - A promise that resolves to a success response if the token is valid, otherwise throws an error.
+	 * @throws {Error} - Throws an error if the token validation fails.
+	 */
+
+	static async validateUserSession(token) {
+		// token validation failure message
+		const unAuthorizedResponse = responses.failureResponse({
+			message: 'UNAUTHORIZED_REQUEST',
+			statusCode: httpStatusCode.unauthorized,
+			responseCode: 'UNAUTHORIZED',
+		})
+
+		const tokenArray = token.split(' ')
+
+		// If not bearer throw error
+		if (tokenArray[0] !== 'bearer') {
+			throw unAuthorizedResponse
+		}
+		try {
+			const decodedToken = jwt.verify(tokenArray[1], process.env.ACCESS_TOKEN_SECRET)
+			const sessionId = decodedToken.data.session_id.toString()
+
+			const redisData = await utilsHelper.redisGet(sessionId)
+
+			// If data is not in redis, token is invalid
+			if (!redisData || redisData.accessToken !== tokenArray[1]) {
+				throw unAuthorizedResponse
+			}
+
+			// Renew the TTL if allowed idle is not infinite
+			if (process.env.ALLOWED_IDLE_TIME != null) {
+				await utilsHelper.redisSet(sessionId, redisData, process.env.ALLOWED_IDLE_TIME)
+			}
+
+			return responses.successResponse({
+				statusCode: httpStatusCode.ok,
+				message: 'USER_SESSION_VALIDATED_SUCCESSFULLY',
+				result: {
+					data: {
+						user_session_active: true,
+					},
+				},
+			})
+		} catch (err) {
+			throw unAuthorizedResponse
+		}
+	}
+
+	/**
+	 * Update the user session with access token and refresh token, and set the data in Redis.
+	 * @param {number} userSessionId - The ID of the user session to update.
+	 * @param {string} accessToken - The new access token.
+	 * @param {string} refreshToken - The new refresh token.
+	 * @returns {Promise<Object>} - A promise that resolves to a success response after updating the user session and setting data in Redis.
+	 * @throws {Error} - Throws an error if the update operation fails.
+	 */
+	static async updateUserSessionAndsetRedisData(userSessionId, accessToken, refreshToken) {
+		try {
+			// update user-sessions with refresh token and access token
+			await this.updateUserSession(
+				{
+					id: userSessionId,
+				},
+				{
+					token: accessToken,
+					refresh_token: refreshToken,
+				}
+			)
+
+			// save data in redis against session_id, write a function for this
+			const redisData = {
+				accessToken: accessToken,
+				refreshToken: refreshToken,
+			}
+			/** Allowed idle time set to zero (infinity indicator here)
+			 * set TTL of redis to accessTokenExpiry.
+			 * Else it will be there in redis permenantly and will affect listing of user sessions
+			 */
+
+			let expiryTime = process.env.ALLOWED_IDLE_TIME
+			if (process.env.ALLOWED_IDLE_TIME == null) {
+				expiryTime = utilsHelper.convertDurationToSeconds(common.accessTokenExpiry)
+			}
+			const redisKey = userSessionId.toString()
+			await utilsHelper.redisSet(redisKey, redisData, expiryTime)
+
+			const result = {}
+			return responses.successResponse({
+				statusCode: httpStatusCode.ok,
+				message: 'USER_SESSION_UPDATED_CESSFULLY',
+				result,
+			})
+		} catch (error) {
+			throw error
+		}
+	}
+
+	/**
+	 * Retrieve the count of active user sessions for a given userId.
+	 * @param {number} userId - The ID of the user for which to retrieve active sessions.
+	 * @returns {Promise<number>} - A Promise that resolves to the count of active user sessions.
+	 * @throws {Error} - If an error occurs while retrieving the count of active user sessions.
+	 */
+	static async activeUserSessionCounts(userId) {
+		try {
+			// Define filter criteria
+			const filterQuery = {
+				user_id: userId,
+				ended_at: null,
+			}
+
+			// Fetch user sessions based on filter criteria
+			const userSessions = await userSessionsQueries.findAll(filterQuery)
+
+			// Initialize count of active sessions
+			let activeSession = 0
+
+			// Loop through user sessions and check if each session exists in Redis
+			for (const session of userSessions) {
+				const id = session.id.toString()
+				const redisData = await utilsHelper.redisGet(id)
+				if (redisData !== null) {
+					activeSession++
+				}
+			}
+			return activeSession
+		} catch (error) {
+			throw error
+		}
+	}
+}
diff --git a/src/validators/v1/organization.js b/src/validators/v1/organization.js
index 9a0bcf838..dfb6b6f2d 100644
--- a/src/validators/v1/organization.js
+++ b/src/validators/v1/organization.js
@@ -21,8 +21,7 @@ module.exports = {
 			.trim()
 			.notEmpty()
 			.withMessage('description field is empty')
-			.not()
-			.matches(/(\b)(on\S+)(\s*)=|javascript:|<(|\/|[^\/>][^>]+|\/[^>][^>]+)>/gi)
+			.matches(/^[a-zA-Z0-9\-.,\s]+$/)
 			.withMessage('invalid description')
 		req.checkBody('domains').trim().notEmpty().withMessage('domains field is empty')
 	},
@@ -43,8 +42,7 @@ module.exports = {
 			.trim()
 			.notEmpty()
 			.withMessage('description field is empty')
-			.not()
-			.matches(/(\b)(on\S+)(\s*)=|javascript:|<(|\/|[^\/>][^>]+|\/[^>][^>]+)>/gi)
+			.matches(/^[a-zA-Z0-9\-.,\s]+$/)
 			.withMessage('invalid description')
 	},
 
diff --git a/src/validators/v1/user.js b/src/validators/v1/user.js
index a0ceb2c2f..91c49f40b 100644
--- a/src/validators/v1/user.js
+++ b/src/validators/v1/user.js
@@ -38,8 +38,7 @@ module.exports = {
 				.trim()
 				.notEmpty()
 				.withMessage('about field is empty')
-				.not()
-				.matches(/(\b)(on\S+)(\s*)=|javascript:|<(|\/|[^\/>][^>]+|\/[^>][^>]+)>/gi)
+				.matches(/^[a-zA-Z0-9\-.,\s]+$/)
 				.withMessage('invalid about')
 
 			req.checkBody('has_accepted_terms_and_conditions')