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:
@@ -0,0 +1,23 @@
|
||||
const mockRedis = { set: jest.fn(), eval: jest.fn() };
|
||||
jest.mock("../../app/config/redisClient", () => mockRedis);
|
||||
const { generateOtp, otpHash, createLoginChallenge, verifyLoginChallenge } = require("../../app/services/auth/otp.service");
|
||||
|
||||
describe("login OTP service", () => {
|
||||
beforeEach(() => jest.clearAllMocks());
|
||||
test("generates six numeric digits cryptographically", () => expect(generateOtp()).toMatch(/^\d{6}$/));
|
||||
test("stores only an OTP hash with TTL", async () => {
|
||||
const result = await createLoginChallenge({ userId: "usr-1", rememberMe: true, context: {} });
|
||||
const stored = JSON.parse(mockRedis.set.mock.calls[0][1]);
|
||||
expect(stored.otpHash).toHaveLength(64);
|
||||
expect(stored.otp).toBeUndefined();
|
||||
expect(mockRedis.set.mock.calls[0]).toEqual(expect.arrayContaining(["EX", 900]));
|
||||
expect(result.otp).toMatch(/^\d{6}$/);
|
||||
expect(stored.otpHash).toBe(otpHash(result.challengeId, result.otp));
|
||||
});
|
||||
test("maps invalid, exhausted, and expired challenges to a generic failure", async () => {
|
||||
for (const code of [-1, -2, -3]) {
|
||||
mockRedis.eval.mockResolvedValueOnce([code]);
|
||||
await expect(verifyLoginChallenge("00000000-0000-4000-8000-000000000000", "000000")).rejects.toMatchObject({ code: "INVALID_OTP", status: 401 });
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user