Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 71 additions & 71 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2527,83 +2527,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

---

## Masterminds/semver

This product contains 'Masterminds/semver' by Masterminds.

Work with Semantic Versions in Go

* LICENSE: MIT License

Copyright (C) 2014-2019, Matt Butcher and Matt Farina

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


---

## anthonynsimon/bild

This product contains 'anthonynsimon/bild' by anthonynsimon.
## LumenResearch/uasurfer

Image processing algorithms in pure Go

* HOMEPAGE:
* https://github.com/anthonynsimon/bild

* LICENSE: MIT License

MIT License

Copyright (c) 2016-2024 Anthony Simon

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


---

## avct/uasurfer

This product contains 'uasurfer' by Avocet.
This product contains 'LumenResearch/uasurfer' by Lumen Research.

Go package for fast and reliable abstraction of browser user agent strings.

* HOMEPAGE:
* https://github.com/avct/uasurfer
* https://github.com/LumenResearch/uasurfer

* LICENSE: Apache-2.0
* LICENSE: Other


Apache License
Expand Down Expand Up @@ -2798,6 +2731,73 @@ Go package for fast and reliable abstraction of browser user agent strings.
See the License for the specific language governing permissions and
limitations under the License.

---

## Masterminds/semver

This product contains 'Masterminds/semver' by Masterminds.

Work with Semantic Versions in Go

* LICENSE: MIT License

Copyright (C) 2014-2019, Matt Butcher and Matt Farina

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


---

## anthonynsimon/bild

This product contains 'anthonynsimon/bild' by anthonynsimon.

Image processing algorithms in pure Go

* HOMEPAGE:
* https://github.com/anthonynsimon/bild

* LICENSE: MIT License

MIT License

Copyright (c) 2016-2024 Anthony Simon

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


---

## aws/aws-sdk-go-v2
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// 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 @interactive_menu

/**
* Note: This test requires webhook server running. Initiate `npm run start:webhook` to start.
*/

import * as TIMEOUTS from '../../../fixtures/timeouts';

describe('Interactive Menu - Action Button Error Handling', () => {
let incomingWebhook;

before(() => {
cy.requireWebhookServer();

// # Create and visit new channel and create incoming webhook
cy.apiInitSetup().then(({team, channel}) => {
const newIncomingHook = {
channel_id: channel.id,
channel_locked: true,
description: 'Incoming webhook for action button error testing',
display_name: 'actionErrorTest' + Date.now(),
};

cy.apiCreateWebhook(newIncomingHook).then((hook) => {
incomingWebhook = hook;
});

cy.visit(`/${team.name}/channels/${channel.name}`);
});
});

it('MM-65023 should display error message when action button fails', () => {
const payload = getPayloadWithErrorAction();

// # Post an incoming webhook with action button that will trigger an error
cy.postIncomingWebhook({url: incomingWebhook.url, data: payload, waitFor: 'attachment-pretext'});

// * Wait for the button to be available
cy.findByText('Error Button 1').should('be.visible');

// # Click on "Error Button 1" (invalid URL will cause error)
cy.findByText('Error Button 1').should('be.visible').click({force: true});
cy.wait(TIMEOUTS.HALF_SEC);

// * Verify that error message is displayed
cy.get('.has-error').should('be.visible');
cy.get('.has-error .control-label').should('contain.text', 'Action integration error.');
});

it('MM-65023 should clear error message when successful action is triggered', () => {
const payload = getPayloadWithErrorAndSuccess(Cypress.env().webhookBaseUrl);

// # Post an incoming webhook with error and success buttons
cy.postIncomingWebhook({url: incomingWebhook.url, data: payload, waitFor: 'attachment-pretext'});

// * Wait for the buttons to be available
cy.findByText('Error Button').should('be.visible');
cy.findByText('Success Button').should('be.visible');

// # Click on "Error Button" first
cy.findByText('Error Button').should('be.visible').click({force: true});
cy.wait(TIMEOUTS.HALF_SEC);

// * Verify that error message is displayed for test2
cy.get('.has-error').should('be.visible');
cy.get('.has-error .control-label').should('contain.text', 'Action integration error.');

// # Click on "Success Button" to trigger successful action
cy.findByText('Success Button').should('be.visible').click({force: true});

// * Wait for successful response and verify the specific error from this test is cleared
cy.uiWaitUntilMessagePostedIncludes('a < a | b > a');

// * Find the specific attachment container for this test and verify its error is cleared
cy.contains('.attachment', 'Action Button Error Clear Test - Error and Success')
.find('.has-error').should('not.exist');
});

it('MM-65023 should display tooltip on action button hover', () => {
const payload = getPayloadWithTooltip();

// # Post an incoming webhook with action button that has tooltip
cy.postIncomingWebhook({url: incomingWebhook.url, data: payload, waitFor: 'attachment-pretext'});

// * Wait for the tooltip button to be available
cy.findByText('Button with Tooltip').should('be.visible');

// # Hover over the action button
cy.findByText('Button with Tooltip').should('be.visible').trigger('mouseenter', {force: true});

// * Verify that tooltip is displayed with correct text using WithTooltip component
cy.get('.tooltipContainer').should('be.visible').and('contain.text', 'This is a helpful tooltip');
});
});

function getPayloadWithErrorAction() {
return {
attachments: [{
pretext: 'Action Button Error Test - Single Button',
actions: [{
name: 'Error Button 1',
tooltip: 'This button will trigger an error',
integration: {
url: 'http://invalid-url-test1.example.com/fail',
context: {
action: 'trigger_error_test1',
},
},
}],
}],
};
}

function getPayloadWithErrorAndSuccess(webhookBaseUrl) {
return {
attachments: [{
pretext: 'Action Button Error Clear Test - Error and Success',
actions: [{
name: 'Error Button',
tooltip: 'This button will trigger an error',
integration: {
url: 'http://invalid-url-test2.example.com/fail',
context: {
action: 'trigger_error_test2',
},
},
}, {
name: 'Success Button',
tooltip: 'This button will work',
integration: {
url: `${webhookBaseUrl}/slack_compatible_message_response`,
context: {
action: 'show_spoiler',
spoiler: 'a < a | b > a',
skipSlackParsing: true,
},
},
}],
}],
};
}

function getPayloadWithTooltip() {
return {
attachments: [{
pretext: 'Action Button Tooltip Test',
actions: [{
name: 'Button with Tooltip',
tooltip: 'This is a helpful tooltip',
integration: {
url: 'http://localhost:3000/success',
context: {
action: 'tooltip_test',
},
},
}],
}],
};
}
2 changes: 1 addition & 1 deletion e2e-tests/cypress/tests/support/ui/file_preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Cypress.Commands.add('uiGetFileUploadPreview', () => {

Cypress.Commands.add('uiWaitForFileUploadPreview', () => {
cy.waitUntil(() => cy.uiGetFileUploadPreview().then((el) => {
return el.find('.post-image.normal').length > 0;
return el.find('.post-image__thumbnail').length > 0;
}));
});

Expand Down
12 changes: 8 additions & 4 deletions e2e-tests/playwright/lib/src/server/default_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -844,15 +844,19 @@ const defaultServerConfig: AdminConfig = {
AutoTranslationSettings: {
Enable: false,
Provider: '',
LibreTranslate: {
URL: '',
APIKey: '',
},
TargetLanguages: ['en'],
TimeoutsMs: {
Short: 1200,
Medium: 2500,
Long: 6000,
Notification: 300,
},
LibreTranslate: {
URL: '',
APIKey: '',
},
Agents: {
LLMServiceID: '',
},
},
};
2 changes: 1 addition & 1 deletion server/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ PLUGIN_PACKAGES += mattermost-plugin-channel-export-v1.3.0
ifeq ($(FIPS_ENABLED),true)
PLUGIN_PACKAGES = mattermost-plugin-playbooks-v2.6.1%2B0e01d28-fips
PLUGIN_PACKAGES += mattermost-plugin-agents-v1.7.2%2B866e2dd-fips
PLUGIN_PACKAGES += mattermost-plugin-boards-v9.2.1%2Bdf49b26-fips
PLUGIN_PACKAGES += mattermost-plugin-boards-v9.2.2%2B4282c63-fips
endif

EE_PACKAGES=$(shell $(GO) list $(BUILD_ENTERPRISE_DIR)/...)
Expand Down
10 changes: 6 additions & 4 deletions server/channels/app/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -2956,18 +2956,20 @@ func (a *App) PermanentDeletePost(rctx request.CTX, postID, deleteByID string) *
return model.NewAppError("DeletePost", "app.post.get.app_error", nil, "", http.StatusBadRequest).Wrap(err)
}

postHasFiles := len(post.FileIds) > 0

// If the post is a burn-on-read post, we should get the original post contents
if post.Type == model.PostTypeBurnOnRead {
tmpPost, appErr := a.getBurnOnReadPost(rctx, post)
revealedPost, appErr := a.getBurnOnReadPost(rctx, post)
if appErr != nil {
rctx.Logger().Warn("Failed to get burn-on-read post", mlog.Err(appErr))
}
if tmpPost != nil {
post = tmpPost
if revealedPost != nil {
postHasFiles = len(revealedPost.FileIds) > 0
}
}

if len(post.FileIds) > 0 {
if postHasFiles {
appErr := a.PermanentDeleteFilesByPost(rctx, post.Id)
if appErr != nil {
return appErr
Expand Down
Loading
Loading