feat: implement identity and security features

- Added account types and privileged account types constants.
- Created admin user controller for updating user security fields.
- Developed role assignment controller for managing user roles.
- Implemented validation middleware for request schemas.
- Defined user role and auth session models for database interactions.
- Created services for authentication, email notifications, and OTP handling.
- Developed OAuth service for Google and Apple authentication.
- Added JWT utility functions for token generation and verification.
- Implemented comprehensive tests for authentication, session management, and password policies.
- Created migration for updating user schema and adding new tables for auth sessions and user identities.
This commit is contained in:
Sathira Sri Sathara
2026-09-03 13:56:18 +05:30
parent 267e80e2ec
commit 9d3d431416
54 changed files with 1389 additions and 1076 deletions
+15 -1
View File
@@ -16,6 +16,8 @@ const hashEmailVerificationToken = (token) => {
};
const createEmailVerification = async (userId) => {
const previousKey = await redis.get(`email-verification-user:${userId}`);
if (previousKey) await redis.del(previousKey);
// 1. Generate raw token
const token = generateEmailVerificationToken();
@@ -26,6 +28,7 @@ const createEmailVerification = async (userId) => {
const redisKey = `email-verification:${tokenHash}`;
await redis.set(redisKey, userId, "EX", EMAIL_VERIFICATION_TTL);
await redis.set(`email-verification-user:${userId}`, redisKey, "EX", EMAIL_VERIFICATION_TTL);
return token;
};
@@ -45,12 +48,14 @@ const verifyEmailVerificationToken = async (token) => {
const redisKey = `email-verification:${tokenHash}`;
// 3. Search Redis
const userId = await redis.get(redisKey);
const userId = await redis.getdel(redisKey);
if (!userId) {
return null;
}
await redis.del(`email-verification-user:${userId}`);
return {
userId,
redisKey,
@@ -82,10 +87,19 @@ const deleteEmailVerification = async (redisKey) => {
await redis.del(redisKey);
};
const consumeEmailVerificationToken = async (token) => {
if (!token || typeof token !== "string") return null;
const redisKey = `email-verification:${hashEmailVerificationToken(token)}`;
const userId = await redis.getdel(redisKey);
if (userId) await redis.del(`email-verification-user:${userId}`);
return userId;
};
module.exports = {
createEmailVerification,
verifyEmailVerificationToken,
sendVerificationEmail,
deleteEmailVerification,
consumeEmailVerificationToken,
hashEmailVerificationToken,
};