mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
Migrate more tests to mocha.
This commit is contained in:
parent
7c2fd91271
commit
c487ed0a37
|
@ -110,6 +110,7 @@
|
|||
"should": "^13.2.1",
|
||||
"sinon": "^5.0.7",
|
||||
"tmp": "0.0.33",
|
||||
"tree-kill": "^1.2.1",
|
||||
"ts-node": "^6.0.1",
|
||||
"tslint": "^5.2.0",
|
||||
"typescript": "^2.9.2",
|
||||
|
|
|
@ -4,6 +4,7 @@ var program = require('commander');
|
|||
var spawn = require('child_process').spawn;
|
||||
var chokidar = require('chokidar');
|
||||
var fs = require('fs');
|
||||
var kill = require('tree-kill');
|
||||
|
||||
program
|
||||
.option('-s, --suite <suite>', 'The suite to run Authelia for. This suite represents a configuration for Authelia and a set of tests for that configuration.')
|
||||
|
@ -14,17 +15,18 @@ if (!program.suite) {
|
|||
}
|
||||
|
||||
const ENVIRONMENT_FILENAME = '.suite';
|
||||
const AUTHELIA_INTERRUPT_FILENAME = '.authelia-interrupt';
|
||||
|
||||
|
||||
var tsWatcher = chokidar.watch(['server', 'shared/**/*.ts', 'node_modules'], {
|
||||
var tsWatcher = chokidar.watch(['server', 'shared/**/*.ts', 'node_modules', AUTHELIA_INTERRUPT_FILENAME], {
|
||||
persistent: true,
|
||||
ignoreInitial: true,
|
||||
});
|
||||
|
||||
// Properly cleanup server and client if ctrl-c is hit
|
||||
process.on('SIGINT', function() {
|
||||
killServer(() => {});
|
||||
killClient(() => {});
|
||||
killServer();
|
||||
killClient();
|
||||
fs.unlinkSync(ENVIRONMENT_FILENAME);
|
||||
process.exit();
|
||||
});
|
||||
|
@ -38,7 +40,11 @@ function reloadServer() {
|
|||
}
|
||||
|
||||
function startServer() {
|
||||
serverProcess = spawn('./scripts/run-dev-server.sh', [`test/suites/${program.suite}/config.yml`], {detached: true});
|
||||
if (fs.existsSync(AUTHELIA_INTERRUPT_FILENAME)) {
|
||||
console.log('Authelia is interrupted. Consider removing ' + AUTHELIA_INTERRUPT_FILENAME + ' if it\'s not expected.');
|
||||
return;
|
||||
}
|
||||
serverProcess = spawn('./scripts/run-dev-server.sh', [`test/suites/${program.suite}/config.yml`]);
|
||||
serverProcess.stdout.pipe(process.stdout);
|
||||
serverProcess.stderr.pipe(process.stderr);
|
||||
}
|
||||
|
@ -46,7 +52,6 @@ function startServer() {
|
|||
let clientProcess;
|
||||
function startClient() {
|
||||
clientProcess = spawn('npm', ['run', 'start'], {
|
||||
detached: true,
|
||||
cwd: './client',
|
||||
env: {
|
||||
...process.env,
|
||||
|
@ -61,14 +66,16 @@ function killServer(onExit) {
|
|||
if (serverProcess) {
|
||||
serverProcess.on('exit', () => {
|
||||
serverProcess = undefined;
|
||||
onExit();
|
||||
if (onExit) onExit();
|
||||
});
|
||||
try {
|
||||
process.kill(-serverProcess.pid);
|
||||
kill(serverProcess.pid, 'SIGKILL');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
onExit();
|
||||
if (onExit) onExit();
|
||||
}
|
||||
} else {
|
||||
if (onExit) onExit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,14 +83,16 @@ function killClient(onExit) {
|
|||
if (clientProcess) {
|
||||
clientProcess.on('exit', () => {
|
||||
clientProcess = undefined;
|
||||
onExit();
|
||||
if (onExit) onExit();
|
||||
});
|
||||
try {
|
||||
process.kill(-clientProcess.pid);
|
||||
kill(clientProcess.pid, 'SIGKILL');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
onExit();
|
||||
if (onExit) onExit();
|
||||
}
|
||||
} else {
|
||||
if (onExit) onExit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,6 +106,16 @@ function reload(path) {
|
|||
console.log('Schema needs to be regenerated.');
|
||||
generateConfigurationSchema();
|
||||
}
|
||||
else if (path === AUTHELIA_INTERRUPT_FILENAME) {
|
||||
if (fs.existsSync(path)) {
|
||||
console.log('Authelia is being interrupted.');
|
||||
killServer();
|
||||
} else {
|
||||
console.log('Authelia is restarting.');
|
||||
startServer();
|
||||
}
|
||||
return;
|
||||
}
|
||||
reloadServer();
|
||||
}
|
||||
|
||||
|
@ -128,7 +147,7 @@ async function main() {
|
|||
|
||||
console.log('Start watching...');
|
||||
tsWatcher.on('add', reload);
|
||||
tsWatcher.on('remove', reload);
|
||||
tsWatcher.on('unlink', reload);
|
||||
tsWatcher.on('change', reload);
|
||||
|
||||
startServer();
|
||||
|
|
11
server/src/lib/authentication/AuthenticationError.ts
Normal file
11
server/src/lib/authentication/AuthenticationError.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
|
||||
// Error thrown when the authentication failed when checking
|
||||
// user/password.
|
||||
class AuthenticationError extends Error {
|
||||
constructor(msg: string) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
export default AuthenticationError
|
|
@ -8,6 +8,7 @@ import { GroupsAndEmails } from "../GroupsAndEmails";
|
|||
import { IUsersDatabase } from "../IUsersDatabase";
|
||||
import { HashGenerator } from "../../../utils/HashGenerator";
|
||||
import { ReadWriteQueue } from "./ReadWriteQueue";
|
||||
import AuthenticationError from "../../AuthenticationError";
|
||||
|
||||
const loadAsync = Bluebird.promisify(Yaml.load);
|
||||
|
||||
|
@ -80,7 +81,7 @@ export class FileUsersDatabase implements IUsersDatabase {
|
|||
return HashGenerator.ssha512(password, rounds, salt)
|
||||
.then((hash: string) => {
|
||||
if (hash !== storedHash) {
|
||||
return Bluebird.reject(new Error("Wrong username/password."));
|
||||
return Bluebird.reject(new AuthenticationError("Wrong username/password."));
|
||||
}
|
||||
return Bluebird.resolve();
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@ import { LdapConfiguration } from "../../../configuration/schema/LdapConfigurati
|
|||
import { ISession } from "./ISession";
|
||||
import { GroupsAndEmails } from "../GroupsAndEmails";
|
||||
import Exceptions = require("../../../Exceptions");
|
||||
import AuthenticationError from "../../AuthenticationError";
|
||||
|
||||
type SessionCallback<T> = (session: ISession) => Bluebird<T>;
|
||||
|
||||
|
@ -58,7 +59,7 @@ export class LdapUsersDatabase implements IUsersDatabase {
|
|||
.then(() => getInfo(session));
|
||||
})
|
||||
.catch((err) =>
|
||||
Bluebird.reject(new Exceptions.LdapError(err.message)));
|
||||
Bluebird.reject(new AuthenticationError(err.message)));
|
||||
}
|
||||
|
||||
getEmails(username: string): Bluebird<string[]> {
|
||||
|
|
|
@ -15,6 +15,7 @@ import { BelongToDomain } from "../../../../../shared/BelongToDomain";
|
|||
import { URLDecomposer } from "../..//utils/URLDecomposer";
|
||||
import { Object } from "../../../lib/authorization/Object";
|
||||
import { Subject } from "../../../lib/authorization/Subject";
|
||||
import AuthenticationError from "../../../lib/authentication/AuthenticationError";
|
||||
|
||||
export default function (vars: ServerVariables) {
|
||||
return function (req: express.Request, res: express.Response)
|
||||
|
@ -95,7 +96,7 @@ export default function (vars: ServerVariables) {
|
|||
res.send();
|
||||
return BluebirdPromise.resolve();
|
||||
})
|
||||
.catch(Exceptions.LdapBindError, function (err: Error) {
|
||||
.catch(AuthenticationError, function (err: Error) {
|
||||
vars.regulator.mark(username, false);
|
||||
return ErrorReplies.replyWithError200(req, res, vars.logger, UserMessages.AUTHENTICATION_FAILED)(err);
|
||||
})
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
@needs-regulation-config
|
||||
Feature: Authelia regulates authentication to avoid brute force
|
||||
|
||||
@need-registered-user-blackhat
|
||||
Scenario: Attacker tries too many authentication in a short period of time and get banned
|
||||
Given I visit "https://login.example.com:8080/"
|
||||
And I set field "username" to "blackhat"
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
And I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
And I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
And I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
When I set field "password" to "password"
|
||||
And I click on "Sign in"
|
||||
Then I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
|
||||
@need-registered-user-blackhat
|
||||
Scenario: User is unbanned after a configured amount of time
|
||||
Given I visit "https://login.example.com:8080/?rd=https://public.example.com:8080/secret.html"
|
||||
And I set field "username" to "blackhat"
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
And I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
And I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
And I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
When I wait 6 seconds
|
||||
And I set field "password" to "password"
|
||||
And I click on "Sign in"
|
||||
And I use "REGISTERED" as TOTP token handle
|
||||
And I click on "Sign in"
|
||||
Then I'm redirected to "https://public.example.com:8080/secret.html"
|
|
@ -1,15 +0,0 @@
|
|||
Feature: Authelia keeps user sessions despite the application restart
|
||||
|
||||
@need-authenticated-user-john
|
||||
Scenario: Session is still valid after Authelia restarts
|
||||
When the application restarts
|
||||
Then I have access to "https://admin.example.com:8080/secret.html"
|
||||
|
||||
@need-registered-user-john
|
||||
Scenario: Secrets are stored even when Authelia restarts
|
||||
When the application restarts
|
||||
And I visit "https://admin.example.com:8080/secret.html" and get redirected "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
And I use "REGISTERED" as TOTP token handle
|
||||
And I click on "Sign in"
|
||||
Then I'm redirected to "https://admin.example.com:8080/secret.html"
|
|
@ -1,16 +0,0 @@
|
|||
Feature: User can access certain subdomains with single factor
|
||||
|
||||
Scenario: User is redirected to service after first factor if allowed
|
||||
When I visit "https://login.example.com:8080/?rd=https://single_factor.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
Then I'm redirected to "https://single_factor.example.com:8080/secret.html"
|
||||
|
||||
Scenario: Redirection after first factor fails if single_factor not allowed. It redirects user to first factor.
|
||||
When I visit "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html"
|
||||
And I login with user "john" and password "password"
|
||||
Then I'm redirected to "https://login.example.com:8080/?rd=https://admin.example.com:8080/secret.html"
|
||||
|
||||
Scenario: User can login using basic authentication
|
||||
When I request "https://single_factor.example.com:8080/secret.html" with username "john" and password "password" using basic authentication
|
||||
Then I receive the secret page
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import SeleniumWebdriver, { WebDriver } from "selenium-webdriver";
|
||||
import Assert = require("assert");
|
||||
|
||||
export default async function(driver: WebDriver, type: string, message: string) {
|
||||
export default async function(driver: WebDriver, message: string) {
|
||||
await driver.wait(SeleniumWebdriver.until.elementLocated(SeleniumWebdriver.By.className("notification")), 5000)
|
||||
const notificationEl = driver.findElement(SeleniumWebdriver.By.className("notification"));
|
||||
const txt = await notificationEl.getText();
|
||||
|
|
9
test/helpers/assertions/VerifyNotificationDisplayed.ts
Normal file
9
test/helpers/assertions/VerifyNotificationDisplayed.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import SeleniumWebdriver, { WebDriver } from "selenium-webdriver";
|
||||
import Assert = require("assert");
|
||||
|
||||
export default async function(driver: WebDriver, message: string) {
|
||||
await driver.wait(SeleniumWebdriver.until.elementLocated(SeleniumWebdriver.By.className("notification")), 5000)
|
||||
const notificationEl = driver.findElement(SeleniumWebdriver.By.className("notification"));
|
||||
const txt = await notificationEl.getText();
|
||||
Assert.equal(message, txt);
|
||||
}
|
|
@ -5,8 +5,7 @@ import { StatusCodeError } from 'request-promise/errors';
|
|||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
|
||||
// Sent a GET request to the url and expect a 401
|
||||
export async function GET_Expect401(url: string) {
|
||||
export async function GET_ExpectError(url: string, statusCode: number) {
|
||||
try {
|
||||
await Request.get(url, {
|
||||
json: true,
|
||||
|
@ -15,13 +14,22 @@ export async function GET_Expect401(url: string) {
|
|||
throw new Error('No response');
|
||||
} catch (e) {
|
||||
if (e instanceof StatusCodeError) {
|
||||
Assert.equal(e.statusCode, 401);
|
||||
Assert.equal(e.statusCode, statusCode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Sent a GET request to the url and expect a 401
|
||||
export async function GET_Expect401(url: string) {
|
||||
return await GET_ExpectError(url, 401);
|
||||
}
|
||||
|
||||
export async function GET_Expect502(url: string) {
|
||||
return await GET_ExpectError(url, 502);
|
||||
}
|
||||
|
||||
export async function POST_Expect401(url: string, body?: any) {
|
||||
try {
|
||||
await Request.post(url, {
|
||||
|
|
|
@ -213,10 +213,10 @@ regulation:
|
|||
|
||||
# The time range during which the user can attempt login before being banned.
|
||||
# The user is banned if the authenticaction failed `max_retries` times in a `find_time` seconds window.
|
||||
find_time: 120
|
||||
find_time: 15
|
||||
|
||||
# The length of time before a banned user can login again.
|
||||
ban_time: 300
|
||||
ban_time: 5
|
||||
|
||||
# Configuration of the storage backend used to store data and secrets.
|
||||
#
|
||||
|
|
|
@ -5,6 +5,8 @@ import AccessControl from "./scenarii/AccessControl";
|
|||
import CustomHeadersForwarded from "./scenarii/CustomHeadersForwarded";
|
||||
import SingleFactorAuthentication from "./scenarii/SingleFactorAuthentication";
|
||||
import BasicAuthentication from "./scenarii/BasicAuthentication";
|
||||
import AutheliaRestart from "./scenarii/AutheliaRestart";
|
||||
import AuthenticationRegulation from "./scenarii/AuthenticationRegulation";
|
||||
|
||||
AutheliaSuite('Complete configuration', __dirname + '/config.yml', function() {
|
||||
this.timeout(10000);
|
||||
|
@ -16,4 +18,6 @@ AutheliaSuite('Complete configuration', __dirname + '/config.yml', function() {
|
|||
describe('Enforce internal redirections only', EnforceInternalRedirectionsOnly);
|
||||
describe('Single factor authentication', SingleFactorAuthentication);
|
||||
describe('Basic authentication', BasicAuthentication);
|
||||
describe('Authelia restart', AutheliaRestart);
|
||||
describe('Authentication regulation', AuthenticationRegulation);
|
||||
});
|
72
test/suites/complete/scenarii/AutheliaRestart.ts
Normal file
72
test/suites/complete/scenarii/AutheliaRestart.ts
Normal file
|
@ -0,0 +1,72 @@
|
|||
import Logout from "../../../helpers/Logout";
|
||||
import ChildProcess from 'child_process';
|
||||
import { StartDriver, StopDriver } from "../../../helpers/context/WithDriver";
|
||||
import VerifySecretObserved from "../../../helpers/assertions/VerifySecretObserved";
|
||||
import RegisterAndLoginTwoFactor from "../../../helpers/behaviors/RegisterAndLoginTwoFactor";
|
||||
import VisitPageAndWaitUrlIs from "../../../helpers/behaviors/VisitPageAndWaitUrlIs";
|
||||
import { GET_Expect502 } from "../../../helpers/utils/Requests";
|
||||
import LoginAndRegisterTotp from "../../../helpers/LoginAndRegisterTotp";
|
||||
import FullLogin from "../../../helpers/FullLogin";
|
||||
|
||||
export default function() {
|
||||
describe('Session is still valid after Authelia restarts', function() {
|
||||
before(async function() {
|
||||
// Be sure to start fresh
|
||||
ChildProcess.execSync('rm -f .authelia-interrupt');
|
||||
|
||||
this.driver = await StartDriver();
|
||||
await RegisterAndLoginTwoFactor(this.driver, 'john', true, 'https://admin.example.com:8080/secret.html');
|
||||
await VisitPageAndWaitUrlIs(this.driver, 'https://home.example.com:8080/');
|
||||
});
|
||||
|
||||
after(async function() {
|
||||
await Logout(this.driver);
|
||||
await StopDriver(this.driver);
|
||||
|
||||
// Be sure to cleanup
|
||||
ChildProcess.execSync('rm -f .authelia-interrupt');
|
||||
});
|
||||
|
||||
it("should still access the secret after Authelia restarted", async function() {
|
||||
ChildProcess.execSync('touch .authelia-interrupt');
|
||||
await GET_Expect502('https://login.example.com:8080/api/state');
|
||||
await this.driver.sleep(1000);
|
||||
ChildProcess.execSync('rm .authelia-interrupt');
|
||||
await this.driver.sleep(1000);
|
||||
|
||||
|
||||
await VisitPageAndWaitUrlIs(this.driver, 'https://admin.example.com:8080/secret.html');
|
||||
await VerifySecretObserved(this.driver);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Secrets are persisted even if Authelia restarts', function() {
|
||||
before(async function() {
|
||||
// Be sure to start fresh
|
||||
ChildProcess.execSync('rm -f .authelia-interrupt');
|
||||
|
||||
this.driver = await StartDriver();
|
||||
this.secret = await LoginAndRegisterTotp(this.driver, 'john', true);
|
||||
await Logout(this.driver);
|
||||
});
|
||||
|
||||
after(async function() {
|
||||
await Logout(this.driver);
|
||||
await StopDriver(this.driver);
|
||||
|
||||
// Be sure to cleanup
|
||||
ChildProcess.execSync('rm -f .authelia-interrupt');
|
||||
});
|
||||
|
||||
it("should still access the secret after Authelia restarted", async function() {
|
||||
ChildProcess.execSync('touch .authelia-interrupt');
|
||||
await GET_Expect502('https://login.example.com:8080/api/state');
|
||||
await this.driver.sleep(1000);
|
||||
ChildProcess.execSync('rm .authelia-interrupt');
|
||||
await this.driver.sleep(1000);
|
||||
|
||||
// The user can re-authenticate with the secret.
|
||||
await FullLogin(this.driver, 'john', this.secret, 'https://admin.example.com:8080/secret.html')
|
||||
});
|
||||
});
|
||||
}
|
53
test/suites/complete/scenarii/AuthenticationRegulation.ts
Normal file
53
test/suites/complete/scenarii/AuthenticationRegulation.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
import { StartDriver, StopDriver } from "../../../helpers/context/WithDriver";
|
||||
import LoginAs from "../../../helpers/LoginAs";
|
||||
import VerifyNotificationDisplayed from "../../../helpers/assertions/VerifyNotificationDisplayed";
|
||||
import VerifyIsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
|
||||
|
||||
/*
|
||||
Given I visit "https://login.example.com:8080/"
|
||||
And I set field "username" to "blackhat"
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
And I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
And I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
And I set field "password" to "bad-password"
|
||||
And I click on "Sign in"
|
||||
And I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
When I set field "password" to "password"
|
||||
And I click on "Sign in"
|
||||
Then I get a notification of type "error" with message "Authentication failed. Please check your credentials."
|
||||
*/
|
||||
|
||||
export default function() {
|
||||
describe('Authelia regulates authentications when a hacker is brute forcing', function() {
|
||||
this.timeout(15000);
|
||||
before(async function() {
|
||||
this.driver = await StartDriver();
|
||||
});
|
||||
|
||||
after(async function() {
|
||||
await StopDriver(this.driver);
|
||||
});
|
||||
|
||||
it("should return an error message when providing correct credentials the 4th time.", async function() {
|
||||
await LoginAs(this.driver, "blackhat", "bad-password");
|
||||
await VerifyNotificationDisplayed(this.driver, "Authentication failed. Please check your credentials.");
|
||||
await LoginAs(this.driver, "blackhat", "bad-password");
|
||||
await VerifyNotificationDisplayed(this.driver, "Authentication failed. Please check your credentials.");
|
||||
await LoginAs(this.driver, "blackhat", "bad-password");
|
||||
await VerifyNotificationDisplayed(this.driver, "Authentication failed. Please check your credentials.");
|
||||
|
||||
// when providing good credentials, the hacker is regulated and see same message as previously.
|
||||
await LoginAs(this.driver, "blackhat", "password");
|
||||
await VerifyNotificationDisplayed(this.driver, "Authentication failed. Please check your credentials.");
|
||||
|
||||
// Wait the regulation ban time before retrying with correct credentials.
|
||||
// It should authenticate normally.
|
||||
await this.driver.sleep(6000);
|
||||
await LoginAs(this.driver, "blackhat", "password");
|
||||
await VerifyIsSecondFactorStage(this.driver);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -6,6 +6,9 @@ import VisitPage from "../../../helpers/VisitPage";
|
|||
import VerifyUrlIs from "../../../helpers/assertions/VerifyUrlIs";
|
||||
import VerifyIsSecondFactorStage from "../../../helpers/assertions/VerifyIsSecondFactorStage";
|
||||
|
||||
/*
|
||||
* Those tests are related to single factor protected resources.
|
||||
*/
|
||||
export default function() {
|
||||
beforeEach(async function() {
|
||||
this.driver = await StartDriver();
|
||||
|
|
|
@ -73,10 +73,10 @@ regulation:
|
|||
max_retries: 3
|
||||
|
||||
# The user is banned if the authenticaction failed `max_retries` times in a `find_time` seconds window.
|
||||
find_time: 120
|
||||
find_time: 10
|
||||
|
||||
# The length of time before a banned user can login again.
|
||||
ban_time: 300
|
||||
ban_time: 5
|
||||
|
||||
# Default redirection URL
|
||||
#
|
||||
|
|
|
@ -17,7 +17,7 @@ export default function() {
|
|||
|
||||
it('should get a notification message', async function () {
|
||||
this.timeout(10000);
|
||||
await SeeNotification(this.driver, "error", AUTHENTICATION_FAILED);
|
||||
await SeeNotification(this.driver, AUTHENTICATION_FAILED);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import ValidateTotp from "../../../helpers/ValidateTotp";
|
|||
import WaitRedirected from "../../../helpers/WaitRedirected";
|
||||
import { WebDriver } from "selenium-webdriver";
|
||||
import VisitPageAndWaitUrlIs from "../../../helpers/behaviors/VisitPageAndWaitUrlIs";
|
||||
import VisitPage from "../../../helpers/VisitPage";
|
||||
import VerifyUrlIs from "../../../helpers/assertions/VerifyUrlIs";
|
||||
|
||||
export default function(this: Mocha.ISuiteCallbackContext) {
|
||||
this.timeout(20000);
|
||||
|
@ -52,8 +54,8 @@ export default function(this: Mocha.ISuiteCallbackContext) {
|
|||
await WaitRedirected(driver, "https://admin.example.com:8080/secret.html");
|
||||
await VisitPageAndWaitUrlIs(driver, "https://home.example.com:8080/");
|
||||
await driver.sleep(6000);
|
||||
await driver.get("https://admin.example.com:8080/secret.html");
|
||||
await WaitRedirected(driver, "https://admin.example.com:8080/secret.html");
|
||||
await VisitPage(driver, "https://admin.example.com:8080/secret.html");
|
||||
await VerifyUrlIs(driver, "https://admin.example.com:8080/secret.html");
|
||||
});
|
||||
});
|
||||
}
|
|
@ -29,7 +29,6 @@ export default function() {
|
|||
});
|
||||
|
||||
it("should have user and issuer in otp url", async function() {
|
||||
// this.timeout(100000);
|
||||
const el = await (this.driver as WebDriver).wait(
|
||||
SeleniumWebdriver.until.elementLocated(
|
||||
SeleniumWebdriver.By.className('otpauth-secret')), 5000);
|
||||
|
|
|
@ -57,6 +57,6 @@ export default function() {
|
|||
await FillField(this.driver, "password1", "newpass");
|
||||
await FillField(this.driver, "password2", "badpass");
|
||||
await ClickOn(this.driver, SeleniumWebDriver.By.id('reset-button'));
|
||||
await SeeNotification(this.driver, "error", "The passwords are different.");
|
||||
await SeeNotification(this.driver, "The passwords are different.");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ export default function() {
|
|||
});
|
||||
|
||||
it("get a notification message", async function() {
|
||||
await SeeNotification(this.driver, "error", AUTHENTICATION_TOTP_FAILED);
|
||||
await SeeNotification(this.driver, AUTHENTICATION_TOTP_FAILED);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user