snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 1s
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @system_console @authentication
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
import {getRandomId, newTestPassword} from '@/utils';
|
||||
|
||||
describe('Authentication', () => {
|
||||
const restrictCreationToDomains = 'mattermost.com, test.com';
|
||||
let testUser: Cypress.UserProfile;
|
||||
let testUserAlreadyInTeam: Cypress.UserProfile;
|
||||
let testTeam: Cypress.Team;
|
||||
|
||||
before(() => {
|
||||
// # Do email test if setup properly
|
||||
cy.shouldHaveEmailEnabled();
|
||||
|
||||
cy.apiInitSetup().then(({user, team}) => {
|
||||
testUserAlreadyInTeam = user;
|
||||
testTeam = team;
|
||||
cy.apiCreateUser().then(({user: newUser}) => {
|
||||
testUser = newUser;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Log in as a admin.
|
||||
cy.apiAdminLogin();
|
||||
});
|
||||
|
||||
it('MM-T1756 - Restrict Domains - Multiple - success', () => {
|
||||
// # Set restricted domain
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
RestrictCreationToDomains: restrictCreationToDomains,
|
||||
},
|
||||
});
|
||||
|
||||
// # Log out and go to login page
|
||||
cy.apiLogout();
|
||||
cy.visit('/login');
|
||||
|
||||
// * Assert that create account button is visible
|
||||
cy.findByText('Don\'t have an account?', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
|
||||
// # Go to sign up with email page
|
||||
cy.visit('/signup_user_complete');
|
||||
|
||||
cy.get('#input_email', {timeout: TIMEOUTS.ONE_MIN}).type(`test-${getRandomId()}@mattermost.com`);
|
||||
|
||||
cy.get('#input_password-input').type(newTestPassword());
|
||||
|
||||
cy.get('#input_name').clear().type(`test${getRandomId()}`);
|
||||
|
||||
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
|
||||
|
||||
cy.findByText('Create account').click();
|
||||
|
||||
// * Make sure account was created successfully and we are at the select team page
|
||||
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1757 - Restrict Domains - Multiple - fail', () => {
|
||||
// # Set restricted domain
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
RestrictCreationToDomains: restrictCreationToDomains,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiLogin(testUserAlreadyInTeam);
|
||||
cy.visit('/');
|
||||
|
||||
// # Open Profile
|
||||
cy.uiOpenProfileModal('Profile Settings');
|
||||
|
||||
// # Click "Edit" to the right of "Email"
|
||||
cy.get('#emailEdit').should('be.visible').click();
|
||||
|
||||
// # Type new email
|
||||
cy.get('#primaryEmail').should('be.visible').type('user-123123@example.com');
|
||||
cy.get('#confirmEmail').should('be.visible').type('user-123123@example.com');
|
||||
cy.get('#currentPassword').should('be.visible').type(testUser.password);
|
||||
|
||||
// # Save the settings
|
||||
cy.uiSave().wait(TIMEOUTS.HALF_SEC);
|
||||
|
||||
// * Assert an error exist and is what is expected
|
||||
cy.findByText('The email you provided does not belong to an accepted domain. Please contact your administrator or sign up with a different email.').should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1758 - Restrict Domains - Team invite closed team', () => {
|
||||
// # Set restricted domain
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
RestrictCreationToDomains: restrictCreationToDomains,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
cy.visit(`/signup_user_complete/?id=${testTeam.invite_id}`);
|
||||
|
||||
cy.get('#input_email', {timeout: TIMEOUTS.ONE_MIN}).type(`test-${getRandomId()}@example.com`);
|
||||
|
||||
cy.get('#input_password-input').type(newTestPassword());
|
||||
|
||||
cy.get('#input_name').clear().type(`test${getRandomId()}`);
|
||||
|
||||
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
|
||||
|
||||
cy.findByText('Create account').click();
|
||||
|
||||
// * Make sure account was not created successfully
|
||||
cy.get('.AlertBanner__title').scrollIntoView().should('be.visible');
|
||||
cy.findByText('The email you provided does not belong to an accepted domain. Please contact your administrator or sign up with a different email.').should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1763 - Security - Signup: Email verification not required, user immediately sees Town Square', () => {
|
||||
// # Disable email verification
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: false,
|
||||
},
|
||||
}).then(({config}) => {
|
||||
// # Log out and go to front page
|
||||
cy.apiLogout();
|
||||
cy.visit('/login');
|
||||
|
||||
// * Assert that create account button is visible
|
||||
cy.findByText('Don\'t have an account?', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
|
||||
// # Go to sign up with email page
|
||||
cy.visit('/signup_user_complete');
|
||||
|
||||
const username = `Test${getRandomId()}`;
|
||||
const email = `${username.toLowerCase()}@example.com`;
|
||||
|
||||
cy.get('#input_email', {timeout: TIMEOUTS.ONE_MIN}).type(email);
|
||||
|
||||
cy.get('#input_password-input').type(newTestPassword());
|
||||
|
||||
cy.get('#input_name').clear().type(username);
|
||||
|
||||
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
|
||||
|
||||
cy.findByText('Create account').click();
|
||||
|
||||
// * Make sure account was created successfully and we are on the team joining page
|
||||
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
|
||||
cy.getRecentEmail({username, email}).then(({subject}) => {
|
||||
// * Verify the subject
|
||||
expect(subject).to.include(`[${config.TeamSettings.SiteName}] You joined`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1765 - Authentication - Email - Creation with email = false', () => {
|
||||
// # Disable user sign up and enable GitLab
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
EnableSignUpWithEmail: false,
|
||||
},
|
||||
GitLabSettings: {
|
||||
Enable: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
cy.visit(`/signup_user_complete/?id=${testTeam.invite_id}`);
|
||||
|
||||
cy.findByText('Create your account with one of the following:').should('exist');
|
||||
cy.findByText('GitLab', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
|
||||
// * Email and Password option does not exist
|
||||
cy.findByText('Email address').should('not.exist');
|
||||
cy.findByText('Choose a Password').should('not.exist');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,188 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @system_console @authentication @mfa
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
import {getRandomId} from '@/utils';
|
||||
|
||||
describe('Authentication', () => {
|
||||
beforeEach(() => {
|
||||
// # Log in as admin.
|
||||
cy.apiAdminLogin();
|
||||
});
|
||||
|
||||
it('MM-T1771 - Minimum password length error field shows below minimum and above 72', () => {
|
||||
cy.visit('/admin_console/authentication/password');
|
||||
|
||||
cy.findByPlaceholderText('E.g.: "5"', {timeout: TIMEOUTS.ONE_MIN}).clear().type('88');
|
||||
|
||||
cy.uiSave();
|
||||
|
||||
// * Ensure error appears when saving a password outside of the limits
|
||||
// Note: minimum is 5 on non-FIPS builds and 14 on FIPS builds
|
||||
cy.contains(/Minimum password length must be a whole number greater than or equal to (5|14) and less than or equal to 72\./, {timeout: TIMEOUTS.ONE_MIN}).
|
||||
should('exist').
|
||||
and('be.visible');
|
||||
|
||||
cy.findByPlaceholderText('E.g.: "5"').clear().type('3');
|
||||
|
||||
cy.uiSave();
|
||||
|
||||
// * Ensure error appears when saving a password outside of the limits
|
||||
cy.contains(/Minimum password length must be a whole number greater than or equal to (5|14) and less than or equal to 72\./, {timeout: TIMEOUTS.ONE_MIN}).
|
||||
should('exist').
|
||||
and('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1772 - Change minimum password length, verify help text and error message', () => {
|
||||
cy.visit('/admin_console/authentication/password');
|
||||
|
||||
cy.findByPlaceholderText('E.g.: "5"', {timeout: TIMEOUTS.ONE_MIN}).clear().type('15');
|
||||
|
||||
cy.uiSave();
|
||||
|
||||
cy.findByText('Your password must be 15-72 characters long.').should('be.visible');
|
||||
|
||||
cy.apiLogout();
|
||||
|
||||
// # Go to sign up with email page
|
||||
cy.visit('/signup_user_complete');
|
||||
|
||||
cy.get('#input_email', {timeout: TIMEOUTS.ONE_MIN}).type(`test-${getRandomId()}@example.com`);
|
||||
|
||||
cy.get('#input_name').clear().type(`BestUsername${getRandomId()}`);
|
||||
|
||||
cy.get('#input_password-input').clear().type('less');
|
||||
|
||||
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
|
||||
|
||||
cy.findByText('Create account').click();
|
||||
|
||||
// * Assert the error is what is expected;
|
||||
cy.findByText('Your password must be 15-72 characters long.').should('be.visible');
|
||||
|
||||
cy.get('#input_password-input').clear().type('GreaterThan15Chr!');
|
||||
|
||||
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
|
||||
|
||||
cy.findByText('Create account').click();
|
||||
|
||||
// * Assert that we are not shown an MFA screen and instead a Teams You Can join page
|
||||
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1773 - Minimum password length field resets to default after saving invalid value', () => {
|
||||
cy.visit('/admin_console/authentication/password');
|
||||
|
||||
cy.findByPlaceholderText('E.g.: "5"', {timeout: TIMEOUTS.ONE_MIN}).clear().type('20');
|
||||
|
||||
cy.uiSave();
|
||||
|
||||
cy.reload();
|
||||
|
||||
// * Ensure the limit 20 appears
|
||||
cy.findByPlaceholderText('E.g.: "5"').invoke('val').should('equal', '20');
|
||||
cy.findByPlaceholderText('E.g.: "5"').clear();
|
||||
|
||||
cy.uiSave();
|
||||
|
||||
// Reload to see the actual server state, since on FIPS builds saving
|
||||
// the webapp default of 5 is rejected (below the FIPS minimum of 14).
|
||||
cy.reload();
|
||||
|
||||
// * Ensure the field reflects the server's current minimum password length
|
||||
cy.apiGetConfig().then(({config: {PasswordSettings}}) => {
|
||||
cy.findByPlaceholderText('E.g.: "5"').invoke('val').should('equal', String(PasswordSettings.MinimumLength));
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1774 - Select all Password Requirements, verify help text and error on bad password', () => {
|
||||
cy.apiUpdateConfig({
|
||||
PasswordSettings: {
|
||||
Lowercase: true,
|
||||
Number: true,
|
||||
Uppercase: true,
|
||||
Symbol: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
|
||||
// # Go to sign up with email page
|
||||
cy.visit('/signup_user_complete');
|
||||
|
||||
cy.get('#input_email', {timeout: TIMEOUTS.ONE_MIN}).type(`test-${getRandomId()}@example.com`);
|
||||
|
||||
cy.get('#input_name').clear().type(`BestUsernameInTheWorld${getRandomId()}`);
|
||||
|
||||
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
|
||||
|
||||
['NOLOWERCASE12345!', 'nouppercase12345!', 'NoNumberHere!!!', 'NoSymbol1234567'].forEach((option) => {
|
||||
cy.get('#input_password-input').clear().type(option);
|
||||
cy.findByText('Create account').click();
|
||||
|
||||
// * Assert the error is what is expected;
|
||||
cy.findByText('Your password must be 14-72 characters long and include both lowercase and uppercase letters, numbers, and special characters.').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1777 - Multi-factor Authentication option hidden in Profile when disabled', () => {
|
||||
cy.apiUpdateConfig({
|
||||
ServiceSettings: {
|
||||
EnableMultifactorAuthentication: false,
|
||||
},
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal('Security');
|
||||
|
||||
// * Assert that Multi-factor Authentication text does not exist
|
||||
cy.findByText('Multi-factor Authentication').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1779 - Multi-factor Authentication option appears in Profile when enabled', () => {
|
||||
cy.apiUpdateConfig({
|
||||
ServiceSettings: {
|
||||
EnableMultifactorAuthentication: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
// # Go to Profile
|
||||
cy.uiOpenProfileModal('Security');
|
||||
|
||||
// * Assert that Multi-factor Authentication text does exist
|
||||
cy.findByText('Multi-factor Authentication').should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1780 - Multi-factor Authentication false: User can log in without being prompted for MFA', () => {
|
||||
cy.apiUpdateConfig({
|
||||
ServiceSettings: {
|
||||
EnableMultifactorAuthentication: true,
|
||||
EnforceMultifactorAuthentication: false,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiCreateUser().then(({user: newUser}) => {
|
||||
cy.apiLogout();
|
||||
|
||||
// # Login as a new user and visit default page
|
||||
cy.apiLogin(newUser);
|
||||
cy.visit('/');
|
||||
|
||||
// * Assert that we are not shown a MFA screen and instead a Teams You Can join page
|
||||
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @system_console @authentication
|
||||
|
||||
describe('Authentication', () => {
|
||||
beforeEach(() => {
|
||||
// # Log in as a admin.
|
||||
cy.apiAdminLogin();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.apiAdminLogin({failOnStatusCode: false});
|
||||
cy.apiUpdateConfig({});
|
||||
});
|
||||
|
||||
const testCases = [
|
||||
{
|
||||
title: 'MM-T1767 - Email signin false Username signin true',
|
||||
signinWithEmail: false,
|
||||
signinWithUsername: true,
|
||||
},
|
||||
{
|
||||
title: 'MM-T1768 - Email signin true Username signin true',
|
||||
signinWithEmail: true,
|
||||
signinWithUsername: true,
|
||||
},
|
||||
{
|
||||
title: 'MM-T1769 - Email signin true Username signin false',
|
||||
signinWithEmail: true,
|
||||
signinWithUsername: false,
|
||||
},
|
||||
];
|
||||
|
||||
testCases.forEach(({title, signinWithEmail, signinWithUsername}) => {
|
||||
it(title, () => {
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
EnableSignInWithEmail: signinWithEmail,
|
||||
EnableSignInWithUsername: signinWithUsername,
|
||||
},
|
||||
LdapSettings: {
|
||||
Enable: false,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
|
||||
// # Go to front page
|
||||
cy.visit('/login');
|
||||
|
||||
// # Remove autofocus from login input
|
||||
cy.focused().blur();
|
||||
|
||||
let expectedPlaceholderText;
|
||||
if (signinWithEmail && signinWithUsername) {
|
||||
expectedPlaceholderText = 'Email or Username';
|
||||
} else if (signinWithEmail) {
|
||||
expectedPlaceholderText = 'Email';
|
||||
} else {
|
||||
expectedPlaceholderText = 'Username';
|
||||
}
|
||||
|
||||
// * Make sure the username field has expected placeholder text
|
||||
cy.findByPlaceholderText(expectedPlaceholderText).should('exist').and('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,330 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @system_console @authentication
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
import {reUrl, getRandomId, newTestPassword} from '@/utils';
|
||||
|
||||
describe('Authentication', () => {
|
||||
let testUser: Cypress.UserProfile;
|
||||
|
||||
before(() => {
|
||||
// # Do email test if setup properly
|
||||
cy.shouldHaveEmailEnabled();
|
||||
|
||||
cy.apiCreateUser().then(({user: newUser}) => {
|
||||
testUser = newUser;
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.apiAdminLogin();
|
||||
});
|
||||
|
||||
it('MM-T1764 - Security - Signup: Email verification required (after having created account when verification was not required)', () => {
|
||||
// # Update Configs
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: false,
|
||||
},
|
||||
});
|
||||
|
||||
// # Login as test user and make sure it goes to team selection
|
||||
cy.apiLogin(testUser);
|
||||
cy.visit('/');
|
||||
cy.url().should('include', '/select_team');
|
||||
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
|
||||
cy.apiAdminLogin();
|
||||
|
||||
// # Update Configs
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: true,
|
||||
},
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
|
||||
// # Login as test user and make sure it goes to team selection
|
||||
cy.visit('/login');
|
||||
|
||||
// # Remove autofocus from login input
|
||||
cy.get('.login-body-card-title').click();
|
||||
|
||||
// # Clear email/username field and type username
|
||||
cy.apiGetClientLicense().then(({isLicensed}) => {
|
||||
cy.findByPlaceholderText(isLicensed ? 'Email, Username or AD/LDAP Username' : 'Email or Username', {timeout: TIMEOUTS.ONE_MIN}).clear().type(testUser.username);
|
||||
});
|
||||
|
||||
// # Clear password field and type password
|
||||
cy.findByPlaceholderText('Password').clear().type(testUser.password);
|
||||
|
||||
// # Hit enter to login
|
||||
cy.get('#saveSetting').should('not.be.disabled').click();
|
||||
|
||||
cy.wait(TIMEOUTS.THREE_SEC);
|
||||
|
||||
// * Assert that email verification has been sent and then resend to make sure it gets resent
|
||||
cy.findByText('Resend Email').should('be.visible').and('exist').click();
|
||||
cy.findByText('Verification email sent').should('be.visible').and('exist');
|
||||
cy.findByText('You’re almost done!').should('be.visible').and('exist');
|
||||
cy.findByText('Please verify your email address. Check your inbox for an email.').should('be.visible').and('exist');
|
||||
|
||||
cy.getRecentEmail(testUser).then(({body}) => {
|
||||
const permalink = body[6].match(reUrl)[0];
|
||||
|
||||
// # Visit permalink (e.g. click on email link), view in browser to proceed
|
||||
cy.visit(permalink);
|
||||
|
||||
// # Clear password field and type password
|
||||
cy.get('#input_password-input').clear().type(testUser.password);
|
||||
|
||||
// # Hit enter to login
|
||||
cy.get('#saveSetting').should('not.be.disabled').click();
|
||||
|
||||
// * Should show the join team stuff
|
||||
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1770 - Default password settings', () => {
|
||||
cy.apiGetClientLicense().then(({isCloudLicensed}) => {
|
||||
const newConfig = {
|
||||
PasswordSettings: {
|
||||
MinimumLength: null,
|
||||
Lowercase: null,
|
||||
Number: null,
|
||||
Uppercase: null,
|
||||
Symbol: null,
|
||||
},
|
||||
ServiceSettings: {},
|
||||
};
|
||||
|
||||
if (!isCloudLicensed) {
|
||||
newConfig.ServiceSettings = {
|
||||
MaximumLoginAttempts: null,
|
||||
};
|
||||
}
|
||||
|
||||
cy.apiUpdateConfig(newConfig);
|
||||
|
||||
// * Ensure password has the default minimum length and no password requirements are checked
|
||||
// Note: default MinimumLength is 8 on non-FIPS builds and 14 on FIPS builds
|
||||
cy.apiGetConfig().then(({config: {PasswordSettings}}) => {
|
||||
expect(PasswordSettings.MinimumLength).to.be.oneOf([8, 14]);
|
||||
expect(PasswordSettings.Lowercase).equal(false);
|
||||
expect(PasswordSettings.Number).equal(false);
|
||||
expect(PasswordSettings.Uppercase).equal(false);
|
||||
expect(PasswordSettings.Symbol).equal(false);
|
||||
});
|
||||
|
||||
cy.visit('/admin_console/authentication/password');
|
||||
cy.get('.admin-console__header').should('be.visible').and('have.text', 'Password');
|
||||
|
||||
cy.findByTestId('passwordMinimumLengthinput').should('be.visible').invoke('val').then((val) => {
|
||||
expect(val).to.be.oneOf(['8', '14']);
|
||||
});
|
||||
cy.findByText('At least one lowercase letter').siblings().should('not.be.checked');
|
||||
cy.findByText('At least one uppercase letter').siblings().should('not.be.checked');
|
||||
cy.findByText('At least one number').siblings().should('not.be.checked');
|
||||
cy.findByText('At least one symbol (e.g. "~!@#$%^&*()")').siblings().should('not.be.checked');
|
||||
|
||||
if (!isCloudLicensed) {
|
||||
cy.findByTestId('maximumLoginAttemptsinput').should('be.visible').and('have.value', '10');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1783 - Username validation shows errors for various username requirements', () => {
|
||||
// # Go to sign up with email page
|
||||
cy.visit('/signup_user_complete');
|
||||
|
||||
cy.get('#input_email', {timeout: TIMEOUTS.ONE_MIN}).type(`test-${getRandomId()}@example.com`);
|
||||
|
||||
cy.get('#input_password-input').type(newTestPassword());
|
||||
|
||||
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
|
||||
|
||||
['1user', 'te', 'user#1', 'user!1'].forEach((option) => {
|
||||
cy.get('#input_name').clear().type(option);
|
||||
cy.findByText('Create account').click();
|
||||
|
||||
// * Assert the error is what is expected;
|
||||
cy.get('.Input___error').scrollIntoView().should('be.visible');
|
||||
cy.findByText('Usernames have to begin with a lowercase letter and be 3-22 characters long. You can use lowercase letters, numbers, periods, dashes, and underscores.').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1752 - Enable account creation - true', () => {
|
||||
// # Enable open server
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
EnableUserCreation: true,
|
||||
},
|
||||
});
|
||||
|
||||
// # Logout and go to front page
|
||||
cy.apiLogout();
|
||||
cy.visit('/login');
|
||||
|
||||
// * Assert that create account button is visible
|
||||
cy.findByText('Don\'t have an account?', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
|
||||
// # Go to sign up with email page
|
||||
cy.visit('/signup_user_complete');
|
||||
|
||||
cy.get('#input_email', {timeout: TIMEOUTS.ONE_MIN}).type(`test-${getRandomId()}@example.com`);
|
||||
|
||||
cy.get('#input_password-input').type(newTestPassword());
|
||||
|
||||
cy.get('#input_name').clear().type(`Test${getRandomId()}`);
|
||||
|
||||
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
|
||||
|
||||
cy.findByText('Create account').click();
|
||||
|
||||
// * Make sure account was created successfully and we are on the team joining page
|
||||
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1753 - Enable account creation - false', () => {
|
||||
// # Disable user account creation
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
EnableUserCreation: false,
|
||||
},
|
||||
LdapSettings: {
|
||||
Enable: false,
|
||||
},
|
||||
}).then(({config}) => {
|
||||
expect(config.TeamSettings.EnableUserCreation).to.equal(false);
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
|
||||
// * Verify client config has account creation disabled
|
||||
cy.request('/api/v4/config/client').its('body.EnableUserCreation').should('eq', 'false');
|
||||
|
||||
// # Go to front page
|
||||
cy.visit('/login');
|
||||
|
||||
// # Reload so the login page picks up the client config
|
||||
cy.reload();
|
||||
|
||||
// * Assert that create account button is not visible
|
||||
cy.findByText('Don\'t have an account?').should('not.exist');
|
||||
|
||||
// # Go to sign up with email page
|
||||
cy.visit('/signup_user_complete');
|
||||
|
||||
// * No sign up methods enabled
|
||||
cy.findByText('This server doesn’t have any sign-in methods enabled').should('be.visible').and('exist');
|
||||
});
|
||||
|
||||
it('MM-T1754 - Restrict Domains - Account creation link on signin page', () => {
|
||||
// # Enable user account creation and set restricted domain
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: false,
|
||||
},
|
||||
TeamSettings: {
|
||||
RestrictCreationToDomains: 'test.com',
|
||||
EnableUserCreation: true,
|
||||
},
|
||||
}).then(({config}) => {
|
||||
expect(config.TeamSettings.RestrictCreationToDomains).to.equal('test.com');
|
||||
expect(config.TeamSettings.EnableUserCreation).to.equal(true);
|
||||
});
|
||||
|
||||
cy.apiLogout();
|
||||
|
||||
// # Go to front page
|
||||
cy.visit('/login');
|
||||
|
||||
// * Assert that create account button is visible
|
||||
cy.findByText('Don\'t have an account?', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
|
||||
|
||||
// # Go to sign up with email page
|
||||
cy.visit('/signup_user_complete');
|
||||
|
||||
cy.get('#input_email', {timeout: TIMEOUTS.ONE_MIN}).type(`test-${getRandomId()}@example.com`);
|
||||
|
||||
cy.get('#input_password-input').type(newTestPassword());
|
||||
|
||||
cy.get('#input_name').clear().type(`Test${getRandomId()}`);
|
||||
|
||||
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
|
||||
|
||||
cy.findByText('Create account').click();
|
||||
|
||||
// * Make sure account was not created successfully
|
||||
cy.findByText('The email you provided does not belong to an accepted domain. Please contact your administrator or sign up with a different email.').should('be.visible');
|
||||
});
|
||||
|
||||
it('MM-T1755 - Restrict Domains - Email invite', () => {
|
||||
// # Clear leftover domain restriction so a team can be created
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
RestrictCreationToDomains: '',
|
||||
EnableUserCreation: true,
|
||||
},
|
||||
});
|
||||
|
||||
// # Create a team to invite from
|
||||
cy.apiCreateTeam('invite-domain', 'Invite Domain').then(({team}) => {
|
||||
// # Enable user account creation and set restricted domain
|
||||
cy.apiUpdateConfig({
|
||||
EmailSettings: {
|
||||
RequireEmailVerification: false,
|
||||
},
|
||||
ServiceSettings: {
|
||||
EnableEmailInvitations: true,
|
||||
},
|
||||
TeamSettings: {
|
||||
RestrictCreationToDomains: 'test.com',
|
||||
EnableUserCreation: true,
|
||||
},
|
||||
}).then(({config}) => {
|
||||
expect(config.TeamSettings.RestrictCreationToDomains).to.equal('test.com');
|
||||
expect(config.TeamSettings.EnableUserCreation).to.equal(true);
|
||||
expect(config.ServiceSettings.EnableEmailInvitations).to.equal(true);
|
||||
});
|
||||
|
||||
cy.visit(`/${team.name}/channels/town-square`);
|
||||
cy.get('#post_textbox').should('be.visible');
|
||||
|
||||
// # Open team menu and click on "Invite People"
|
||||
cy.uiOpenTeamMenu('Invite people');
|
||||
|
||||
const inviteEmail = `test-${getRandomId()}@mattermost.com`;
|
||||
|
||||
// # Input email
|
||||
cy.get('.users-emails-input__control').should('be.visible').within(() => {
|
||||
cy.get('input').type(inviteEmail, {force: true});
|
||||
});
|
||||
|
||||
// # Select the Add email option
|
||||
cy.get('.users-emails-input__option:not(.users-emails-input__option--no-matches)').
|
||||
should('contain', inviteEmail).
|
||||
click();
|
||||
|
||||
// * Verify the email chip is added
|
||||
cy.get('.users-emails-input__multi-value').should('contain', inviteEmail);
|
||||
|
||||
// # Click invite members button
|
||||
cy.findByTestId('inviteButton').should('be.enabled').click();
|
||||
|
||||
// * Verify message is what you expect it to be
|
||||
cy.contains('The following email addresses do not belong to an accepted domain:').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Stage: @prod
|
||||
// Group: @channels @system_console @authentication @not_cloud
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
|
||||
describe('Authentication', () => {
|
||||
before(() => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// # Log in as admin.
|
||||
cy.apiAdminLogin();
|
||||
});
|
||||
|
||||
it('MM-T1762 - Invite Salt', () => {
|
||||
cy.visit('/admin_console/site_config/public_links');
|
||||
|
||||
// * Check that public link salt is masked
|
||||
cy.findByText('********************************').should('be.visible');
|
||||
|
||||
// # Click "Regenerate"
|
||||
cy.findByText('Regenerate', {timeout: TIMEOUTS.ONE_MIN}).click();
|
||||
|
||||
// * Check that new public link is generated and unmasked
|
||||
cy.findByText('********************************').should('not.exist');
|
||||
});
|
||||
|
||||
it('MM-T1775 - Maximum Login Attempts field resets to default after saving invalid value', () => {
|
||||
cy.visit('/admin_console/authentication/password');
|
||||
|
||||
cy.findByPlaceholderText('E.g.: "10"', {timeout: TIMEOUTS.ONE_MIN}).clear().type('ten');
|
||||
|
||||
cy.uiSave();
|
||||
|
||||
// * Ensure error appears when saving a password outside of the limits
|
||||
cy.findByPlaceholderText('E.g.: "10"').invoke('val').should('equal', '10');
|
||||
|
||||
// * Verify that the config remain the same
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.ServiceSettings.MaximumLoginAttempts).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
it('MM-T1776 - Maximum Login Attempts field successfully saves valid change', () => {
|
||||
cy.visit('/admin_console/authentication/password');
|
||||
|
||||
cy.findByPlaceholderText('E.g.: "10"', {timeout: TIMEOUTS.ONE_MIN}).clear().type('2');
|
||||
|
||||
cy.uiSaveConfig();
|
||||
|
||||
// * Ensure error appears when saving a password outside of the limits
|
||||
cy.findByPlaceholderText('E.g.: "10"').invoke('val').should('equal', '2');
|
||||
|
||||
// * Verify that the config have changed
|
||||
cy.apiGetConfig().then(({config}) => {
|
||||
expect(config.ServiceSettings.MaximumLoginAttempts).to.equal(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// ***************************************************************
|
||||
// - [#] indicates a test step (e.g. # Go to a page)
|
||||
// - [*] indicates an assertion (e.g. * Check the title)
|
||||
// - Use element ID when selecting an element. Create one if none.
|
||||
// ***************************************************************
|
||||
|
||||
// Group: @channels @system_console @authentication
|
||||
|
||||
import * as TIMEOUTS from '@/fixtures/timeouts';
|
||||
|
||||
describe('Authentication', () => {
|
||||
before(() => {
|
||||
// # Enable open server
|
||||
cy.apiUpdateConfig({
|
||||
TeamSettings: {
|
||||
EnableOpenServer: false,
|
||||
},
|
||||
});
|
||||
|
||||
// # Logout and visit default page
|
||||
cy.apiLogout();
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
it('MM-T1760 - Enable Open Server false: Create account link is hidden', () => {
|
||||
// * Assert that create account button is not visible
|
||||
cy.findByText('Don\'t have an account?', {timeout: TIMEOUTS.TEN_SEC}).should('not.exist');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user