Compare commits

...

297 Commits

Author SHA1 Message Date
Martin Edenhofer
238784d13e Updated for 2.3.1. 2018-03-28 23:58:07 +02:00
Martin Edenhofer
46c61e84b6 Updated gem for security reasons (CVE-2018-3741). 2018-03-23 07:59:27 +01:00
Thorsten Eckel
fdc0abbe7f Fixed issue #1857 - Direct access to organization tickets possible even though shared is deactivated. 2018-03-09 08:57:44 +01:00
Thorsten Eckel
e0daa409ab Fixed issue #1852: Can't configure local MTA after SMTP was configured as outbound server. 2018-03-02 20:27:48 +01:00
Thorsten Eckel
89d4fe19f8 Fixed issue #1852: Can't configure local MTA after SMTP was configured as outbound server. 2018-03-01 20:25:21 +01:00
Thorsten Eckel
5aa751efcf Follow up: Fixed issue #1810 - Reset notification receiving to 'full' again to avoid unwanted spamming to users that have no direct permissions to the ticket. This needs a broader refactoring. 2018-02-27 11:41:29 +01:00
Thorsten Eckel
3ced341ec4 Fixed issue #1810: To high permissions required to move Ticket into Group (change) and receive notification about changes (full). 2018-02-27 10:49:05 +01:00
Thorsten Eckel
f7fb992fa1 Fixed bug: There is nothing like console.notice. 2018-02-23 08:41:53 +01:00
Muhammad Nuzaihan
d8f5663404 Fixes and improves reporting in #1809 by not showing merge but still use user's input 2018-02-21 00:14:11 +08:00
Martin Edenhofer
3c1eb43b8d Performance improvement to generate faster assets (just lookup groups once). 2018-02-20 05:04:49 +01:00
Thorsten Eckel
9fe5c82d7e Fixed issue #1841: Taskbar item race condition causes JS exception. 2018-02-19 18:01:08 +01:00
Thorsten Eckel
76c24c0d47 Added .active? to Import backends default API for e.g. monitoring checks. 2018-02-17 12:40:51 +01:00
Martin Edenhofer
69357d1d4f Improved token copy dialog. 2018-02-17 12:26:16 +01:00
Martin Edenhofer
8684b1e4b5 Fixed issue #1829 - The column widths of a table are shifted after manual change and use of pagination. 2018-02-13 17:14:12 +01:00
Martin Edenhofer
73199b9b6b Fixed issue #1813 - JS error on creating new customer. 2018-02-09 14:21:31 +01:00
Rolf Schmidt
f2e54de705 Allow clearbit failure. 2018-02-07 11:50:34 +01:00
Rolf Schmidt
58c2874f4a Fixed issue #1322 - Customer response via note does not trigger escalation. 2018-02-07 11:47:17 +01:00
Martin Edenhofer
9566acacd3 Updated nokogiri to verion 1.8.2. 2018-02-07 05:33:33 +01:00
Thorsten Eckel
5b344e1bb8 Fixed issue #1795 - Forcing samaccountname as login attribute is not suitable and causes issues in divergent setups. 2018-02-05 14:45:07 +01:00
Thorsten Eckel
1dac03be16 Fixes an issue introduced with commit 1ec2b514bb which causes the functionality of the Sequencer Unit Import::Ldap::User::Lookup::Attributes to change. New attribute dependencies are introduced that the Exchange Sequence can not fulfill. The original functionality was moved to the more generic Sequencer Unit namespace Import::Common::Model::FindBy::UserAttributes. This should be used for the Exchange FolderContact Sequence. 2018-02-05 14:45:01 +01:00
Martin Edenhofer
5589b9cb53 Removed platform list. 2018-02-02 21:23:41 +01:00
Martin Edenhofer
42432ba5f3 Fixed use of new namespace for App.Utils.parseAddressListLocal(). 2018-02-02 21:23:33 +01:00
Martin Edenhofer
0554a91442 Improved html markup. 2018-02-02 21:21:45 +01:00
Martin Edenhofer
32f17a3fb8 Fixed typo. 2018-01-31 18:57:52 +01:00
Martin Edenhofer
f02a3f4cfb Fixed issue# 1790 - On reply of an email, the recipient will not be set if sender header contains invalid email addresses. 2018-01-31 14:21:10 +01:00
pebosi
aa7a28c4dc Fix typo to fix chat (#1791) 2018-01-31 14:21:00 +01:00
Martin Edenhofer
cb963ada6b Improved error handling. 2018-01-31 10:27:21 +01:00
Martin Edenhofer
ea50d0c06f Updated CHANGES for 2.3. 2018-01-30 01:41:07 +01:00
Martin Edenhofer
db5d4de8ad Merge branch 'develop' 2018-01-30 01:26:30 +01:00
Martin Edenhofer
efd4c38f99 Merge branch 'develop' 2018-01-30 00:35:17 +01:00
Martin Edenhofer
d13ff15956 Merge branch 'develop' 2017-12-20 10:56:40 +01:00
Martin Edenhofer
d4c5d81373 Merge branch 'develop' 2017-12-06 17:10:31 +01:00
Martin Edenhofer
66c0975877 Merge branch 'develop' 2017-12-06 16:51:16 +01:00
Martin Edenhofer
76efb008a8 Merge branch 'develop' 2017-12-06 15:39:41 +01:00
Martin Edenhofer
abc0541244 Merge branch 'develop' 2017-12-06 09:56:14 +01:00
Martin Edenhofer
c9f8022f83 Merge branch 'develop' 2017-11-30 11:33:56 +01:00
Martin Edenhofer
dfc757968e Merge branch 'develop' 2017-11-30 09:32:27 +01:00
Martin Edenhofer
52bc45c0f8 Merge branch 'develop' 2017-11-20 12:03:21 +01:00
Martin Edenhofer
cbc8ba5467 Merge branch 'develop' 2017-11-14 23:03:43 +01:00
Martin Edenhofer
5f071e7d7f Merge branch 'develop' 2017-11-07 08:19:41 +01:00
Martin Edenhofer
1dcd6a243c Merge branch 'develop' 2017-11-06 03:03:07 +01:00
Martin Edenhofer
679deb1cf3 Merge branch 'develop' 2017-11-03 08:14:33 +01:00
Martin Edenhofer
6f6ac44978 Merge branch 'develop' 2017-10-30 13:35:44 +01:00
Martin Edenhofer
0bb341cb7e Merge branch 'develop' 2017-10-25 14:05:59 +02:00
Martin Edenhofer
6c122e046b Merge branch 'develop' 2017-10-25 10:15:04 +02:00
Martin Edenhofer
57c2dad0a3 Merge branch 'develop' 2017-10-23 03:19:56 +02:00
Martin Edenhofer
faefd529b4 Merge branch 'develop' 2017-10-09 02:27:20 +02:00
Martin Edenhofer
1481a12035 Merge branch 'develop' 2017-10-09 01:37:42 +02:00
Martin Edenhofer
2bf0635e0d Merge branch 'develop' 2017-09-27 11:02:30 +02:00
Martin Edenhofer
2211274bc5 Merge branch 'develop' 2017-09-12 16:39:39 +02:00
Martin Edenhofer
c229c42838 Merge branch 'develop' 2017-09-11 06:45:49 +02:00
Martin Edenhofer
a3c71f6558 Merge branch 'develop' 2017-09-10 19:43:13 +02:00
Thorsten Eckel
db8b85f767 Merge branch 'develop' 2017-09-06 15:01:15 +02:00
Martin Edenhofer
f1664c3841 Merge branch 'develop' 2017-09-05 21:54:52 +02:00
Martin Edenhofer
151c298056 Merge branch 'develop' 2017-08-31 09:05:09 +02:00
Martin Edenhofer
38f51ce6b2 Merge branch 'develop' 2017-08-28 11:44:51 +02:00
Martin Edenhofer
434f3e963e Merge branch 'develop' 2017-08-25 05:38:22 +02:00
Martin Edenhofer
b853dd1597 Merge branch 'develop' 2017-08-24 01:00:34 +02:00
Martin Edenhofer
3b5b6f612f Merge branch 'develop' 2017-08-23 17:16:20 +02:00
Martin Edenhofer
962043c520 Merge branch 'develop' 2017-08-22 14:58:32 +02:00
Martin Edenhofer
8394be87ed Merge branch 'develop' 2017-08-14 11:32:42 +02:00
Martin Edenhofer
5b547ceb3c Merge branch 'develop' 2017-08-13 11:55:41 +02:00
Martin Edenhofer
789ee08485 Merge branch 'develop' 2017-08-11 12:08:58 +02:00
Martin Edenhofer
490937859a Merge branch 'develop' 2017-07-29 13:03:58 +02:00
Martin Edenhofer
dfc306a2ac Merge branch 'develop' 2017-07-28 13:57:37 +02:00
Martin Edenhofer
dea06015a1 Merge branch 'develop' 2017-07-28 11:48:50 +02:00
Martin Edenhofer
2711e3392d Merge branch 'develop' 2017-07-27 06:38:29 +02:00
Martin Edenhofer
f5e1fe0c2f Merge branch 'develop' 2017-07-24 15:26:00 +02:00
Martin Edenhofer
dbbb4ac7a1 Merge branch 'develop' 2017-07-21 15:09:34 +02:00
Martin Edenhofer
8ec2ffdde1 Merge branch 'develop' 2017-07-20 17:22:54 +02:00
Martin Edenhofer
b76664e7ae Merge branch 'develop' 2017-07-20 15:58:47 +02:00
Martin Edenhofer
704c537749 Merge branch 'develop' 2017-07-20 15:00:37 +02:00
Martin Edenhofer
633c99bb72 Merge branch 'develop' 2017-07-19 11:07:56 +02:00
Martin Edenhofer
44051d8023 Merge branch 'develop' 2017-07-16 18:15:24 +02:00
Martin Edenhofer
50dc143c1b Merge branch 'develop' 2017-07-14 15:58:16 +02:00
Martin Edenhofer
6d44275869 Merge branch 'develop' 2017-07-13 20:53:59 +02:00
Martin Edenhofer
b1b3bf6d3c Merge branch 'develop' 2017-07-12 13:30:01 +02:00
Martin Edenhofer
77081ecd4d Merge branch 'develop' 2017-07-04 16:05:04 +02:00
Martin Edenhofer
b823b960d8 Merge branch 'develop' 2017-06-30 08:32:40 +02:00
Martin Edenhofer
e08f634125 Merge branch 'develop' 2017-06-21 09:10:41 +02:00
Martin Edenhofer
ab5e8d9338 Merge branch 'develop' 2017-06-19 20:01:15 +02:00
Martin Edenhofer
9a29ea8f14 Merge branch 'develop' 2017-06-13 02:40:32 +02:00
Martin Edenhofer
cf87e00b21 Merge branch 'develop' 2017-06-13 01:57:29 +02:00
Martin Edenhofer
6233b0a9ec Merge branch 'develop' 2017-06-01 18:32:42 +02:00
Martin Edenhofer
04b1bc638c Merge branch 'develop' 2017-05-29 06:57:52 +02:00
Martin Edenhofer
a78938f7c2 Merge branch 'develop' 2017-05-23 11:05:51 +02:00
Martin Edenhofer
1d23308454 Merge branch 'develop' 2017-05-23 10:30:03 +02:00
Martin Edenhofer
6bc9c00ab8 Merge branch 'develop' 2017-05-16 15:41:06 +02:00
Martin Edenhofer
bc131742be Merge branch 'develop' 2017-05-16 14:22:22 +02:00
Martin Edenhofer
5a12aa0167 Merge branch 'develop' 2017-05-16 01:47:49 +02:00
Martin Edenhofer
b3ab9d0055 Merge branch 'develop' 2017-05-16 00:57:14 +02:00
Martin Edenhofer
1bde8f91bc Merge branch 'develop' 2017-05-15 15:31:15 +02:00
Martin Edenhofer
47ef1b7e5d Merge branch 'develop' 2017-05-11 23:54:32 +02:00
Martin Edenhofer
88c7816f5c Merge branch 'develop' 2017-05-08 17:09:55 +02:00
Martin Edenhofer
82339c6c18 Merge branch 'develop' 2017-05-08 16:56:10 +02:00
Martin Edenhofer
04a609c3a8 Merge branch 'develop' 2017-05-05 15:23:04 +02:00
Martin Edenhofer
60430139aa Merge branch 'develop' 2017-05-02 10:45:06 +02:00
Martin Edenhofer
7d1c655ee3 Merge branch 'develop' 2017-04-28 16:50:31 +02:00
Martin Edenhofer
e34c1c9b79 Merge branch 'develop' 2017-04-28 12:48:40 +02:00
Thorsten Eckel
3c430b35ef Fixed issue #906 - Doorkeeper tokens should be refreshable but aren't. 2017-04-24 13:58:03 +02:00
Rolf Schmidt
7ad3c70311 Fixed issue #975 - Exception in OTRS Import. 2017-04-24 11:58:07 +02:00
Martin Edenhofer
c270bc1e67 Merge branch 'develop' 2017-04-21 14:36:50 +02:00
Thorsten Eckel
3d19bfdcf7 Fixed issue #912 - Long Twitter direct messages are shown as link after 140 chars. 2017-04-21 13:58:33 +02:00
Martin Edenhofer
dc4a55cc5c Merge branch 'develop' 2017-04-21 12:38:25 +02:00
Martin Edenhofer
6e8886277d Merge branch 'develop' 2017-04-21 06:17:09 +02:00
Martin Edenhofer
74e96e92b2 Merge branch 'develop' 2017-04-20 00:22:13 +02:00
Martin Edenhofer
287b1f0d01 Merge branch 'develop' 2017-04-18 09:57:19 +02:00
Martin Edenhofer
feee46e29b Merge branch 'develop' 2017-04-08 08:32:45 +02:00
Martin Edenhofer
991efe36e4 Merge branch 'develop' 2017-04-05 22:23:05 +02:00
Martin Edenhofer
a2aacb20fa Merge branch 'develop' 2017-03-31 16:20:21 +02:00
Martin Edenhofer
592e978062 Merge branch 'develop' 2017-03-31 14:01:20 +02:00
Martin Edenhofer
a4769c8bc7 Merge branch 'develop' 2017-03-27 14:49:54 +02:00
Martin Edenhofer
d1378d53f1 Merge branch 'develop' 2017-03-25 14:44:10 +01:00
Martin Edenhofer
f0b91d3269 Merge branch 'develop' 2017-03-23 21:10:03 +01:00
Martin Edenhofer
48c77dd688 Merge branch 'develop' 2017-03-21 16:06:51 +01:00
Martin Edenhofer
d86d904395 Merge branch 'develop' 2017-03-21 10:05:58 +01:00
Martin Edenhofer
5efc455f0c Merge branch 'develop' 2017-03-18 23:16:57 +01:00
Martin Edenhofer
be3bbeba20 Merged develop into master. 2017-03-18 13:45:42 +01:00
Martin Edenhofer
31ab1b614c Merge branch 'develop' 2017-03-17 08:09:20 +01:00
Martin Edenhofer
4bc5fa4693 Merge branch 'develop' 2017-03-14 19:24:36 +01:00
Martin Edenhofer
418a64f401 Merge branch 'develop' 2017-03-14 13:33:37 +01:00
Martin Edenhofer
abe46270a6 Merge branch 'develop' 2017-03-03 10:54:22 +01:00
Martin Edenhofer
1249a77150 Merge branch 'develop' 2017-03-03 09:46:01 +01:00
Martin Edenhofer
cfa6b9ed16 Merge branch 'develop' 2017-02-24 23:19:06 +01:00
Rolf Schmidt
aa2303f999 Merge branch 'develop' 2017-02-24 09:27:43 +01:00
Martin Edenhofer
d5616684f8 Merge branch 'develop' 2017-02-22 07:12:36 +01:00
Martin Edenhofer
0f75ba57bd Merge branch 'develop' 2017-02-15 17:42:20 +01:00
Martin Edenhofer
c83675bbba Merge branch 'develop' 2017-02-15 13:39:29 +01:00
Martin Edenhofer
17d16d405c Merge branch 'develop' 2017-02-06 11:48:59 +01:00
Martin Edenhofer
76795ca302 Merge branch 'develop' 2017-02-06 00:16:24 +01:00
Martin Edenhofer
5d145bd09f Merge branch 'develop' 2017-02-05 19:26:16 +01:00
Martin Edenhofer
82471552a8 Merge branch 'develop' 2017-02-01 23:24:18 +01:00
Rolf Schmidt
dc60574129 Merge branch 'develop' 2017-01-23 15:05:52 +01:00
Martin Edenhofer
d33a96dee2 Merge branch 'develop' 2017-01-19 06:18:19 +01:00
Martin Edenhofer
0098d4ab82 Merge branch 'develop' 2017-01-17 15:57:42 +01:00
Martin Edenhofer
bb03b5eab8 Merge branch 'develop' 2017-01-17 12:41:03 +01:00
Martin Edenhofer
17eb0f84ec Merge branch 'develop' 2017-01-17 08:56:18 +01:00
Martin Edenhofer
56d0523c1f Merge branch 'develop' 2017-01-04 15:21:24 +01:00
Martin Edenhofer
9fa18758bc Merge branch 'develop' 2016-12-21 14:12:06 +01:00
Martin Edenhofer
d2f2c55b06 Merge branch 'develop' 2016-12-21 08:50:52 +01:00
Martin Edenhofer
f4a409bd6e Merge branch 'develop' 2016-12-21 00:13:59 +01:00
Martin Edenhofer
971b724d4c Merge branch 'develop' 2016-12-18 12:45:13 +01:00
Martin Edenhofer
3263c6f2ba Merge branch 'develop' 2016-12-16 15:49:33 +01:00
Martin Edenhofer
359b026535 Merge branch 'develop' 2016-12-15 17:16:38 +01:00
Martin Edenhofer
c63518fd3e Merge branch 'develop' 2016-12-14 16:06:09 +01:00
Martin Edenhofer
24ba3cff44 Merge branch 'develop' 2016-12-06 13:29:23 +01:00
Martin Edenhofer
f7066e1995 Merge branch 'develop' 2016-12-06 12:23:13 +01:00
Martin Edenhofer
6844499309 Merge branch 'develop' 2016-11-25 16:59:16 +01:00
Martin Edenhofer
afa3e47eab Merge branch 'develop' 2016-11-25 14:22:00 +01:00
Martin Edenhofer
5f3e9298f1 Merge branch 'develop' 2016-11-24 16:03:45 +01:00
Martin Edenhofer
e4dd303357 Merge branch 'develop' 2016-11-21 17:07:30 +01:00
Martin Edenhofer
2fa06eee3d Merge branch 'develop' 2016-11-21 08:58:54 +01:00
Martin Edenhofer
dc0ac03334 Merge branch 'develop' 2016-11-19 16:42:10 +01:00
Martin Edenhofer
c5a1d69ec5 Merge branch 'develop' 2016-11-19 16:35:07 +01:00
Martin Edenhofer
9891981f92 Merge branch 'develop' 2016-11-17 15:12:22 +01:00
Martin Edenhofer
2c721f71e7 Merge branch 'develop' 2016-11-17 10:03:34 +01:00
Martin Edenhofer
0b4a4be0b7 Merge branch 'develop' 2016-11-16 23:21:05 +01:00
Martin Edenhofer
b13bb2fcaf Added change log. 2016-11-14 08:37:51 +01:00
Martin Edenhofer
d9ba369fcf Merge branch 'develop' 2016-11-14 08:36:58 +01:00
Martin Edenhofer
3adece0db5 Merge branch 'develop' 2016-11-14 00:03:57 +01:00
Martin Edenhofer
7101ffc277 Merge branch 'develop' 2016-11-12 16:44:43 +01:00
Martin Edenhofer
19a7a439b8 Merge branch 'develop' 2016-11-11 19:29:56 +01:00
Martin Edenhofer
e728320241 Merge branch 'develop' 2016-10-30 07:08:08 +01:00
Martin Edenhofer
1bc17afc53 Merge branch 'master' of git.znuny.com:zammad/zammad 2016-10-30 07:07:39 +01:00
Thorsten Eckel
ee5c58f53a Fixed bug: Zip archive doesn't contain sub folder content. 2016-10-19 08:25:51 +02:00
Martin Edenhofer
9bdf6d7b81 Merge branch 'develop' 2016-10-19 07:50:08 +02:00
Thorsten Eckel
5754fdccdd Working on CI tag/branch pushing, syncing, deployment issue. 2016-10-19 07:32:05 +02:00
Thorsten Eckel
4901050d57 Working on issue not syncing to github correctly. 2016-10-19 07:25:18 +02:00
Martin Edenhofer
7980c8cb93 Merge branch 'develop' 2016-10-19 07:21:10 +02:00
Martin Edenhofer
7e7088388d Merge branch 'develop' 2016-10-17 16:43:54 +02:00
Martin Edenhofer
2f6e52d63d Merge branch 'develop' 2016-09-28 16:08:28 +02:00
Martin Edenhofer
bde8babb43 Merge branch 'develop' 2016-09-28 08:53:02 +02:00
Martin Edenhofer
d6d68fb363 Merge branch 'develop' 2016-09-19 07:47:06 +02:00
Martin Edenhofer
814ffed0f0 Merge branch 'develop' 2016-09-15 22:11:57 +02:00
Thorsten Eckel
b013fb8cbc Merge branch 'private-otrs_import_df' 2016-09-13 12:06:56 +02:00
Martin Edenhofer
fbd8e63592 Merge branch 'develop' 2016-09-13 08:55:38 +02:00
Martin Edenhofer
e8ad3965d7 Removed build badged. 2016-09-10 16:47:33 +02:00
Martin Edenhofer
e00981ee23 Merge branch 'master' of git.znuny.com:zammad/zammad 2016-09-10 00:05:18 +02:00
Martin Edenhofer
4e74c6beda Merge branch 'develop' 2016-09-10 00:04:28 +02:00
Thorsten Eckel
2d09e556d7 Added deployment of archives. 2016-09-07 15:31:28 +02:00
Martin Edenhofer
8cd39398d6 Merge branch 'develop' 2016-09-06 16:07:33 +02:00
Martin Edenhofer
94c616ffe3 Merge branch 'develop' 2016-08-25 10:00:36 +02:00
Martin Edenhofer
57649bb888 Merge branch 'develop' 2016-08-23 09:49:40 +02:00
Martin Edenhofer
7e9442ec4a Merge branch 'develop' 2016-08-21 21:38:00 +02:00
Martin Edenhofer
521e6265fd Merge branch 'develop' 2016-08-19 13:58:26 +02:00
Martin Edenhofer
a42a9689fc Merge branch 'develop' 2016-08-19 13:48:46 +02:00
Martin Edenhofer
d9ffb8001d Merge branch 'develop' 2016-07-28 13:39:08 +02:00
Martin Edenhofer
ec86d26ae6 Merge branch 'develop' 2016-07-24 23:52:04 +02:00
Martin Edenhofer
e00efc821a Merge branch 'develop' 2016-07-18 19:35:51 +02:00
Martin Edenhofer
f04be8ca93 Merge branch 'develop' 2016-07-12 20:50:32 +02:00
Martin Edenhofer
c7ff6a323a Merge branch 'develop' 2016-07-08 11:28:43 +02:00
Martin Edenhofer
34833416bc Merge branch 'develop' 2016-06-30 09:50:09 +02:00
Martin Edenhofer
d7a6e28d81 Merge branch 'develop' 2016-06-29 00:18:44 +02:00
Martin Edenhofer
c13531d720 Merge branch 'develop' 2016-06-27 11:28:22 +02:00
Martin Edenhofer
4a40cced7d Merge branch 'develop' 2016-06-26 08:07:04 +02:00
Martin Edenhofer
450de10cc7 Merge branch 'develop' 2016-06-23 08:24:56 +02:00
Martin Edenhofer
5e587a455c Merge branch 'develop' 2016-06-22 08:54:24 +02:00
Martin Edenhofer
04aef9b258 Merge branch 'develop' 2016-06-20 15:52:43 +02:00
Martin Edenhofer
9b72557d13 Merge branch 'develop' 2016-06-15 06:58:36 +02:00
Martin Edenhofer
a5e0bc30c1 Merge branch 'develop' 2016-06-09 13:40:27 +02:00
Martin Edenhofer
458c166e9f Merge branch 'develop' 2016-06-08 16:43:29 +02:00
Martin Edenhofer
3373e5d141 Merge branch 'develop' 2016-06-08 10:48:12 +02:00
Martin Edenhofer
8f6b8de617 Merge branch 'develop' 2016-06-08 07:42:19 +02:00
Martin Edenhofer
22b21a82e7 Merge branch 'develop' 2016-06-07 07:02:25 +02:00
Martin Edenhofer
b4151b299f Merge branch 'develop' 2016-06-04 02:23:14 +02:00
Martin Edenhofer
e969fca8c4 Merge branch 'develop' 2016-06-03 07:08:59 +02:00
Martin Edenhofer
e59993a5d6 Merge branch 'develop' 2016-05-31 08:31:56 +02:00
Martin Edenhofer
3adc9d4cf1 Merge branch 'develop' 2016-05-30 13:21:46 +02:00
Martin Edenhofer
c1153250cb Merge branch 'develop' 2016-05-30 00:00:52 +02:00
Martin Edenhofer
7718dc28d3 Merge branch 'develop'
# Conflicts:
#	README.md
2016-05-27 17:30:22 +02:00
Martin Edenhofer
1894580ae6 Updated badge url. 2016-05-27 17:28:26 +02:00
Martin Edenhofer
11df714bbf Merge branch 'develop' 2016-05-20 15:18:36 +02:00
Martin Edenhofer
72adee37a8 Merge branch 'develop' 2016-05-20 06:10:19 +02:00
Martin Edenhofer
0e8f460d73 Merge branch 'develop' 2016-05-06 16:25:09 +02:00
Martin Edenhofer
4e62d5d0d2 Merge branch 'develop' 2016-05-06 09:40:16 +02:00
Martin Edenhofer
004e5ba457 Merge branch 'develop' 2016-05-04 12:13:34 +02:00
Martin Edenhofer
f1a8a8da6f Merge branch 'develop' 2016-05-03 16:01:03 +02:00
Martin Edenhofer
bfb44d1189 Merge branch 'develop' 2016-05-01 14:18:26 +02:00
Martin Edenhofer
d64afd8d97 Merge branch 'develop' 2016-04-14 17:47:03 +02:00
Martin Edenhofer
97cfdb9c4c Merge branch 'develop' 2016-04-12 08:25:06 +02:00
Martin Edenhofer
bb336f63f1 Merge branch 'develop' 2016-03-25 18:23:12 +01:00
Martin Edenhofer
80da08f447 Merge branch 'develop' 2016-03-23 09:31:02 +01:00
Martin Edenhofer
a6db2b7c90 Merge branch 'develop' 2016-03-17 17:45:04 +01:00
Martin Edenhofer
e1c3f83324 Merge branch 'develop' 2016-03-17 10:41:20 +01:00
Martin Edenhofer
8545a44ad1 Merge branch 'develop' 2016-03-16 11:17:22 +01:00
Martin Edenhofer
cfbe7510a2 Merge branch 'develop' 2016-03-16 09:10:05 +01:00
Martin Edenhofer
1479c32edb Merge branch 'develop' 2016-03-15 00:34:36 +01:00
Martin Edenhofer
a9d428bf5a Merge branch 'develop' 2016-03-11 10:38:15 +01:00
Martin Edenhofer
3a62eb11da Merge branch 'develop' 2016-03-04 07:07:55 +01:00
Martin Edenhofer
2df5f81029 Merge branch 'develop' 2016-03-03 03:42:27 +01:00
Martin Edenhofer
b88c23bc92 Merge branch 'develop' 2016-02-28 00:16:49 +01:00
Martin Edenhofer
4144fbaf5b Merge branch 'develop' 2016-02-25 23:46:10 +01:00
Martin Edenhofer
86ddc93f52 Merge branch 'develop' 2016-02-23 14:29:01 +01:00
Martin Edenhofer
8a1b583535 Merge branch 'develop' 2016-02-23 01:38:39 +01:00
Martin Edenhofer
7623628b86 Merge branch 'develop' 2016-02-12 08:53:57 +01:00
Martin Edenhofer
f753bc203f Merge branch 'develop' 2016-02-11 13:25:39 +01:00
Martin Edenhofer
ff9ba10705 Merge branch 'develop' 2016-02-11 02:11:06 +01:00
Martin Edenhofer
fdc25bdc26 Merge branch 'develop' 2016-02-09 01:36:03 +01:00
Martin Edenhofer
d154a587ad Merge branch 'develop' 2016-02-04 12:55:30 +01:00
Martin Edenhofer
a9cc4f037b Merge branch 'develop' 2016-02-04 10:41:41 +01:00
Martin Edenhofer
50d6679189 Merge branch 'develop' 2016-02-03 13:19:51 +01:00
Martin Edenhofer
b82cf4e1d6 Merge branch 'develop' 2016-01-29 15:19:23 +01:00
Martin Edenhofer
fa6eaa6710 Merge branch 'develop'
# Conflicts:
#	README.md
2016-01-26 19:59:34 +01:00
Martin Edenhofer
2ca17ac1bd Updated build status url. 2016-01-26 13:57:24 +01:00
Martin Edenhofer
862ecd7d36 Merge branch 'develop' 2016-01-22 14:47:53 +01:00
Martin Edenhofer
e38b72593b Merge branch 'develop' 2016-01-12 11:14:24 +01:00
Martin Edenhofer
81883cae8f Revert "update terminal start script"
This reverts commit 63770c9cbf.
2016-01-12 11:13:40 +01:00
Felix Niklas
63770c9cbf update terminal start script 2016-01-12 10:58:46 +01:00
Martin Edenhofer
aaf5da55a0 Merge branch 'develop' 2015-12-28 11:33:58 +01:00
Martin Edenhofer
8455d9ae17 Merge branch 'develop' 2015-12-21 16:03:31 +01:00
Martin Edenhofer
839a8e8eb4 Merge branch 'develop' 2015-12-13 15:26:35 +01:00
Martin Edenhofer
7aa3f6eaee Updated build url. 2015-12-10 09:44:16 +01:00
Martin Edenhofer
219abc69a3 Merge branch 'develop' 2015-12-10 09:21:59 +01:00
Martin Edenhofer
595822c928 Merge branch 'develop' 2015-12-02 02:27:40 +01:00
Martin Edenhofer
32112937b1 Merge branch 'develop' 2015-12-02 01:41:10 +01:00
Martin Edenhofer
a0889c5b99 Merge branch 'develop' 2015-12-01 22:03:52 +01:00
Martin Edenhofer
4bc281bfb0 Merge branch 'develop' 2015-12-01 20:04:51 +01:00
Martin Edenhofer
e12ec607d7 Merge branch 'develop' 2015-11-30 15:11:25 +01:00
Martin Edenhofer
545f393293 Merge branch 'develop' 2015-11-30 01:24:11 +01:00
Martin Edenhofer
4efa152e93 Merge branch 'master' of github.com:martini/zammad 2015-11-24 03:39:17 +01:00
Martin Edenhofer
0ebda4f32a Merge branch 'develop'
Conflicts:
	README.md
	script/websocket-server.rb
2015-11-24 03:38:55 +01:00
Martin Edenhofer
b94f54799f Merge branch 'develop' of http://ci.lab.zammad.com/core/zammad 2015-11-24 03:07:38 +01:00
Martin Edenhofer
99f0b4e2e2 Merge branch 'develop' 2015-11-19 14:27:39 +01:00
Martin Edenhofer
53cb906733 Merge branch 'develop' 2015-11-01 01:49:02 +01:00
Martin Edenhofer
2c31fe8a84 Merge branch 'develop' 2015-10-31 23:40:10 +01:00
Martin Edenhofer
6c5e673a2c Merge branch 'develop' 2015-10-02 15:31:54 +02:00
Martin Edenhofer
574b891a33 Merge branch 'develop' 2015-09-28 02:12:31 +02:00
Martin Edenhofer
9ef1d3f58b Merge branch 'develop'
Conflicts:
	extras/zammad.spec
2015-09-28 01:24:03 +02:00
Martin Edenhofer
8b3f432746 Merge branch 'develop' 2015-09-01 03:15:03 +02:00
Martin Edenhofer
14a9df261e Merge branch 'develop' 2015-08-31 15:11:27 +02:00
Martin Edenhofer
5620a2847b Merge branch 'develop' 2015-08-31 12:42:04 +02:00
Martin Edenhofer
13aaae3835 Merge branch 'develop' 2015-08-30 09:19:02 +02:00
Martin Edenhofer
2d4fcd3a4f Merge branch 'develop' 2015-08-30 08:22:27 +02:00
Martin Edenhofer
f4f70b0bc2 Merge branch 'develop' 2015-08-30 01:36:18 +02:00
Martin Edenhofer
1d279bb88f Merge branch 'develop' 2015-08-30 01:32:10 +02:00
Martin Edenhofer
fe4757cbf9 Merge branch 'develop' 2015-08-21 17:03:28 +02:00
me
1d476f163e Use also mysql on test. 2015-08-21 16:53:38 +02:00
Martin Edenhofer
513701b6d2 Merge branch 'develop'
Conflicts:
	README.md
	script/websocket-server.rb
2015-08-11 15:17:14 +02:00
Thorsten Eckel
1a1b661714 Fixed typo. 2015-07-16 09:50:18 +02:00
Roy Kaldung
6081a98279 Update README.md 2015-01-12 12:39:26 +01:00
Roy Kaldung
157991c33d Update README.md 2015-01-12 12:38:11 +01:00
Roy Kaldung
ef67be9170 We like to know if it's starting or stopping 2014-11-06 17:24:45 +01:00
Martin Edenhofer
39f3819303 Merge branch 'develop' 2014-11-06 16:13:39 +01:00
Martin Edenhofer
7a676bd563 Merge branch 'develop' into 'master', goto next level.
Conflicts:
	Gemfile
	README.md
	extras/zammad.spec
2014-10-05 20:42:39 +02:00
Roy Kaldung
80c54daa03 Delete httpd.spec 2014-05-02 12:47:51 +02:00
Roy Kaldung
99c88cde62 Delete apr.spec 2014-05-02 12:47:41 +02:00
Roy Kaldung
17d113ca20 removed old file 2014-05-02 12:47:18 +02:00
Martin Edenhofer
2fbf4324a7 Update Gemfile 2014-02-22 14:46:25 +01:00
Roy Kaldung
b46c390d30 minor change to test GitHub hook (automatic deploy) 2013-12-04 18:22:21 +01:00
Martin Edenhofer
3c3651bc52 Merge branch 'develop'
Conflicts:
	app/controllers/tickets_controller.rb
2013-09-20 13:52:53 +02:00
Roy Kaldung
abeeb5e66d Updated Build Status image URL 2013-08-23 21:00:55 +02:00
rkaldung
09d61ce4c8 added dependency 2013-08-14 20:38:09 +02:00
rkaldung
cc1c4495b2 Merge branch 'master' of github.com:martini/zammad 2013-08-14 20:27:15 +02:00
rkaldung
7b1ec4d17f modified install section 2013-08-14 20:26:25 +02:00
rkaldung
99b3201ccf added initial spec for rpm 2013-08-14 20:20:55 +02:00
Roy Kaldung
d4205d9ba6 removed Windows ;-) 2013-08-14 20:08:23 +02:00
Roy Kaldung
8d57633390 minor changes on comments 2013-08-05 19:18:52 +02:00
40 changed files with 1914 additions and 324 deletions

View File

@@ -259,6 +259,7 @@ test:integration:clearbit:
- rake db:migrate
- ruby -I test test/integration/clearbit_test.rb
- rake db:drop
allow_failure: true
test:integration:sipgate:
stage: test

View File

@@ -1,16 +1,51 @@
# Change Log
## [2.3.0](https://github.com/zammad/zammad/tree/2.3.0) (2018-xx-xx)
## [2.3.1](https://github.com/zammad/zammad/tree/2.3.1) (2018-03-29)
[Full Changelog](https://github.com/zammad/zammad/compare/2.3.0...2.3.1)
**Fixed bugs:**
- Direct access to organization tickets possible even though shared is deactivated [\#1857](https://github.com/zammad/zammad/issues/1857) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Can't create email-account with local MTA as outgoing server [\#1852](https://github.com/zammad/zammad/issues/1852) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Issues in the rights-management [\#1810](https://github.com/zammad/zammad/issues/1810) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Reporting: profile condition is ignored [\#1809](https://github.com/zammad/zammad/issues/1809) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Taskbar item race condition causes JS exception [\#1841](https://github.com/zammad/zammad/issues/1841) [[bug](https://github.com/zammad/zammad/labels/bug)]
- The column widths of a table are shifted after manual change and use of pagination. [\#1829](https://github.com/zammad/zammad/issues/1829) [[bug](https://github.com/zammad/zammad/labels/bug)]
- JS error on creating new customer [\#1813](https://github.com/zammad/zammad/issues/1813) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Customer response via note does not trigger escalation [\#1322](https://github.com/zammad/zammad/issues/1322) [[bug](https://github.com/zammad/zammad/labels/bug)]
- LDAP authentication doen't work in 2.3.x [\#1795](https://github.com/zammad/zammad/issues/1795) [[bug](https://github.com/zammad/zammad/labels/bug)]
- XSS issue in ticket overview [\#1869](https://github.com/zammad/zammad/issues/1869) [[bug](https://github.com/zammad/zammad/labels/bug)]
## [2.3.0](https://github.com/zammad/zammad/tree/2.3.0) (2018-01-30)
[Full Changelog](https://github.com/zammad/zammad/compare/2.2.0...2.3.0)
**Implemented enhancements:**
- Convert Chat into Ticket [\#422](https://github.com/zammad/zammad/issues/422)
- Added support of blocking IPs and/or countries for chat.
- Added support to search and reopen already finised chat sessions.
- LDAP User uid attribute is not reliable [\#1709](https://github.com/zammad/zammad/issues/1709) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Add article.body support for triggers [\#1745](https://github.com/zammad/zammad/issues/1745) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
**Fixed bugs:**
- Do not allow roles as default signup with admin, admin.\* and ticket.agent permissions [\#1758](https://github.com/zammad/zammad/issues/1758) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
- Attachments with content-id header but not shown as inline part are note taken for forward action [\#1778](https://github.com/zammad/zammad/issues/1778) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Need data\_option\[:null\] - Ticket Object Manager [\#1742](https://github.com/zammad/zammad/issues/1742) [[bug](https://github.com/zammad/zammad/labels/bug)]
- LDAP login not possible since change to objectguid [\#1764](https://github.com/zammad/zammad/issues/1764) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Generated excel report fails to create for special strings in ticket titles \(also: CSV formula injection possible\) [\#1756](https://github.com/zammad/zammad/issues/1756) [[bug](https://github.com/zammad/zammad/labels/bug)] [[reporting](https://github.com/zammad/zammad/labels/reporting)]
- Loss of LDAP group assignment is not reflected in Zammad role assignment [\#1751](https://github.com/zammad/zammad/issues/1751) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Ticket search fails for limit exceeding 100 with internal server error [\#1753](https://github.com/zammad/zammad/issues/1753) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Trigger ignoring tag condition [\#1683](https://github.com/zammad/zammad/issues/1683) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Unable to send auto reply if from contains 2 or more senders with invalid email address [\#1749](https://github.com/zammad/zammad/issues/1749) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Report for Created tickets should not have "merged" tickets [\#1741](https://github.com/zammad/zammad/issues/1741) [[bug](https://github.com/zammad/zammad/labels/bug)] [[reporting](https://github.com/zammad/zammad/labels/reporting)]
- Exchange integration process stuck at 1000 users [\#1740](https://github.com/zammad/zammad/issues/1740) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Telegram bot error when exit and delete telegram group [\#1732](https://github.com/zammad/zammad/issues/1732) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Exchange integration tries to import user twice and fails [\#1663](https://github.com/zammad/zammad/issues/1663) [[bug](https://github.com/zammad/zammad/labels/bug)]
- LDAP - missing support for groupOfUniqueNames / uniquemember [\#1664](https://github.com/zammad/zammad/issues/1664) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Removed LDAP attributes aren't reflected on the user [\#1665](https://github.com/zammad/zammad/issues/1665) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Wrong ticket number count in preview [\#1723](https://github.com/zammad/zammad/issues/1723) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Zammad Api for idoit.object\_ids broken [\#1711](https://github.com/zammad/zammad/issues/1711) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Unable to login with Office365 [\#1710](https://github.com/zammad/zammad/issues/1710) [[bug](https://github.com/zammad/zammad/labels/bug)]
- No user preference for out-of-office available [\#1699](https://github.com/zammad/zammad/issues/1699) [[bug](https://github.com/zammad/zammad/labels/bug)]
- SipgateController - undefined method `each' for nil:NilClass \(NoMethodError\) [\#1698](https://github.com/zammad/zammad/issues/1698) [[bug](https://github.com/zammad/zammad/labels/bug)]
- Agent ticket overview broken [\#789](https://github.com/zammad/zammad/issues/789) [[bug](https://github.com/zammad/zammad/labels/bug)]
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*

View File

@@ -213,7 +213,7 @@ GEM
logging (2.2.2)
little-plugger (~> 1.1)
multi_json (~> 1.10)
loofah (2.1.1)
loofah (2.2.2)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lumberjack (1.0.12)
@@ -235,7 +235,7 @@ GEM
net-ldap (0.16.1)
netrc (0.11.0)
nio4r (2.1.0)
nokogiri (1.8.1)
nokogiri (1.8.2)
mini_portile2 (~> 2.3.0)
nori (2.6.0)
notiffany (0.1.1)
@@ -318,8 +318,8 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
rails-observers (0.1.5)
activemodel (>= 4.0)
railties (5.1.4)

View File

@@ -3,9 +3,9 @@
Zammad is a web based open source helpdesk/customer support system with many
features to manage customer communication via several channels like telephone,
facebook, twitter, chat and e-mails. It is distributed under the GNU AFFERO
General Public License (AGPL) and tested on Linux, Solaris, AIX, FreeBSD,
OpenBSD and Mac OS 10.x. Do you receive many e-mails and want to answer them
with a team of agents?
General Public License (AGPL).
Do you receive many e-mails and want to answer them with a team of agents?
You're going to love Zammad!

View File

@@ -195,8 +195,8 @@ class App.ControllerTable extends App.Controller
el.filter('.js-pager').html('')
return
pager = App.view('generic/table_pager')(
page: @shownPage
pages: pages
page: @shownPage
pages: pages
)
if find
el.find('.js-pager').html(pager)
@@ -851,13 +851,21 @@ class App.ControllerTable extends App.Controller
# update store and runtime @headerWidth
@preferencesStore('headerWidth', leftColumnKey, leftWidth)
@headerWidth[leftColumnKey] = leftWidth
_.find(@headers, (column) -> column.name is leftColumnKey).displayWidth = leftWidth
# set header at runtime
for header in @headers
if header.name is leftColumnKey
header.displayWidth = @resizeTargetLeft.outerWidth()
# update store and runtime @headerWidth
if rightColumnKey
@preferencesStore('headerWidth', rightColumnKey, rightWidth)
@headerWidth[rightColumnKey] = rightWidth
_.find(@headers, (column) -> column.name is rightColumnKey).displayWidth = rightWidth
# set header at runtime
for header in @headers
if header.name is rightColumnKey
header.displayWidth = @resizeTargetRight.outerWidth()
sortByColumn: (event) =>
column = $(event.currentTarget).closest('[data-column-key]').attr('data-column-key')

View File

@@ -722,7 +722,7 @@ class App.ChannelEmailAccountWizard extends App.WizardModal
# get params
params = @formParam(e.target)
if params.options.password is @passwordPlaceholder
if params.options && params.options.password is @passwordPlaceholder
params.options.password = @inboundPassword
# let backend know about the channel
@@ -784,7 +784,7 @@ class App.ChannelEmailAccountWizard extends App.WizardModal
params = @formParam(e.target)
params['email'] = @account['meta']['email']
if params.options.password is @passwordPlaceholder
if params.options && params.options.password is @passwordPlaceholder
params.options.password = @outboundPassword
if !params['email'] && @channel

View File

@@ -358,7 +358,6 @@ class ConnectionWizard extends App.WizardModal
# remember payload
user_attributes = {}
for key, value of App.User.attributesGet()
continue if key == 'login'
if (value.tag is 'input' || value.tag is 'richtext' || value.tag is 'textarea') && value.type isnt 'password'
user_attributes[key] = value.display || key
roles = {}
@@ -394,6 +393,7 @@ class ConnectionWizard extends App.WizardModal
givenname: 'firstname'
sn: 'lastname'
mail: 'email'
samaccountname: 'login'
telephonenumber: 'phone'
@userMappingForm.find('tbody tr.js-entry').remove()
@@ -417,14 +417,23 @@ class ConnectionWizard extends App.WizardModal
for key in ['source', 'dest']
if !_.isArray(user_attributes[key])
user_attributes[key] = [user_attributes[key]]
user_attributes_local =
'samaccountname': 'login'
user_attributes_local = {}
length = user_attributes.source.length-1
for count in [0..length]
if user_attributes.source[count] && user_attributes.dest[count]
user_attributes_local[user_attributes.source[count]] = user_attributes.dest[count]
requiredAttribute = Object.keys(user_attributes_local).some( (local_attribute) ->
return user_attributes_local[local_attribute] == 'login'
)
@wizardConfig.user_attributes = user_attributes_local
if !requiredAttribute
@showSlide('js-mapping')
@showAlert('js-mapping', App.i18n.translatePlain("Attribute '%s' is required in the mapping", 'login'))
return
# group role map
group_role_map = @formParam(@groupRoleForm)
for key in ['source', 'dest']
@@ -448,17 +457,8 @@ class ConnectionWizard extends App.WizardModal
buildRowsUserMap: (user_attribute_map) =>
# show static login row
userUidDisplayValue = @wizardConfig.wizardData.backend_user_attributes['samaccountname']
el = [
$(App.view('integration/ldap_user_attribute_row_read_only')(
key: userUidDisplayValue,
value: 'Login'
))
]
el = []
for source, dest of user_attribute_map
continue if source == 'samaccountname'
continue if !(source of @wizardConfig.wizardData.backend_user_attributes)
el.push @buildRowUserAttribute(source, dest)
el

View File

@@ -127,7 +127,7 @@ class Create extends App.ControllerModal
App.view('profile/token_access_created')(
name: ui.newToken.name
)
post: ->
onShown: ->
@$('.js-select').on('click', ui.selectAll)
onCancel: ->
@close()

View File

@@ -775,10 +775,19 @@ class ChatWindow extends App.Controller
# cleanup params
fqdn = App.Config.get('fqdn')
http_type = App.Config.get('http_type')
url = ''
session = @session
# in case we do not have a model, create one
if session && !session.uiUrl
session = new App.ChatSession(session)
if session && session.uiUrl
url = session.uiUrl()
clean_params =
id: id
prefilledParams:
body: "#{http_type}://#{fqdn}#{@session.uiUrl()}"
body: "#{http_type}://#{fqdn}/#{url}"
title: 'Chat'
App.TaskManager.execute(

View File

@@ -558,6 +558,10 @@ class App.TicketZoom extends App.Controller
# update changes in ui
currentStore = @currentStore()
modelDiff = @formDiff(currentParams, currentStore)
# set followup state if needed
@setDefaultFollowUpState(modelDiff, currentStore)
@markFormDiff(modelDiff)
@taskUpdateAll(modelDiff)
@@ -582,6 +586,43 @@ class App.TicketZoom extends App.Controller
currentStore
setDefaultFollowUpState: (modelDiff, currentStore) ->
# if the default state is set
# and the body get changed to empty
# then we want to reset the state
if @isDefaultFollowUpStateSet && !modelDiff.article.body
@$('.sidebar select[name=state_id]').val(currentStore.ticket.state_id).trigger('change')
@isDefaultFollowUpStateSet = false
return
# set default if body is filled
return if !modelDiff.article.body
# and state got not changed
return if modelDiff.ticket.state_id
# and we are in the customer interface
return if !@permissionCheck('ticket.customer')
# and the default is was not set before
return if @isDefaultFollowUpStateSet
# prevent multiple changes for the default follow up state
@isDefaultFollowUpStateSet = true
# get state
state = App.TicketState.findByAttribute('default_follow_up', true)
# change ui and trigger change
if state
@$('.sidebar[data-tab=ticket] select[name=state_id]').val(state.id).trigger('change')
true
resetDefaultFollowUpState: ->
@isDefaultFollowUpStateSet = false
formCurrent: =>
currentParams =
ticket: @formParam(@el.find('.edit'))
@@ -596,6 +637,10 @@ class App.TicketZoom extends App.Controller
# remove not needed attributes
delete currentParams.article.form_id
if @permissionCheck('ticket.customer')
currentParams.article.internal = ''
currentParams
formDiff: (currentParams, currentStore) ->
@@ -867,6 +912,9 @@ class App.TicketZoom extends App.Controller
# reset task
@taskReset()
# reset default follow up state
@resetDefaultFollowUpState()
# reset/delete uploaded attachments
App.Ajax.request(
type: 'DELETE'

View File

@@ -37,8 +37,11 @@ class UserNew extends App.ControllerModal
# find role_id
if !params.role_ids || _.isEmpty(params.role_ids)
role = App.Role.findByAttribute('name', 'Customer')
params.role_ids = role.id
role_ids = []
for role of App.Role.all()
if role && role.active is true && role.default_at_signup is true
role_ids.push role.id
params.role_ids = role_ids
@log 'notice', 'updateAttributes', params
user = new App.User

View File

@@ -890,6 +890,29 @@ class App.Utils
text = text.replace(/http(s|):\/\/[-A-Za-z0-9+&@#\/%?=~_\|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]/img, placeholder)
text.length
@parseAddressListLocal: (line) ->
recipients = emailAddresses.parseAddressList(line)
result = []
if !_.isEmpty(recipients)
for recipient in recipients
if recipient && recipient.address
result.push recipient.address
return result
# workaround for email-addresses.js issue with this kind of
# mail headers "From: invalid sender, realname <sender@example.com>"
# email-addresses.js is returning null because it can't parse the
# whole header
if _.isEmpty(recipients) && line.match('@')
recipients = line.split(',')
re = /(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/
for recipient in recipients
if recipient && recipient.match('@')
localResult = recipient.match(re)
if localResult && localResult[0]
result.push localResult[0]
result
@getRecipientArticle: (ticket, article, article_created_by, type, email_addresses = [], all) ->
# empty form
@@ -938,16 +961,18 @@ class App.Utils
# check if article sender is local
senderIsLocal = false
if !_.isEmpty(article.from)
senders = emailAddresses.parseAddressList(article.from)
if senders && senders[0] && senders[0].address
senderIsLocal = isLocalAddress(senders[0].address)
senders = App.Utils.parseAddressListLocal(article.from)
if senders
for sender in senders
if sender && sender.match('@')
senderIsLocal = isLocalAddress(sender)
# check if article recipient is local
recipientIsLocal = false
if !_.isEmpty(article.to)
recipients = emailAddresses.parseAddressList(article.to)
if recipients && recipients[0] && recipients[0].address
recipientIsLocal = isLocalAddress(recipients[0].address)
recipients = App.Utils.parseAddressListLocal(article.to)
if recipients && recipients[0]
recipientIsLocal = isLocalAddress(recipients[0])
# sender is local
if senderIsLocal
@@ -971,14 +996,14 @@ class App.Utils
# filter for uniq recipients
recipientAddresses = {}
addAddresses = (addressLine, line) ->
lineNew = ''
recipients = emailAddresses.parseAddressList(addressLine)
recipients = App.Utils.parseAddressListLocal(addressLine)
if !_.isEmpty(recipients)
for recipient in recipients
if !_.isEmpty(recipient.address)
localRecipientAddress = recipient.address.toString().toLowerCase()
if !_.isEmpty(recipient)
localRecipientAddress = recipient.toString().toLowerCase()
# check if address is not local
if !isLocalAddress(localRecipientAddress)

View File

@@ -1,6 +1,6 @@
// email-addresses.js - RFC 5322 email address parser
// v 2.0.1
// v 3.0.1
//
// http://tools.ietf.org/html/rfc5322
//
@@ -186,27 +186,7 @@ function parse5322(opts) {
// "First Last" -> "First Last"
// "First Last" -> "First Last"
function collapseWhitespace(s) {
function isWhitespace(c) {
return c === ' ' ||
c === '\t' ||
c === '\r' ||
c === '\n';
}
var i, str;
str = "";
for (i = 0; i < s.length; i += 1) {
if (!isWhitespace(s[i]) || !isWhitespace(s[i + 1])) {
str += s[i];
}
}
if (isWhitespace(str[0])) {
str = str.substring(1);
}
if (isWhitespace(str[str.length - 1])) {
str = str.substring(0, str.length - 1);
}
return str;
return s.replace(/([ \t]|\r\n)+/g, ' ').replace(/^\s*/, '').replace(/\s*$/, '');
}
// UTF-8 pseudo-production (RFC 6532)
@@ -597,10 +577,14 @@ function parse5322(opts) {
return wrap('domain', function domainCheckTLD() {
var result = or(obsDomain, dotAtom, domainLiteral)();
if (opts.rejectTLD) {
if (result.semantic.indexOf('.') < 0) {
if (result && result.semantic && result.semantic.indexOf('.') < 0) {
return null;
}
}
// strip all whitespace from domains
if (result) {
result.semantic = result.semantic.replace(/\s+/g, '');
}
return result;
}());
}
@@ -612,6 +596,36 @@ function parse5322(opts) {
)());
}
// 3.6.2 Originator Fields
// Below we only parse the field body, not the name of the field
// like "From:", "Sender:", or "Reply-To:". Other libraries that
// parse email headers can parse those and defer to these productions
// for the "RFC 5322" part.
// RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
// from = "From:" (mailbox-list / address-list) CRLF
function fromSpec() {
return wrap('from', or(
mailboxList,
addressList
)());
}
// RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
// sender = "Sender:" (mailbox / address) CRLF
function senderSpec() {
return wrap('sender', or(
mailbox,
address
)());
}
// RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
// reply-to = "Reply-To:" address-list CRLF
function replyToSpec() {
return wrap('reply-to', addressList());
}
// 4.1. Miscellaneous Obsolete Tokens
// obs-NO-WS-CTL = %d1-8 / ; US-ASCII control
@@ -766,92 +780,186 @@ function parse5322(opts) {
// ast analysis
function findNode(name, root) {
var i, queue, node;
var i, stack, node;
if (root === null || root === undefined) { return null; }
queue = [root];
while (queue.length > 0) {
node = queue.shift();
stack = [root];
while (stack.length > 0) {
node = stack.pop();
if (node.name === name) {
return node;
}
for (i = 0; i < node.children.length; i += 1) {
queue.push(node.children[i]);
for (i = node.children.length - 1; i >= 0; i -= 1) {
stack.push(node.children[i]);
}
}
return null;
}
function findAllNodes(name, root) {
var i, queue, node, result;
var i, stack, node, result;
if (root === null || root === undefined) { return null; }
queue = [root];
stack = [root];
result = [];
while (queue.length > 0) {
node = queue.shift();
while (stack.length > 0) {
node = stack.pop();
if (node.name === name) {
result.push(node);
}
for (i = 0; i < node.children.length; i += 1) {
queue.push(node.children[i]);
for (i = node.children.length - 1; i >= 0; i -= 1) {
stack.push(node.children[i]);
}
}
return result;
}
function findAllNodesNoChildren(names, root) {
var i, stack, node, result, namesLookup;
if (root === null || root === undefined) { return null; }
stack = [root];
result = [];
namesLookup = {};
for (i = 0; i < names.length; i += 1) {
namesLookup[names[i]] = true;
}
while (stack.length > 0) {
node = stack.pop();
if (node.name in namesLookup) {
result.push(node);
// don't look at children (hence findAllNodesNoChildren)
} else {
for (i = node.children.length - 1; i >= 0; i -= 1) {
stack.push(node.children[i]);
}
}
}
return result;
}
function giveResult(ast) {
function grabSemantic(n) {
return n !== null ? n.semantic : null;
}
var i, ret, addresses, addr, name, aspec, local, domain;
var addresses, groupsAndMailboxes, i, groupOrMailbox, result;
if (ast === null) {
return null;
}
ret = { ast: ast };
addresses = findAllNodes('address', ast);
ret.addresses = [];
for (i = 0; i < addresses.length; i += 1) {
addr = addresses[i];
name = findNode('display-name', addr);
aspec = findNode('addr-spec', addr);
local = findNode('local-part', aspec);
domain = findNode('domain', aspec);
ret.addresses.push({
node: addr,
parts: {
name: name,
address: aspec,
local: local,
domain: domain
},
name: grabSemantic(name),
address: grabSemantic(aspec),
local: grabSemantic(local),
domain: grabSemantic(domain)
});
}
addresses = [];
if (opts.simple) {
ret = ret.addresses;
for (i = 0; i < ret.length; i += 1) {
delete ret[i].node;
// An address is a 'group' (i.e. a list of mailboxes) or a 'mailbox'.
groupsAndMailboxes = findAllNodesNoChildren(['group', 'mailbox'], ast);
for (i = 0; i < groupsAndMailboxes.length; i += 1) {
groupOrMailbox = groupsAndMailboxes[i];
if (groupOrMailbox.name === 'group') {
addresses.push(giveResultGroup(groupOrMailbox));
} else if (groupOrMailbox.name === 'mailbox') {
addresses.push(giveResultMailbox(groupOrMailbox));
}
}
return ret;
result = {
ast: ast,
addresses: addresses,
};
if (opts.simple) {
result = simplifyResult(result);
}
if (opts.oneResult) {
return oneResult(result);
}
if (opts.simple) {
return result && result.addresses;
} else {
return result;
}
}
function giveResultGroup(group) {
var i;
var groupName = findNode('display-name', group);
var groupResultMailboxes = [];
var mailboxes = findAllNodesNoChildren(['mailbox'], group);
for (i = 0; i < mailboxes.length; i += 1) {
groupResultMailboxes.push(giveResultMailbox(mailboxes[i]));
}
return {
node: group,
parts: {
name: groupName,
},
type: group.name, // 'group'
name: grabSemantic(groupName),
addresses: groupResultMailboxes,
};
}
function giveResultMailbox(mailbox) {
var name = findNode('display-name', mailbox);
var aspec = findNode('addr-spec', mailbox);
var comments = findAllNodes('cfws', mailbox);
var local = findNode('local-part', aspec);
var domain = findNode('domain', aspec);
return {
node: mailbox,
parts: {
name: name,
address: aspec,
local: local,
domain: domain,
comments: comments
},
type: mailbox.name, // 'mailbox'
name: grabSemantic(name),
address: grabSemantic(aspec),
local: grabSemantic(local),
domain: grabSemantic(domain),
groupName: grabSemantic(mailbox.groupName),
};
}
function grabSemantic(n) {
return n !== null && n !== undefined ? n.semantic : null;
}
function simplifyResult(result) {
var i;
if (result && result.addresses) {
for (i = 0; i < result.addresses.length; i += 1) {
delete result.addresses[i].node;
}
}
return result;
}
function oneResult(result) {
if (!result) { return null; }
if (!opts.partial && result.addresses.length > 1) { return null; }
return result.addresses && result.addresses[0];
}
/////////////////////////////////////////////////////
var parseString, pos, len, parsed;
var parseString, pos, len, parsed, startProduction;
opts = handleOpts(opts, {});
if (opts === null) { return null; }
parseString = opts.input;
startProduction = {
'address': address,
'address-list': addressList,
'angle-addr': angleAddr,
'from': fromSpec,
'group': group,
'mailbox': mailbox,
'mailbox-list': mailboxList,
'reply-to': replyToSpec,
'sender': senderSpec,
}[opts.startAt] || addressList;
if (!opts.strict) {
initialize();
opts.strict = true;
parsed = addressList(parseString);
parsed = startProduction(parseString);
if (opts.partial || !inStr()) {
return giveResult(parsed);
}
@@ -859,46 +967,51 @@ function parse5322(opts) {
}
initialize();
parsed = addressList(parseString);
parsed = startProduction(parseString);
if (!opts.partial && inStr()) { return null; }
return giveResult(parsed);
}
function parseOneAddressSimple(opts) {
var result;
opts = handleOpts(opts, {
return parse5322(handleOpts(opts, {
oneResult: true,
rfc6532: true,
simple: true
});
if (opts === null) { return null; }
result = parse5322(opts);
if ((!result) ||
(!opts.partial &&
(opts.simple && result.length > 1) ||
(!opts.simple && result.addresses.length > 1))) {
return null;
}
return opts.simple ?
result && result[0] :
result && result.addresses && result.addresses[0];
simple: true,
startAt: 'address-list',
}));
}
function parseAddressListSimple(opts) {
var result;
opts = handleOpts(opts, {
return parse5322(handleOpts(opts, {
rfc6532: true,
simple: true
});
if (opts === null) { return null; }
simple: true,
startAt: 'address-list',
}));
}
result = parse5322(opts);
function parseFromSimple(opts) {
return parse5322(handleOpts(opts, {
rfc6532: true,
simple: true,
startAt: 'from',
}));
}
return opts.simple ? result : result.addresses;
function parseSenderSimple(opts) {
return parse5322(handleOpts(opts, {
oneResult: true,
rfc6532: true,
simple: true,
startAt: 'sender',
}));
}
function parseReplyToSimple(opts) {
return parse5322(handleOpts(opts, {
rfc6532: true,
simple: true,
startAt: 'reply-to',
}));
}
function handleOpts(opts, defs) {
@@ -926,24 +1039,28 @@ function handleOpts(opts, defs) {
if (!defs) { return null; }
defaults = {
rfc6532: false,
oneResult: false,
partial: false,
rejectTLD: false,
rfc6532: false,
simple: false,
startAt: 'address-list',
strict: false,
rejectTLD: false
};
for (o in defaults) {
if (isNullUndef(opts[o])) {
opts[o] = !isNullUndef(defs[o]) ? defs[o] : defaults[o];
}
opts[o] = !!opts[o];
}
return opts;
}
parse5322.parseOneAddress = parseOneAddressSimple;
parse5322.parseAddressList = parseAddressListSimple;
parse5322.parseFrom = parseFromSimple;
parse5322.parseSender = parseSenderSimple;
parse5322.parseReplyTo = parseReplyToSimple;
// in Zammad context, go back to non CommonJS
// if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {

View File

@@ -152,8 +152,10 @@
$(window).on('keydown.dismiss.bs.modal', $.proxy(function (e) {
e.which == 27 && this.hide()
// 2016-08-21: added event to capture esc for cancel
e = $.Event('dismiss.bs.modal')
this.$element.trigger(e)
if (e.which == 27) {
e = $.Event('dismiss.bs.modal')
this.$element.trigger(e)
}
// -
}, this))
} else if (!this.isShown) {

View File

@@ -417,6 +417,15 @@ class Model extends Module
# ID change, need to do some shifting
if atts.id and @id isnt atts.id
@changeID(atts.id)
# temporary debugging of a possible race condition
if !@constructor.irecords[@id]
model = @constructor.className
atts_json = JSON.stringify(atts)
console.log "Can't refresh not exisint %s instance with ID %s and attributes %s. Possible race condition?", model, @id, atts_json
# prevent exception
return
# go to the source and load attributes
@constructor.irecords[@id].load(atts)
@trigger('refresh', this)

View File

@@ -250,7 +250,7 @@ class App.Chat extends App.Model
{ name: 'note', display: 'Note', tag: 'textarea', limit: 250, null: true },
{ name: 'max_queue', display: 'Max. clients in waitlist', tag: 'input', default: 2 },
{ name: 'block_ip', display: 'Blocked IPs (separated by ;)', tag: 'input', default: '', null: true },
{ name: 'block_country', display: 'Blocked contries', tag: 'column_select', multiple: true, null: true, default: '', options: @countries, seperator: ';' },
{ name: 'block_country', display: 'Blocked countries', tag: 'column_select', multiple: true, null: true, default: '', options: @countries, seperator: ';' },
{ name: 'active', display: 'Active', tag: 'active', default: true },
{ name: 'created_by_id', display: 'Created by', relation: 'User', readonly: 1 },
{ name: 'created_at', display: 'Created', tag: 'datetime', readonly: 1 },

View File

@@ -1,5 +1,5 @@
<div class="js-pager"></div>
<table class="table table-hover<%- " #{@class}" if @class %>">
<table class="table table-hover<% if @class: %> <%= @class %><% end %>">
<thead>
<tr>
<% if @sortable: %>
@@ -19,14 +19,10 @@
<th style="width: 40px" class="table-radio"></th>
<% end %>
<% for header, i in @headers: %>
<th class="js-tableHead<%= " #{ header.className }" if header.className %><%= " align-#{ header.align }" if header.align %>" style="<% if header.displayWidth: %>width:<%= header.displayWidth %>px<% end %>" data-column-key="<%= header.name %>">
<th class="js-tableHead<% if header.className: %> <%= header.className %><% end %><% if header.align: %> align-<%= header.align %><% end %>" style="<% if header.displayWidth: %>width:<%= header.displayWidth %>px<% end %>" data-column-key="<%= header.name %>">
<div class="table-column-head<%= ' js-sort' if @tableId %>">
<div class="table-column-title"><%- @T(header.display) %></div>
<div class="table-column-sortIcon">
<% if header.sortOrderIcon: %>
<%- @Icon(header.sortOrderIcon[0], header.sortOrderIcon[1]) %>
<% end %>
</div>
<div class="table-column-sortIcon"><% if header.sortOrderIcon: %><%- @Icon(header.sortOrderIcon[0], header.sortOrderIcon[1]) %><% end %></div>
</div>
<% if @tableId && !header.unresizable && i < @headers.length - 1: %>
<div class="table-col-resize js-col-resize"></div>

View File

@@ -31,7 +31,7 @@
<% end %>
<% end %>
<% end %>
<td<%- " class='#{ header.parentClass }'" if header.parentClass %><%- " title='#{ header.title }'" if header.title %><%- " style='text-align:#{ header.align }'" if header.align %>>
<td<% if header.parentClass: %> class="<%= header.parentClass %>"<% end %><% if header.title: %> title="<%= header.title %>"<% end %><% if header.align: %> style="text-align:<%= header.align %>"<% end %>>
<% if header.name is 'icon': %>
<%- @Icon('task-state', header.class) %>
<% else if header.icon: %>

View File

@@ -295,7 +295,7 @@ check if country is blocked for chat
def blocked_country?(ip)
return false if ip.blank?
retunn false if block_country.blank?
return false if block_country.blank?
geo_ip = Service::GeoIp.location(ip)
return false if geo_ip.blank?
return false if geo_ip['country_code'].blank?

View File

@@ -21,13 +21,7 @@ class Report
selected: true,
dataDownload: true,
adapter: Report::TicketGenericTime,
params: { field: 'created_at' },
condition: {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}
params: { field: 'created_at' }
},
{
name: 'closed',
@@ -35,52 +29,28 @@ class Report
selected: true,
dataDownload: true,
adapter: Report::TicketGenericTime,
params: { field: 'close_at' },
condition: {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}
params: { field: 'close_at' }
},
{
name: 'backlog',
display: 'Backlog',
selected: true,
dataDownload: false,
adapter: Report::TicketBacklog,
condition: {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}
adapter: Report::TicketBacklog
},
{
name: 'first_solution',
display: 'First Solution',
selected: false,
dataDownload: true,
adapter: Report::TicketFirstSolution,
condition: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
adapter: Report::TicketFirstSolution
},
{
name: 'reopened',
display: 'Reopened',
selected: false,
dataDownload: true,
adapter: Report::TicketReopened,
condition: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
adapter: Report::TicketReopened
},
{
name: 'movedin',
@@ -88,13 +58,7 @@ class Report
selected: false,
dataDownload: true,
adapter: Report::TicketMoved,
params: { type: 'in' },
condition: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
params: { type: 'in' }
},
{
name: 'movedout',
@@ -102,13 +66,7 @@ class Report
selected: false,
dataDownload: true,
adapter: Report::TicketMoved,
params: { type: 'out' },
condition: {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
params: { type: 'out' }
},
]
config[:metric][:count][:backend] = backend

View File

@@ -36,6 +36,7 @@ returns
data[ app_model ][ id ] = local_attributes
local_attributes['group_ids'].each_key do |group_id|
next if data[:Group] && data[:Group][group_id]
group = Group.lookup(id: group_id)
next if !group
data = group.assets(data)

View File

@@ -21,13 +21,11 @@ class Ticket
# access ok if its own ticket
return true if customer_id == user.id
# access ok if its organization ticket
if user.organization_id && organization_id
return true if organization_id == user.organization_id
end
# no access
return false
# check organization ticket access
return false if organization_id.blank?
return false if user.organization_id.blank?
return false if organization_id != user.organization_id
return organization.shared?
end
# check agent

View File

@@ -98,11 +98,7 @@ returns
filter[:group_id] = []
groups = if params[:current_user].permissions?('ticket.agent')
if params[:ticket].present?
params[:current_user].groups_access(%w[change])
else
params[:current_user].groups_access(%w[create])
end
params[:current_user].groups_access(%w[create change])
else
Group.where(active: true)
end

View File

@@ -0,0 +1,48 @@
class CustomLdapLoginAttribute < ActiveRecord::Migration[5.1]
def up
# return if it's a new setup
return if !Setting.find_by(name: 'system_init_done')
return if no_change_needed?
perform_changes
end
private
def perform_changes
delete_spared
update_config
end
def delete_spared
# remove samaccountname which is always wrong if there is more than
# one other login attribute since it's automatically added
ldap_config[:user_attributes].delete('samaccountname')
# this should not happen but remove any other duplicate that
# maps to login and keep the "first" in the list
# - which is more or less random
login_attributes.reject { |e| e == 'samaccountname' }.drop(1).each do |spared|
ldap_config[:user_attributes].delete(spared)
end
end
def update_config
Import::Ldap.config = ldap_config
end
def login_attributes
@login_attributes ||= ldap_config[:user_attributes].select { |_local, remote| remote == 'login' }.keys
end
def no_change_needed?
return true if ldap_config.blank?
return true if ldap_config[:user_attributes].blank?
ldap_config[:user_attributes].values.count('login') < 2
end
def ldap_config
@ldap_config ||= Import::Ldap.config
end
end

View File

@@ -374,7 +374,7 @@ cleanup html string:
def self.cleanup_target(string)
string = CGI.unescape(string).encode('utf-8', 'binary', invalid: :replace, undef: :replace, replace: '?')
string.gsub(/[[:space:]]|\t|\n|\r/, '').gsub(%r{/\*.*?\*/}, '').gsub(/<!--.*?-->/, '').gsub(/\[.+?\]/, '')
string.gsub(/[[:space:]]|\t|\n|\r/, '').gsub(%r{/\*.*?\*/}, '').gsub(/<!--.*?-->/, '').gsub(/\[.+?\]/, '').delete("\u0000")
end
def self.url_same?(url_new, url_old)

View File

@@ -3,6 +3,17 @@
module Import
class Base
# Checks if the backend is active.
#
# @example
# Import::ExampleBackend.active?
# #=> true
#
# return [Boolean]
def self.active?
true
end
# Checks if the backend is able to get queued by the Scheduler.
#
# @example

View File

@@ -50,6 +50,14 @@ returns
elsif params[:interval] == 'minute'
stop = start + 1.minute
end
without_merged_tickets = {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
params[:selector].merge!(without_merged_tickets)
query, bind_params, tables = Ticket.selector2sql(params[:selector])
ticket_list = Ticket.select('tickets.id, tickets.close_at, tickets.created_at').where(
'tickets.close_at IS NOT NULL AND tickets.close_at >= ? AND tickets.close_at < ?',
@@ -89,7 +97,15 @@ returns
=end
def self.items(params)
query, bind_params, tables = Ticket.selector2sql(params[:selector])
without_merged_tickets = {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
selector = params[:selector].merge!(without_merged_tickets)
query, bind_params, tables = Ticket.selector2sql(selector)
ticket_list = Ticket.select('tickets.id, tickets.close_at, tickets.created_at').where(
'tickets.close_at IS NOT NULL AND tickets.close_at >= ? AND tickets.close_at < ?',
params[:range_start],

View File

@@ -29,10 +29,18 @@ returns
field: params[:params][:field],
}
without_merged_tickets = {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}
selector = params[:selector].clone
if params[:params].present? && params[:params][:selector].present?
selector = selector.merge(params[:params][:selector])
end
selector.merge!(without_merged_tickets) # do not show merged tickets in reports
result_es = SearchIndexBackend.selectors(['Ticket'], selector, nil, nil, aggs_interval)
@@ -140,10 +148,18 @@ returns
limit = 100
end
without_merged_tickets = {
'state' => {
'operator' => 'is not',
'value' => 'merged'
}
}
selector = params[:selector].clone
if params[:params] && params[:params][:selector]
selector = selector.merge(params[:params][:selector])
end
selector.merge!(without_merged_tickets) # do not show merged tickets in reports
result = SearchIndexBackend.selectors(['Ticket'], selector, limit, nil, aggs_interval)
return result if params[:sheet].present?

View File

@@ -60,6 +60,13 @@ returns
end
local_params = group_attributes(selector, params)
local_selector = params[:selector].clone
without_merged_tickets = {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
local_selector.merge!(without_merged_tickets) # do not show merged tickets in reports
if params[:params][:type] == 'out'
local_selector.delete('ticket.group_id')
end
@@ -110,6 +117,13 @@ returns
end
local_params = group_attributes(selector, params)
local_selector = params[:selector].clone
without_merged_tickets = {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
local_selector = params[:selector].merge!(without_merged_tickets) # do not show merged tickets in reports
if params[:params][:type] == 'out'
local_selector.delete('ticket.group_id')
end

View File

@@ -52,6 +52,14 @@ returns
elsif params[:interval] == 'minute'
stop = start + 1.minute
end
without_merged_tickets = {
'ticket_state.name' => {
'operator' => 'is not',
'value' => 'merged'
}
}
params[:selector].merge!(without_merged_tickets) # do not show merged tickets in reports
count = history_count(
object: 'Ticket',
type: 'updated',

View File

@@ -16,7 +16,7 @@ class Sequencer
'Import::Common::Model::Associations::Extract',
'Import::Common::User::Attributes::Downcase',
'Import::Common::User::Email::CheckValidity',
'Import::Ldap::User::Lookup::Attributes',
'Import::Common::Model::FindBy::UserAttributes',
'Import::Common::Model::Attributes::AddByIds',
'Import::Common::Model::Update',
'Import::Common::Model::Create',

View File

@@ -9,13 +9,7 @@ class Sequencer
private
def mapping
ldap_config[:user_attributes].dup.tap do |config|
# fallback to samaccountname as login
# if no login is given via mapping
if !config.values.include?('login')
config['samaccountname'] = 'login'
end
end
ldap_config[:user_attributes]
end
end
end

View File

@@ -13,18 +13,20 @@ class Sessions::Event::ChatStatusCustomer < Sessions::Event::ChatBase
# update recipients of existing sessions
chat_session = Chat::Session.find_by(session_id: session_id)
chat_session.add_recipient(@client_id, true)
if chat_session
chat_session.add_recipient(@client_id, true)
# sent url update to agent
if @payload['data']['url']
message = {
event: 'chat_session_notice',
data: {
session_id: chat_session.session_id,
message: @payload['data']['url'],
},
}
chat_session.send_to_recipients(message, @client_id)
# sent url update to agent
if @payload['data']['url']
message = {
event: 'chat_session_notice',
data: {
session_id: chat_session.session_id,
message: @payload['data']['url'],
},
}
chat_session.send_to_recipients(message, @client_id)
end
end
end

View File

@@ -1982,34 +1982,106 @@ test('check getRecipientArticle format', function() {
lastname: 'lastname',
email: 'customer@example.com',
}
agent = {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'agent@example.com',
}
ticket = {
customer: customer,
}
article = {
message_id: 'message_id7',
created_by: agent,
type: {
name: 'email',
},
sender: {
name: 'Agent',
name: 'Customer',
},
from: 'customer2@example.com',
to: 'customer@example.com',
from: 'some other invalid part, ' + customer.email,
to: 'some group',
created_by: {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'article_created_by@example.com',
}
}
result = {
to: 'customer2@example.com',
to: 'customer@example.com',
cc: '',
body: '',
in_reply_to: 'message_id7',
}
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
console.log(verify)
deepEqual(verify, result)
customer = {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'customer@example.com',
}
ticket = {
customer: customer,
}
article = {
message_id: 'message_id7.1',
type: {
name: 'email',
},
sender: {
name: 'Customer',
},
from: 'some other invalid part, Some Realname ' + customer.email,
to: 'some group',
created_by: {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'article_created_by@example.com',
}
}
result = {
to: 'customer@example.com',
cc: '',
body: '',
in_reply_to: 'message_id7.1',
}
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
console.log(verify)
deepEqual(verify, result)
customer = {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'customer@example.com',
}
ticket = {
customer: customer,
}
article = {
message_id: 'message_id7.2',
type: {
name: 'email',
},
sender: {
name: 'Customer',
},
from: 'some other invalid part, Some Realname ' + customer.email + ' , abc',
to: 'some group',
created_by: {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'article_created_by@example.com',
}
}
result = {
to: 'customer@example.com',
cc: '',
body: '',
in_reply_to: 'message_id7.2',
}
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
console.log(verify)
deepEqual(verify, result)
customer = {
@@ -2036,11 +2108,11 @@ test('check getRecipientArticle format', function() {
sender: {
name: 'Agent',
},
from: 'agent@example.com',
from: 'customer2@example.com',
to: 'customer@example.com',
}
result = {
to: 'customer@example.com',
to: 'customer2@example.com',
cc: '',
body: '',
in_reply_to: 'message_id8',
@@ -2072,9 +2144,8 @@ test('check getRecipientArticle format', function() {
sender: {
name: 'Agent',
},
from: 'Agent@Example.com',
from: 'agent@example.com',
to: 'customer@example.com',
cc: 'zammad@example.com',
}
result = {
to: 'customer@example.com',
@@ -2110,16 +2181,16 @@ test('check getRecipientArticle format', function() {
name: 'Agent',
},
from: 'Agent@Example.com',
to: 'customer@example.com, agent@example.com',
to: 'customer@example.com',
cc: 'zammad@example.com',
}
result = {
to: 'customer@example.com, agent@example.com',
cc: 'zammad@example.com',
to: 'customer@example.com',
cc: '',
body: '',
in_reply_to: 'message_id10',
}
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type, [], true)
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type)
deepEqual(verify, result)
customer = {
@@ -2147,8 +2218,8 @@ test('check getRecipientArticle format', function() {
name: 'Agent',
},
from: 'Agent@Example.com',
to: 'customeR@EXAMPLE.com, agent@example.com',
cc: 'zammad@example.com, customer@example.com',
to: 'customer@example.com, agent@example.com',
cc: 'zammad@example.com',
}
result = {
to: 'customer@example.com, agent@example.com',
@@ -2156,7 +2227,7 @@ test('check getRecipientArticle format', function() {
body: '',
in_reply_to: 'message_id11',
}
verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, [], true)
verify = App.Utils.getRecipientArticle(ticket, article, article.created_by, article.type, [], true)
deepEqual(verify, result)
customer = {
@@ -2184,24 +2255,16 @@ test('check getRecipientArticle format', function() {
name: 'Agent',
},
from: 'Agent@Example.com',
to: 'customeR@EXAMPLE.com, agent@example.com, zammad2@EXAMPLE.com',
cc: 'zammad@example.com, customer2@example.com',
to: 'customeR@EXAMPLE.com, agent@example.com',
cc: 'zammad@example.com, customer@example.com',
}
result = {
to: 'customer@example.com, agent@example.com',
cc: 'customer2@example.com',
cc: 'zammad@example.com',
body: '',
in_reply_to: 'message_id12',
}
email_addresses = [
{
email: 'zammad@example.com',
},
{
email: 'zammad2@example.com',
}
]
verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, [], true)
deepEqual(verify, result)
customer = {
@@ -2214,7 +2277,7 @@ test('check getRecipientArticle format', function() {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'AGENT@example.com',
email: 'agent@example.com',
}
ticket = {
customer: customer,
@@ -2253,21 +2316,27 @@ test('check getRecipientArticle format', function() {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'zammad@example.com',
email: 'customer@example.com',
}
agent = {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'AGENT@example.com',
}
ticket = {
customer: customer,
}
article = {
message_id: 'message_id14',
created_by: customer,
created_by: agent,
type: {
name: 'email',
},
sender: {
name: 'Agent',
},
from: 'zammad@EXAMPLE.com',
from: 'Agent@Example.com',
to: 'customeR@EXAMPLE.com, agent@example.com, zammad2@EXAMPLE.com',
cc: 'zammad@example.com, customer2@example.com',
}
@@ -2292,7 +2361,7 @@ test('check getRecipientArticle format', function() {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'customer@example.com',
email: 'zammad@example.com',
}
ticket = {
customer: customer,
@@ -2306,13 +2375,13 @@ test('check getRecipientArticle format', function() {
sender: {
name: 'Agent',
},
from: 'customer@example.com',
to: 'customer1@example.com, customer2@example.com, zammad@example.com',
cc: '',
from: 'zammad@EXAMPLE.com',
to: 'customeR@EXAMPLE.com, agent@example.com, zammad2@EXAMPLE.com',
cc: 'zammad@example.com, customer2@example.com',
}
result = {
to: 'customer1@example.com, customer2@example.com, customer@example.com',
cc: '',
to: 'customer@example.com, agent@example.com',
cc: 'customer2@example.com',
body: '',
in_reply_to: 'message_id15',
}
@@ -2346,11 +2415,11 @@ test('check getRecipientArticle format', function() {
name: 'Agent',
},
from: 'customer@example.com',
to: 'customer1@example.com, customer2@example.com, zammad@example.com, customer2+2@example.com',
to: 'customer1@example.com, customer2@example.com, zammad@example.com',
cc: '',
}
result = {
to: 'customer1@example.com, customer2@example.com, customer2+2@example.com, customer@example.com',
to: 'customer1@example.com, customer2@example.com, customer@example.com',
cc: '',
body: '',
in_reply_to: 'message_id16',
@@ -2372,30 +2441,24 @@ test('check getRecipientArticle format', function() {
lastname: 'lastname',
email: 'customer@example.com',
}
agent = {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'zammad@example.com',
}
ticket = {
customer: customer,
}
article = {
message_id: 'message_id17',
created_by: agent,
created_by: customer,
type: {
name: 'email',
},
sender: {
name: 'Agent',
},
from: 'zammad@example.com',
to: 'customer@example.com',
from: 'customer@example.com',
to: 'customer1@example.com, customer2@example.com, zammad@example.com, customer2+2@example.com',
cc: '',
}
result = {
to: 'customer@example.com',
to: 'customer1@example.com, customer2@example.com, customer2+2@example.com, customer@example.com',
cc: '',
body: '',
in_reply_to: 'message_id17',
@@ -2435,6 +2498,51 @@ test('check getRecipientArticle format', function() {
sender: {
name: 'Agent',
},
from: 'zammad@example.com',
to: 'customer@example.com',
cc: '',
}
result = {
to: 'customer@example.com',
cc: '',
body: '',
in_reply_to: 'message_id18',
}
email_addresses = [
{
email: 'zammad@example.com',
},
{
email: 'zammad2@example.com',
}
]
verify = App.Utils.getRecipientArticle(ticket, article, agent, article.type, email_addresses, true)
deepEqual(verify, result)
customer = {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'customer@example.com',
}
agent = {
login: 'login',
firstname: 'firstname',
lastname: 'lastname',
email: 'zammad@example.com',
}
ticket = {
customer: customer,
}
article = {
message_id: 'message_id19',
created_by: agent,
type: {
name: 'email',
},
sender: {
name: 'Agent',
},
from: 'Sender <zammad@example.com>',
to: 'Customer <customer@example.com>',
cc: '',
@@ -2443,7 +2551,7 @@ test('check getRecipientArticle format', function() {
to: 'customer@example.com',
cc: '',
body: '',
in_reply_to: 'message_id18',
in_reply_to: 'message_id19',
}
email_addresses = [
{
@@ -2466,7 +2574,7 @@ test('check getRecipientArticle format', function() {
customer: agent,
}
article = {
message_id: 'message_id19',
message_id: 'message_id20',
created_by: agent,
type: {
name: 'email',
@@ -2482,7 +2590,7 @@ test('check getRecipientArticle format', function() {
to: 'agent@example.com',
cc: '',
body: '',
in_reply_to: 'message_id19',
in_reply_to: 'message_id20',
}
email_addresses = [
{

View File

@@ -4,6 +4,13 @@ require 'lib/import/import_job_backend_examples'
RSpec.describe Import::Base do
it_behaves_like 'ImportJob backend'
describe '#active?' do
it 'returns true by default' do
expect(described_class.active?).to be true
end
end
describe '#queueable?' do
it 'returns true by default' do

View File

@@ -64,5 +64,92 @@ class CustomerTicketCreateTest < TestCase
css: '.content.active div.ticket-article',
value: 'some body 1234 äöüß',
)
# now we want to verify the default followup state
# for this case we close the ticket first and then
# write a new article. If the content is written
# then the state should change initially to open
# close the ticket
select(
css: '.content.active [name="state_id"]',
value: 'closed',
)
set(
css: '.content.active [data-name="body"]',
value: 'close #1',
no_click: true,
)
click(css: '.content.active .js-submit')
watch_for(
css: '.content.active div.ticket-article',
value: 'close #1',
)
# check if the ticket is closed
match(
css: '.content.active .sidebar [name="state_id"]',
value: 'closed',
)
# type in new content into rte to trigger the default follow up state
set(
css: '.content.active [data-name="body"]',
value: 'some body blublub default followup for reopen check',
no_click: true,
)
# verify if the state has changed to open
watch_for(
css: '.content.active .sidebar [name="state_id"]',
value: 'open',
)
# no we verify the reverse way:
# if the body get changed to empty again then
# the default follow up state should get unset and
# will change to the the default ticket state.
# remove content from rte
set(
css: '.content.active [data-name="body"]',
value: '',
no_click: true,
)
# check if state changed to closed again
watch_for(
css: '.content.active .sidebar [name="state_id"]',
value: 'closed',
)
# type in new content into rte to trigger the default follow up state
set(
css: '.content.active [data-name="body"]',
value: 'some body blublub default followup for reopen check',
no_click: true,
)
# verify if the state has changed to open
watch_for(
css: '.content.active .sidebar [name="state_id"]',
value: 'open',
)
# submit and reload to check if the new state is set
click(css: '.content.active .js-submit')
watch_for(
css: '.content.active div.ticket-article',
value: 'some body blublub default followup for reopen check',
)
# verify if the state has changed to open
match(
css: '.content.active .sidebar [name="state_id"]',
value: 'open',
)
end
end

1047
test/fixtures/mail66.box vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -304,7 +304,7 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(2, result[9])
assert_equal(2, result[10])
assert_equal(1, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
@@ -317,8 +317,7 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(@ticket5.id, result[:ticket_ids][0])
assert_equal(@ticket6.id, result[:ticket_ids][1])
assert_equal(@ticket7.id, result[:ticket_ids][2])
assert_equal(@ticket8.id, result[:ticket_ids][3])
assert_nil(result[:ticket_ids][4])
assert_nil(result[:ticket_ids][3])
# month - with selector #1
result = Report::TicketFirstSolution.aggs(
@@ -425,7 +424,7 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(1, result[9])
assert_equal(2, result[10])
assert_equal(1, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
@@ -442,8 +441,7 @@ class ReportTest < ActiveSupport::TestCase
assert(result)
assert_equal(@ticket6.id, result[:ticket_ids][0])
assert_equal(@ticket7.id, result[:ticket_ids][1])
assert_equal(@ticket8.id, result[:ticket_ids][2])
assert_nil(result[:ticket_ids][3])
assert_nil(result[:ticket_ids][2])
# week
result = Report::TicketFirstSolution.aggs(
@@ -929,7 +927,7 @@ class ReportTest < ActiveSupport::TestCase
assert_equal(0, result[7])
assert_equal(0, result[8])
assert_equal(6, result[9])
assert_equal(2, result[10])
assert_equal(1, result[10])
assert_equal(0, result[11])
assert_nil(result[12])
@@ -940,15 +938,14 @@ class ReportTest < ActiveSupport::TestCase
params: { field: 'created_at' },
)
assert(result)
assert_equal(@ticket8.id, result[:ticket_ids][0].to_i)
assert_equal(@ticket7.id, result[:ticket_ids][1].to_i)
assert_equal(@ticket6.id, result[:ticket_ids][2].to_i)
assert_equal(@ticket5.id, result[:ticket_ids][3].to_i)
assert_equal(@ticket4.id, result[:ticket_ids][4].to_i)
assert_equal(@ticket3.id, result[:ticket_ids][5].to_i)
assert_equal(@ticket2.id, result[:ticket_ids][6].to_i)
assert_equal(@ticket1.id, result[:ticket_ids][7].to_i)
assert_nil(result[:ticket_ids][8])
assert_equal(@ticket7.id, result[:ticket_ids][0].to_i)
assert_equal(@ticket6.id, result[:ticket_ids][1].to_i)
assert_equal(@ticket5.id, result[:ticket_ids][2].to_i)
assert_equal(@ticket4.id, result[:ticket_ids][3].to_i)
assert_equal(@ticket3.id, result[:ticket_ids][4].to_i)
assert_equal(@ticket2.id, result[:ticket_ids][5].to_i)
assert_equal(@ticket1.id, result[:ticket_ids][6].to_i)
assert_nil(result[:ticket_ids][7])
# create at - selector with merge
result = Report::TicketGenericTime.aggs(

View File

@@ -1285,6 +1285,35 @@ delete your own text from the attached returned message.
",
},
},
{
data: IO.binread('test/fixtures/mail66.box'),
body_md5: '346effdbc86ef1f5ea263102fba2e542',
attachments: [
{
md5: '9e56d72f98bbc339c180329e61e21bdf',
filename: 'message.html',
},
{
md5: 'ddbdf67aa2f5c60c294008a54d57082b',
filename: 'FF_Geburtstagsmail.jpg',
},
{
md5: 'a618d671348735744d4c9a4005b56799',
filename: 'team.jpg',
},
],
params: {
from: 'ABC GmbH <info@example.com>',
from_email: 'info@example.com',
from_display_name: 'ABC GmbH',
subject: 'ABC gratuliert!',
content_type: 'text/html',
body: 'Glückwunschkarte <p>Wenn diese Mail nicht richtig dargestellt wird, dann klicken Sie bitte <a href="http://www.example.com/wlabel/geburtstag/?id=0umjv6klh0skcp4j57kl3ro8jymo4c134rcbh31ezc3bk1wv&amp;xz=d???NvnDNoP???!??a?qH@&gt;+?DI?&amp;nv=1337" rel="nofollow noreferrer noopener" target="_blank" title="http://www.example.com/wlabel/geburtstag/?id=0umjv6klh0skcp4j57kl3ro8jymo4c134rcbh31ezc3bk1wv&amp;xz=d???NvnDNoP???!??a?qH@&gt;+?DI?&amp;nv=1337"><u>hier</u></a>.</p><table border="0" cellpadding="0" cellspacing="0" align="center" style="border:2px solid #ebebeb;"> <tr style="background-color:#ffffff;"> <td> <img src="FF_Geburtstagsmail.jpg" alt="Herzlichen Glückwunsch !"> </td> </tr> <tr> <td style="background-color:#ffffff; padding:30px 30px 0 30px;"> <h1>Sehr geehrte Damen und Herren,</h1> <p>zu Ihrem Geburtstag schicken wir Ihnen ein großes Paket mit guten Wünschen:<br> Viel Erfolg, Energie und ein gutes Gespür für die richtigen Entscheidungen!</p><p>Ihr Ehrentag ist ein guter Anlass zurückzublicken und sich an Erreichtem zu erfreuen. Doch er ist auch Anlass, den Blick nach vorne zu richten. Sich kurz zu orientieren und neue Ziele zu stecken. Unsere besten Wünsche begleiten Sie auf Ihrem zukünftigen Weg und wir freuen uns darauf, Ihnen auch dabei zur Seite zu stehen!</p><p>Heute wünschen wir Ihnen einen schönen Tag im Kreise Ihrer Freunde und Familie.</p><p>Herzliche Grüße</p><p>Ihre ABC</p></td> </tr> <tr> <td style="background-color:#ffffff; padding-left: 30px; font-size: 0.75em;"> <br>
<br> ABC GmbH<br> Einestraße 23<br> 99999 München<br>
<br> Telefon.: +49 (0)11 11 11 11-1<br> Fax: +49 (0)11 11 11 11-1<br> <br> <a href="https://www.example.com/" rel="nofollow noreferrer noopener" target="_blank">www.example.com</a><br> <p>&nbsp;</p>Geschäftszeiten: Mo-Do 08:00-18:00 Uhr Fr 08:00-17:00 Uhr<br> Sitz der Gesellschaft: München<br> Registergericht: Amtsgericht München, HRB AAAA<br> Geschäftsführer: AAAA, BBBB<br><br></td> </tr>
</table>',
},
},
]
count = 0

View File

@@ -140,10 +140,10 @@ class TicketScreenOptionsTest < ActiveSupport::TestCase
assert(result[:form_meta][:filter][:type_id])
assert_equal([], result[:form_meta][:filter][:type_id].sort)
assert(result[:form_meta][:filter][:group_id])
assert_equal([group1.id, group3.id], result[:form_meta][:filter][:group_id].sort)
assert_equal([group1.id, group2.id, group3.id], result[:form_meta][:filter][:group_id].sort)
assert(result[:form_meta][:dependencies])
assert(result[:form_meta][:dependencies][:group_id])
assert_equal(3, result[:form_meta][:dependencies][:group_id].count)
assert_equal(4, result[:form_meta][:dependencies][:group_id].count)
assert(result[:form_meta][:dependencies][:group_id][''])
assert(result[:form_meta][:dependencies][:group_id][''][:owner_id])
assert_equal([], result[:form_meta][:dependencies][:group_id][''][:owner_id])
@@ -182,10 +182,10 @@ class TicketScreenOptionsTest < ActiveSupport::TestCase
assert(result[:form_meta][:filter][:type_id])
assert_equal([], result[:form_meta][:filter][:type_id].sort)
assert(result[:form_meta][:filter][:group_id])
assert_equal([group1.id, group3.id], result[:form_meta][:filter][:group_id].sort)
assert_equal([group1.id, group2.id, group3.id], result[:form_meta][:filter][:group_id].sort)
assert(result[:form_meta][:dependencies])
assert(result[:form_meta][:dependencies][:group_id])
assert_equal(3, result[:form_meta][:dependencies][:group_id].count)
assert_equal(4, result[:form_meta][:dependencies][:group_id].count)
assert(result[:form_meta][:dependencies][:group_id][''])
assert(result[:form_meta][:dependencies][:group_id][''][:owner_id])
assert_equal([], result[:form_meta][:dependencies][:group_id][''][:owner_id])
@@ -467,10 +467,10 @@ class TicketScreenOptionsTest < ActiveSupport::TestCase
Ticket::Article::Type.lookup(name: 'note').id,
], result[:form_meta][:filter][:type_id].sort)
assert(result[:form_meta][:filter][:group_id])
assert_equal([group1.id, group2.id], result[:form_meta][:filter][:group_id].sort)
assert_equal([group1.id, group2.id, group3.id], result[:form_meta][:filter][:group_id].sort)
assert(result[:form_meta][:dependencies])
assert(result[:form_meta][:dependencies][:group_id])
assert_equal(3, result[:form_meta][:dependencies][:group_id].count)
assert_equal(4, result[:form_meta][:dependencies][:group_id].count)
assert(result[:form_meta][:dependencies][:group_id][''])
assert(result[:form_meta][:dependencies][:group_id][''][:owner_id])
assert_equal([], result[:form_meta][:dependencies][:group_id][''][:owner_id])
@@ -513,10 +513,10 @@ class TicketScreenOptionsTest < ActiveSupport::TestCase
Ticket::Article::Type.lookup(name: 'note').id,
], result[:form_meta][:filter][:type_id].sort)
assert(result[:form_meta][:filter][:group_id])
assert_equal([group1.id, group2.id], result[:form_meta][:filter][:group_id].sort)
assert_equal([group1.id, group2.id, group3.id], result[:form_meta][:filter][:group_id].sort)
assert(result[:form_meta][:dependencies])
assert(result[:form_meta][:dependencies][:group_id])
assert_equal(3, result[:form_meta][:dependencies][:group_id].count)
assert_equal(4, result[:form_meta][:dependencies][:group_id].count)
assert(result[:form_meta][:dependencies][:group_id][''])
assert(result[:form_meta][:dependencies][:group_id][''][:owner_id])
assert_equal([], result[:form_meta][:dependencies][:group_id][''][:owner_id])