keycloak/js/libs/keycloak-admin-client/test/attackDetection.spec.ts
Peter Skopek d11136f671 Separate password and OTP brute force protection to prevent OTP bypass attacks by default
Closes #46164

Signed-off-by: Peter Skopek <peter.skopek@ibm.com>

Update model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/changes/remote/updater/loginfailures/LoginFailuresUpdater.java

Co-authored-by: Pedro Ruivo <pruivo@users.noreply.github.com>
Signed-off-by: Peter Skopek <peter.skopek@ibm.com>

Add recovery codes to the list of brute force checked authenticators.

Closes #46164
Signed-off-by: Peter Skopek <peter.skopek@ibm.com>
2026-03-17 18:57:37 +01:00

50 lines
1.4 KiB
TypeScript

// tslint:disable:no-unused-expression
import { faker } from "@faker-js/faker";
import * as chai from "chai";
import { KeycloakAdminClient } from "../src/client.js";
import type UserRepresentation from "../src/defs/userRepresentation.js";
import { credentials } from "./constants.js";
const expect = chai.expect;
describe("Attack Detection", () => {
let kcAdminClient: KeycloakAdminClient;
let currentUser: UserRepresentation;
before(async () => {
kcAdminClient = new KeycloakAdminClient();
await kcAdminClient.auth(credentials);
const username = faker.internet.username();
currentUser = await kcAdminClient.users.create({
username,
});
});
after(async () => {
await kcAdminClient.users.del({ id: currentUser.id! });
});
it("list attack detection for user", async () => {
const attackDetection = await kcAdminClient.attackDetection.findOne({
id: currentUser.id!,
});
expect(attackDetection).to.deep.equal({
numFailures: 0,
numSecondaryAuthFailures: 0,
disabled: false,
lastIPFailure: "n/a",
lastFailure: 0,
numTemporaryLockouts: 0,
failedLoginNotBefore: 0,
});
});
it("clear any user login failures for all users", async () => {
await kcAdminClient.attackDetection.delAll();
});
it("clear any user login failures for a user", async () => {
await kcAdminClient.attackDetection.del({ id: currentUser.id! });
});
});