feat: Implement stayLoggedIn functionality for JWT authentication

This commit is contained in:
StarAppeal
2025-09-29 09:36:36 +02:00
parent 7acec25f84
commit a3a34b3576
7 changed files with 73 additions and 8542 deletions
+29 -2
View File
@@ -4,7 +4,6 @@ import express from "express";
import {RestAuth} from "../../src/rest/auth";
import {JwtAuthenticator} from "../../src/utils/jwtAuthenticator";
import {PasswordUtils} from "../../src/utils/passwordUtils";
// @ts-ignore
import {createMockJwtAuthenticator, createMockUserService, createPublicTestApp} from "../helpers/testSetup";
import crypto from "crypto";
@@ -172,7 +171,7 @@ describe("RestAuth", () => {
username: "testuser",
id: "user-id-123",
uuid: "uuid-123",
});
}, 24 * 60 * 60 * 1000);
const cookieHeader = response.headers['set-cookie'];
expect(cookieHeader).toBeDefined();
@@ -187,6 +186,34 @@ describe("RestAuth", () => {
expect(authTokenCookie).toContain("SameSite=Lax");
});
it("should login with longer token validity when stayLoggedIn is true", async () => {
const mockUser = {name: "testuser", password: "hashed", uuid: "uuid-123", id: "user-id-123"};
const mockToken = "jwt-token-123";
const loginDataWithStayLoggedIn = { ...validLoginData, stayLoggedIn: true };
mockUserService.getUserAuthByName.mockResolvedValue(mockUser);
mockPasswordUtils.comparePassword.mockResolvedValue(true);
mockJwtAuthenticator.generateToken.mockReturnValue(mockToken);
const response = await request(app).post("/auth/login").send(loginDataWithStayLoggedIn).expect(200);
expect(response.body.ok).toBe(true);
expect(response.body.data.token).toBe(mockToken);
expect(mockJwtAuthenticator.generateToken).toHaveBeenCalledWith({
username: "testuser",
id: "user-id-123",
uuid: "uuid-123",
}, 30 * 24 * 60 * 60 * 1000);
const cookieHeader = response.headers['set-cookie'];
expect(cookieHeader).toBeDefined();
const cookies = Array.isArray(cookieHeader) ? cookieHeader : [cookieHeader!];
const authTokenCookie = cookies.find((cookie: string) => cookie.startsWith("auth-token="));
expect(authTokenCookie).toBeDefined();
expect(authTokenCookie).toContain(`auth-token=${mockToken}`);
});
describe("POST /logout", () => {
it("should clear the auth-token cookie and return a success message", async () => {
const response = await request(app).post("/auth/logout").send().expect(200);
+11 -1
View File
@@ -64,7 +64,17 @@ describe("JwtAuthenticator", () => {
const payload = { username: "bob" } as any;
const token = auth.generateToken(payload);
expect(jwt.sign).toHaveBeenCalledWith(payload, secret);
expect(jwt.sign).toHaveBeenCalledWith(payload, secret, {});
expect(token).toBe("signed.jwt");
});
it("generateToken signs payload with expiry when expiresInMs is provided", () => {
(jwt.sign as any).mockReturnValue("signed.jwt");
const payload = { username: "bob" } as any;
const expiresInMs = 24 * 60 * 60 * 1000;
const token = auth.generateToken(payload, expiresInMs);
expect(jwt.sign).toHaveBeenCalledWith(payload, secret, { expiresIn: 86400 }); // 86400 Sekunden = 1 Tag
expect(token).toBe("signed.jwt");
});
});