Compare commits
386 Commits
bnet/addit
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
279ae66120 | 6 years ago |
|
|
13a066b24f | 6 years ago |
|
|
40250563e3 | 6 years ago |
|
|
b22f1c9a1b | 6 years ago |
|
|
ec2e713ecb | 6 years ago |
|
|
4ada2c3f13 | 6 years ago |
|
|
98881a0cbd | 6 years ago |
|
|
1c76c8440f | 6 years ago |
|
|
731be15d46 | 6 years ago |
|
|
9ee1f4b636 | 6 years ago |
|
|
51eb8a6a68 | 6 years ago |
|
|
9508acf249 | 6 years ago |
|
|
30610e867e | 6 years ago |
|
|
9dbe666d4c | 6 years ago |
|
|
86d34960c8 | 6 years ago |
|
|
61185b9362 | 6 years ago |
|
|
13b03c3953 | 6 years ago |
|
|
b4dabff26c | 6 years ago |
|
|
278cf3c18e | 6 years ago |
|
|
e9c592a6e8 | 6 years ago |
|
|
bb06645b8f | 6 years ago |
|
|
9b8ed0dfeb | 6 years ago |
|
|
218cd2ab4a | 6 years ago |
|
|
4e00237cc4 | 6 years ago |
|
|
eaebae1e54 | 6 years ago |
|
|
77174ff9ff | 6 years ago |
|
|
25772702ac | 6 years ago |
|
|
af0e98759d | 6 years ago |
|
|
cd76046237 | 6 years ago |
|
|
46d3cae2ff | 6 years ago |
|
|
bda02002de | 6 years ago |
|
|
ecabb1e667 | 6 years ago |
|
|
31249d932d | 6 years ago |
|
|
e05c69afab | 6 years ago |
|
|
6436c22d2d | 6 years ago |
|
|
da2bb8af6d | 6 years ago |
|
|
f6586c7cf7 | 6 years ago |
|
|
82ee69df15 | 6 years ago |
|
|
34a0af8964 | 6 years ago |
|
|
30d31c323b | 6 years ago |
|
|
a47c558df4 | 6 years ago |
|
|
14a8a99ee2 | 6 years ago |
|
|
40ecd47f90 | 6 years ago |
|
|
06a1964ef6 | 6 years ago |
|
|
24d0cf5d34 | 6 years ago |
|
|
c3d4598985 | 6 years ago |
|
|
7dcba95605 | 6 years ago |
|
|
9bec8dd506 | 6 years ago |
|
|
663f7a8c58 | 6 years ago |
|
|
3af6303ad7 | 6 years ago |
|
|
35c29be9b2 | 6 years ago |
|
|
87f42677c2 | 6 years ago |
|
|
7ead0bb227 | 6 years ago |
|
|
014659b600 | 6 years ago |
|
|
f0f6234a1a | 6 years ago |
|
|
87ca7a09dc | 6 years ago |
|
|
377239fa8e | 6 years ago |
|
|
a2ee9f7eab | 6 years ago |
|
|
1aebb1985c | 6 years ago |
|
|
09848515fe | 6 years ago |
|
|
0efa899d6c | 6 years ago |
|
|
55343ffd7d | 6 years ago |
|
|
ec86e3cb7f | 6 years ago |
|
|
8fac36e2c2 | 6 years ago |
|
|
3d2bb47f8d | 6 years ago |
|
|
c39081b6a1 | 6 years ago |
|
|
12d4705935 | 6 years ago |
|
|
0b09b24a55 | 6 years ago |
|
|
8344f07d7f | 6 years ago |
|
|
219e353ac1 | 6 years ago |
|
|
4951d6603a | 6 years ago |
|
|
87e4cd0cf2 | 6 years ago |
|
|
8db9b8b6e2 | 6 years ago |
|
|
682cea5cc5 | 6 years ago |
|
|
aae1189dbf | 6 years ago |
|
|
6f8663f7ef | 6 years ago |
|
|
6b5fc8db95 | 6 years ago |
|
|
b35b5a1a26 | 6 years ago |
|
|
bf34e8cf9c | 6 years ago |
|
|
36532345df | 6 years ago |
|
|
30b5803ee4 | 6 years ago |
|
|
cb9b22dcc1 | 6 years ago |
|
|
3e9aefceef | 6 years ago |
|
|
15ee34a438 | 6 years ago |
|
|
4a5efe09f9 | 6 years ago |
|
|
43456db922 | 6 years ago |
|
|
32fac136db | 6 years ago |
|
|
9ddb57f5bb | 6 years ago |
|
|
679cb1833c | 6 years ago |
|
|
ae687d7a7a | 6 years ago |
|
|
cb8c07843b | 6 years ago |
|
|
ace991946f | 6 years ago |
|
|
e0b56aeb4d | 6 years ago |
|
|
7d97c5b215 | 6 years ago |
|
|
77e2ee9c9e | 6 years ago |
|
|
c2b12d2b2b | 6 years ago |
|
|
e84dc4c385 | 6 years ago |
|
|
b771cccbaa | 6 years ago |
|
|
e66ffae856 | 6 years ago |
|
|
3d4a02a3a6 | 6 years ago |
|
|
2965e60c1f | 6 years ago |
|
|
f9c84e2646 | 6 years ago |
|
|
7df358d64e | 6 years ago |
|
|
f0ec65ee70 | 6 years ago |
|
|
81839093bb | 6 years ago |
|
|
005da225f6 | 6 years ago |
|
|
c26ba1ee5d | 6 years ago |
|
|
81dcf4a7de | 6 years ago |
|
|
84505edac5 | 6 years ago |
|
|
11aa9633b1 | 6 years ago |
|
|
623a642457 | 6 years ago |
|
|
68350bd385 | 6 years ago |
|
|
3c8b270d8d | 6 years ago |
|
|
be7770b5a9 | 6 years ago |
|
|
a70baca3ae | 6 years ago |
|
|
97732d5de7 | 6 years ago |
|
|
dc1ce546b9 | 6 years ago |
|
|
2c1a22d283 | 6 years ago |
|
|
0fbd184294 | 6 years ago |
|
|
b3b5b9665d | 6 years ago |
|
|
a748214595 | 6 years ago |
|
|
e5247e855e | 6 years ago |
|
|
d194b238c7 | 6 years ago |
|
|
370789c8c9 | 6 years ago |
|
|
88577119d7 | 6 years ago |
|
|
088714619e | 6 years ago |
|
|
f452d33d44 | 6 years ago |
|
|
b2391417b3 | 6 years ago |
|
|
68c8ee0a2b | 6 years ago |
|
|
b7410ffe89 | 6 years ago |
|
|
80a244756d | 6 years ago |
|
|
38d6659384 | 6 years ago |
|
|
e58c6547ca | 6 years ago |
|
|
770d818dd9 | 6 years ago |
|
|
4b219792a7 | 6 years ago |
|
|
f94b871aa6 | 6 years ago |
|
|
db5ab6d3f6 | 6 years ago |
|
|
65a6a511a6 | 6 years ago |
|
|
f2328bbe6b | 6 years ago |
|
|
b80171f37b | 6 years ago |
|
|
4e2e876101 | 6 years ago |
|
|
305c9355ee | 6 years ago |
|
|
32b37fba33 | 6 years ago |
|
|
ea2d0ad458 | 6 years ago |
|
|
b606d81cdf | 6 years ago |
|
|
706912e534 | 6 years ago |
|
|
50d6ea30e0 | 6 years ago |
|
|
60c8dd2e23 | 6 years ago |
|
|
0b02e87afe | 6 years ago |
|
|
fe796d4040 | 6 years ago |
|
|
3478b002f8 | 6 years ago |
|
|
4114dc932d | 6 years ago |
|
|
a075616fb2 | 6 years ago |
|
|
d594ce2483 | 6 years ago |
|
|
d340f18295 | 6 years ago |
|
|
8080eb2c71 | 6 years ago |
|
|
84aa5d93f1 | 6 years ago |
|
|
c6392f2168 | 6 years ago |
|
|
6c1e8e1efe | 6 years ago |
|
|
cbcebad9c1 | 6 years ago |
|
|
b6db3e4ad7 | 6 years ago |
|
|
bdf0a6539e | 6 years ago |
|
|
8793baa006 | 6 years ago |
|
|
97e6065897 | 6 years ago |
|
|
1613f3ab4c | 6 years ago |
|
|
e4281ae6d4 | 6 years ago |
|
|
d1b61410fc | 6 years ago |
|
|
d979aa0584 | 6 years ago |
|
|
1376b5a647 | 6 years ago |
|
|
b536e18d97 | 6 years ago |
|
|
2f20f43cbb | 6 years ago |
|
|
93519df826 | 6 years ago |
|
|
689c761026 | 6 years ago |
|
|
e89376709c | 6 years ago |
|
|
6e63db6487 | 6 years ago |
|
|
c2c85b0a76 | 6 years ago |
|
|
2037f2612b | 6 years ago |
|
|
b6e75ebea7 | 6 years ago |
|
|
c138567ab5 | 6 years ago |
|
|
4258acf57f | 6 years ago |
|
|
3faa976fc8 | 6 years ago |
|
|
5005c6c3e3 | 6 years ago |
|
|
5a6606a245 | 6 years ago |
|
|
4f47ac0405 | 6 years ago |
|
|
700031b3b7 | 6 years ago |
|
|
62fb938260 | 6 years ago |
|
|
38116c1ae5 | 6 years ago |
|
|
5c73848499 | 6 years ago |
|
|
c2e348067e | 6 years ago |
|
|
47089e9265 | 6 years ago |
|
|
f93857fbab | 6 years ago |
|
|
10ec313034 | 6 years ago |
|
|
9311c49cf4 | 6 years ago |
|
|
470e91e615 | 6 years ago |
|
|
c4f114fa84 | 6 years ago |
|
|
7d2b4f8d15 | 6 years ago |
|
|
d8ebf290b2 | 6 years ago |
|
|
b26340c271 | 6 years ago |
|
|
646e0b99ea | 6 years ago |
|
|
e3556986a1 | 6 years ago |
|
|
355ff138fd | 6 years ago |
|
|
5d025609d3 | 6 years ago |
|
|
a646b13715 | 6 years ago |
|
|
31b0275573 | 6 years ago |
|
|
a9abe62d58 | 6 years ago |
|
|
fded360d84 | 6 years ago |
|
|
3cab0ad493 | 6 years ago |
|
|
0eb4674216 | 6 years ago |
|
|
1b376517e8 | 6 years ago |
|
|
51a9dd631f | 6 years ago |
|
|
5236f40823 | 6 years ago |
|
|
e8e8c31eb3 | 6 years ago |
|
|
245e1aa9f9 | 6 years ago |
|
|
d51352b9cb | 6 years ago |
|
|
530b53d92f | 6 years ago |
|
|
11e5c1af4f | 6 years ago |
|
|
5a1a33752e | 6 years ago |
|
|
094da1e653 | 6 years ago |
|
|
e2bd4548ed | 6 years ago |
|
|
2c0dd762ed | 6 years ago |
|
|
cf8277ea3e | 6 years ago |
|
|
f72054e761 | 6 years ago |
|
|
1edd7a4b3f | 6 years ago |
|
|
57162ef481 | 6 years ago |
|
|
421dbf5271 | 6 years ago |
|
|
564287d6c8 | 6 years ago |
|
|
accb5f63e2 | 6 years ago |
|
|
9a0e71ddee | 6 years ago |
|
|
934382c91f | 6 years ago |
|
|
a32e2b4c6f | 6 years ago |
|
|
59e1efb595 | 6 years ago |
|
|
7abd4f2c15 | 6 years ago |
|
|
5defccb919 | 6 years ago |
|
|
7911c75b1e | 6 years ago |
|
|
ef0d23241a | 6 years ago |
|
|
f32b9ae51d | 6 years ago |
|
|
581bc6886b | 6 years ago |
|
|
724f5c740c | 6 years ago |
|
|
31b33c0f39 | 6 years ago |
|
|
15885055ca | 6 years ago |
|
|
9d1e4b4828 | 6 years ago |
|
|
87304c29d1 | 6 years ago |
|
|
53a111f8c3 | 6 years ago |
|
|
1f656e5a07 | 6 years ago |
|
|
895b6f54f3 | 6 years ago |
|
|
a88798ab18 | 6 years ago |
|
|
7ebc159780 | 6 years ago |
|
|
0ea8e9c289 | 6 years ago |
|
|
dd7b51bcd3 | 6 years ago |
|
|
d67b288cbc | 6 years ago |
|
|
eac409ac4a | 6 years ago |
|
|
0b9ff6426e | 6 years ago |
|
|
47d9ed6d0c | 6 years ago |
|
|
ad84b2df3f | 6 years ago |
|
|
f610707554 | 6 years ago |
|
|
df2acc5eb8 | 6 years ago |
|
|
9bb95471bf | 6 years ago |
|
|
226097fc3f | 6 years ago |
|
|
52caed0d66 | 6 years ago |
|
|
37cfa0a43b | 6 years ago |
|
|
5f30dc68a3 | 6 years ago |
|
|
eadbe91c92 | 6 years ago |
|
|
29defb82e9 | 6 years ago |
|
|
cf90c69ad7 | 6 years ago |
|
|
545ea62dfc | 6 years ago |
|
|
34e2507aac | 6 years ago |
|
|
93c0e02f07 | 6 years ago |
|
|
d8d29241a6 | 6 years ago |
|
|
0aa5eca1fd | 6 years ago |
|
|
db4bf5573e | 6 years ago |
|
|
a5b15da155 | 6 years ago |
|
|
0b45c3c6b0 | 6 years ago |
|
|
df7b76b023 | 6 years ago |
|
|
a51beef56c | 6 years ago |
|
|
f3381f12d3 | 6 years ago |
|
|
3fda927858 | 6 years ago |
|
|
259b7fa065 | 6 years ago |
|
|
a335102e47 | 6 years ago |
|
|
d9667295d8 | 6 years ago |
|
|
869d1d1eaf | 6 years ago |
|
|
8471930652 | 6 years ago |
|
|
5b253fb498 | 6 years ago |
|
|
90781bff3b | 6 years ago |
|
|
58aea024b4 | 6 years ago |
|
|
94c795b539 | 6 years ago |
|
|
e7cb9bf604 | 6 years ago |
|
|
e3c6989494 | 6 years ago |
|
|
3b3dd0cf7a | 6 years ago |
|
|
35101ca44a | 6 years ago |
|
|
57476c09f9 | 6 years ago |
|
|
604e814898 | 6 years ago |
|
|
9219f4cd65 | 6 years ago |
|
|
1c1a73e4d5 | 6 years ago |
|
|
511e99ee1a | 6 years ago |
|
|
2321bce469 | 6 years ago |
|
|
04aff2efa3 | 6 years ago |
|
|
2f928a516d | 6 years ago |
|
|
fa34e5ebcd | 6 years ago |
|
|
006f7d1087 | 6 years ago |
|
|
ffeebff3f9 | 6 years ago |
|
|
45546508d2 | 6 years ago |
|
|
8d81df7dc3 | 6 years ago |
|
|
dbc2b5e11c | 6 years ago |
|
|
4485940d0e | 6 years ago |
|
|
4cf2363f43 | 6 years ago |
|
|
b68c141e1d | 6 years ago |
|
|
e0574d909e | 6 years ago |
|
|
8a25ddbf53 | 6 years ago |
|
|
feb4ecdf51 | 6 years ago |
|
|
022a1b683f | 6 years ago |
|
|
d4a8642d5a | 6 years ago |
|
|
d2738d1e8b | 6 years ago |
|
|
ba83042b1a | 6 years ago |
|
|
ea3ad31ce0 | 6 years ago |
|
|
47f72303ac | 6 years ago |
|
|
4b607e2ed3 | 6 years ago |
|
|
fecff809fe | 6 years ago |
|
|
0113ea9602 | 6 years ago |
|
|
2e2028ae78 | 6 years ago |
|
|
b6810cc163 | 6 years ago |
|
|
f4722cb451 | 6 years ago |
|
|
d0dd042b73 | 6 years ago |
|
|
b63bc1ae22 | 6 years ago |
|
|
81bccd00ad | 6 years ago |
|
|
22d629a0e9 | 6 years ago |
|
|
110eebdd1b | 6 years ago |
|
|
ee1f01a0df | 6 years ago |
|
|
157edd72bb | 6 years ago |
|
|
b4b400c91d | 6 years ago |
|
|
1eb50c7cd3 | 6 years ago |
|
|
71bcf2e245 | 6 years ago |
|
|
b63d549834 | 6 years ago |
|
|
4b24ba1372 | 6 years ago |
|
|
4cf8952afa | 6 years ago |
|
|
338b25dec9 | 6 years ago |
|
|
03cee8f554 | 6 years ago |
|
|
8aaf7d35c1 | 6 years ago |
|
|
30af42be87 | 6 years ago |
|
|
757d5fc1b1 | 6 years ago |
|
|
9ebba7c2ce | 6 years ago |
|
|
6aab238773 | 6 years ago |
|
|
c5c5a9325c | 6 years ago |
|
|
508e83470c | 6 years ago |
|
|
f768ff1464 | 6 years ago |
|
|
75125cbac1 | 6 years ago |
|
|
97001e9221 | 6 years ago |
|
|
727f8f04d8 | 6 years ago |
|
|
52c755207d | 6 years ago |
|
|
3a097e6836 | 6 years ago |
|
|
df414aa30c | 6 years ago |
|
|
5543240e67 | 6 years ago |
|
|
5a0843de4b | 6 years ago |
|
|
5b6a50a4e4 | 6 years ago |
|
|
6f4c2cf231 | 6 years ago |
|
|
bdce0ba3f2 | 6 years ago |
|
|
3cd3d8eecb | 6 years ago |
|
|
bd21d43ac9 | 6 years ago |
|
|
90738d7a36 | 6 years ago |
|
|
40aef395bb | 6 years ago |
|
|
67898b23e4 | 6 years ago |
|
|
2e26aee2b6 | 6 years ago |
|
|
f2c878c82b | 6 years ago |
|
|
814db5a33e | 6 years ago |
|
|
294683b390 | 6 years ago |
|
|
a269e7c106 | 6 years ago |
|
|
4d54074ad2 | 6 years ago |
|
|
c2bd60f1aa | 6 years ago |
|
|
a80d73602f | 6 years ago |
|
|
b8555ce4f3 | 6 years ago |
|
|
4e840c7669 | 6 years ago |
|
|
7f6dd16479 | 6 years ago |
|
|
98c71ee62e | 6 years ago |
|
|
c734f3e1ab | 6 years ago |
|
|
3c01f472e0 | 6 years ago |
|
|
4cc20eef72 | 6 years ago |
|
|
700cc5a055 | 6 years ago |
|
|
58850f0b93 | 6 years ago |
|
|
5677b2fc9d | 6 years ago |
|
|
8a726316bb | 6 years ago |
|
|
57aa69206a | 6 years ago |
|
|
358f647273 | 6 years ago |
|
|
8db933e440 | 6 years ago |
|
|
0e2d3789ce | 6 years ago |
|
|
959654c0c2 | 6 years ago |
|
|
9f1d185c44 | 6 years ago |
|
|
32775f0e43 | 6 years ago |
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
$config = array();
|
||||
|
||||
// Database configuration
|
||||
$config['db_dsnw'] = 'sqlite:////tmp/sqlite.db?mode=0646';
|
||||
|
||||
// Test user credentials
|
||||
$config['tests_username'] = 'test';
|
||||
$config['tests_password'] = 'test';
|
||||
|
||||
// GreenMail
|
||||
$config['smtp_port'] = 25;
|
||||
|
||||
// Settings required by the tests
|
||||
|
||||
$config['create_default_folders'] = true;
|
||||
$config['skin'] = 'elastic';
|
||||
$config['support_url'] = 'http://support.url';
|
||||
|
||||
// Plugins with tests
|
||||
|
||||
$config['plugins'] = [
|
||||
'archive',
|
||||
'attachment_reminder',
|
||||
'markasjunk',
|
||||
'zipdownload'
|
||||
];
|
||||
|
||||
$config['archive_mbox'] = 'Archive';
|
||||
@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The script is intended for use on Travis with Trusty distribution
|
||||
|
||||
DIR=$(dirname $0)
|
||||
|
||||
# Enable xdebug for code coverage
|
||||
if [ "$CODE_COVERAGE" != 1 ]; then phpenv config-rm xdebug.ini || true; fi
|
||||
|
||||
cd $DIR/..
|
||||
|
||||
cp composer.json-dist composer.json
|
||||
|
||||
# Add laravel/dusk for Browser tests
|
||||
if [ "$BROWSER_TESTS" = 1 ]; then composer require "laravel/dusk:~5.9.1" --no-update; fi
|
||||
|
||||
# Remove qr-code as it requires php-gd which is not always available on Travis
|
||||
# and we don't really need it for tests
|
||||
composer remove endroid/qr-code --no-update
|
||||
|
||||
# Install PHP dependencies
|
||||
composer install --prefer-dist
|
||||
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The script is intended for use on Travis with Trusty distribution
|
||||
# It executes unit and functional tests
|
||||
|
||||
DIR=$(dirname $0)
|
||||
cd $DIR/..
|
||||
|
||||
if [ "$CODE_COVERAGE" = 1 ]
|
||||
then
|
||||
CODE_COVERAGE_ARGS="--coverage-text"
|
||||
fi
|
||||
|
||||
vendor/bin/phpunit -c tests/phpunit.xml $CODE_COVERAGE_ARGS
|
||||
|
||||
if [ "$BROWSER_TESTS" = 1 ] && [ $? = 0 ]
|
||||
then
|
||||
.ci/setup.sh \
|
||||
&& echo "TESTS_MODE: DESKTOP" \
|
||||
&& TESTS_MODE=desktop vendor/bin/phpunit -c tests/Browser/phpunit.xml \
|
||||
&& echo "TESTS_MODE: PHONE" \
|
||||
&& TESTS_MODE=phone vendor/bin/phpunit -c tests/Browser/phpunit.xml \
|
||||
&& echo "TESTS_MODE: TABLET" \
|
||||
&& TESTS_MODE=tablet vendor/bin/phpunit -c tests/Browser/phpunit.xml
|
||||
fi
|
||||
@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
# The script is intended for use on Travis with Trusty distribution
|
||||
# It installs in-browser tests dependencies and prepares Roundcube instance
|
||||
|
||||
GMV=1.5.11
|
||||
CHROMEVERSION=$(google-chrome-stable --version | tr -cd [:digit:]. | cut -d . -f 1)
|
||||
GMARGS="-Dgreenmail.setup.all -Dgreenmail.users=test:test -Dgreenmail.startup.timeout=3000"
|
||||
|
||||
# Roundcube tests and instance configuration
|
||||
cp .ci/config-test.inc.php config/config-test.inc.php
|
||||
|
||||
# Make temp and logs writeable
|
||||
sudo chmod 777 temp logs
|
||||
|
||||
# Install javascript dependencies
|
||||
bin/install-jsdeps.sh
|
||||
|
||||
# Compile Elastic's styles
|
||||
lessc skins/elastic/styles/styles.less > skins/elastic/styles/styles.css
|
||||
lessc skins/elastic/styles/print.less > skins/elastic/styles/print.css
|
||||
lessc skins/elastic/styles/embed.less > skins/elastic/styles/embed.css
|
||||
|
||||
# Install proper WebDriver version for installed Chrome browser
|
||||
php tests/Browser/install.php $CHROMEVERSION
|
||||
|
||||
# GreenMail server download, setup and start
|
||||
wget https://repo1.maven.org/maven2/com/icegreen/greenmail-standalone/$GMV/greenmail-standalone-$GMV.jar \
|
||||
&& (sudo java $GMARGS -jar greenmail-standalone-$GMV.jar &) \
|
||||
&& sleep 5
|
||||
@ -1,6 +0,0 @@
|
||||
[submodule "plugins/postfixadmin-user-identities"]
|
||||
path = plugins/postfixadmin-user-identities
|
||||
url = git@git.banananet.work:banananetwork/roundcubemail-postfixadmin-user-identities.git
|
||||
[submodule "plugins/swipe"]
|
||||
path = plugins/swipe
|
||||
url = git@git.banananet.work:banananetwork/roundcubemail-swipe.git
|
||||
@ -0,0 +1,4 @@
|
||||
ALTER TABLE [dbo].[users] ALTER COLUMN [language] [varchar] (16) COLLATE Latin1_General_CI_AI NULL
|
||||
GO
|
||||
ALTER TABLE [dbo].[dictionary] ALTER COLUMN [language] [varchar] (16) COLLATE Latin1_General_CI_AI NOT NULL
|
||||
GO
|
||||
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `users` MODIFY `language` varchar(16);
|
||||
ALTER TABLE `dictionary` MODIFY `language` varchar(16) NOT NULL;
|
||||
@ -0,0 +1,21 @@
|
||||
ALTER TABLE `session` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `users` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache_shared` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache_index` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache_thread` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `cache_messages` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `contacts` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `contactgroups` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `identities` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `dictionary` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `searches` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `filestore` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
ALTER TABLE `system` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
ALTER TABLE `users` CHANGE `username` `username` varchar(128) BINARY NOT NULL;
|
||||
ALTER TABLE `cache` CHANGE `cache_key` `cache_key` varchar(128) BINARY NOT NULL;
|
||||
ALTER TABLE `cache_shared` CHANGE `cache_key` `cache_key` varchar(255) BINARY NOT NULL;
|
||||
ALTER TABLE `cache_index` CHANGE `mailbox` `mailbox` varchar(255) BINARY NOT NULL;
|
||||
ALTER TABLE `cache_thread` CHANGE `mailbox` `mailbox` varchar(255) BINARY NOT NULL;
|
||||
ALTER TABLE `cache_messages` CHANGE `mailbox` `mailbox` varchar(255) BINARY NOT NULL;
|
||||
@ -0,0 +1,2 @@
|
||||
ALTER TABLE "users" MODIFY "language" varchar(16) NOT NULL;
|
||||
ALTER TABLE "dictionary" MODIFY "language" varchar(16);
|
||||
@ -0,0 +1 @@
|
||||
-- empty
|
||||
@ -0,0 +1,2 @@
|
||||
ALTER TABLE "dictionary" ALTER COLUMN "language" TYPE varchar(16);
|
||||
ALTER TABLE "users" ALTER COLUMN "language" TYPE varchar(16);
|
||||
@ -0,0 +1 @@
|
||||
-- empty
|
||||
@ -0,0 +1,57 @@
|
||||
CREATE TABLE tmp_users (
|
||||
user_id integer NOT NULL PRIMARY KEY,
|
||||
username varchar(128) NOT NULL default '',
|
||||
mail_host varchar(128) NOT NULL default '',
|
||||
created datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
last_login datetime DEFAULT NULL,
|
||||
failed_login datetime DEFAULT NULL,
|
||||
failed_login_counter integer DEFAULT NULL,
|
||||
language varchar(16),
|
||||
preferences text NOT NULL default ''
|
||||
);
|
||||
|
||||
INSERT INTO tmp_users (user_id, username, mail_host, created, last_login, failed_login, failed_login_counter, language, preferences)
|
||||
SELECT user_id, username, mail_host, created, last_login, failed_login, failed_login_counter, language, preferences FROM users;
|
||||
|
||||
DROP TABLE users;
|
||||
|
||||
CREATE TABLE users (
|
||||
user_id integer NOT NULL PRIMARY KEY,
|
||||
username varchar(128) NOT NULL default '',
|
||||
mail_host varchar(128) NOT NULL default '',
|
||||
created datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
last_login datetime DEFAULT NULL,
|
||||
failed_login datetime DEFAULT NULL,
|
||||
failed_login_counter integer DEFAULT NULL,
|
||||
language varchar(16),
|
||||
preferences text NOT NULL default ''
|
||||
);
|
||||
|
||||
INSERT INTO users (user_id, username, mail_host, created, last_login, failed_login, failed_login_counter, language, preferences)
|
||||
SELECT user_id, username, mail_host, created, last_login, failed_login, failed_login_counter, language, preferences FROM tmp_users;
|
||||
|
||||
CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host);
|
||||
|
||||
DROP TABLE tmp_users;
|
||||
|
||||
DROP TABLE users;
|
||||
|
||||
CREATE TABLE tmp_dictionary (
|
||||
user_id integer DEFAULT NULL,
|
||||
language varchar(16) NOT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO tmp_dictionary (user_id, language, data) SELECT user_id, language, data FROM dictionary;
|
||||
|
||||
CREATE TABLE dictionary (
|
||||
user_id integer DEFAULT NULL,
|
||||
language varchar(16) NOT NULL,
|
||||
data text NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO dictionary (user_id, language, data) SELECT user_id, language, data FROM tmp_dictionary;
|
||||
|
||||
CREATE UNIQUE INDEX ix_dictionary_user_language ON dictionary (user_id, language);
|
||||
|
||||
DROP TABLE tmp_dictionary;
|
||||
@ -0,0 +1 @@
|
||||
-- empty
|
||||
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| Roundcube Webmail Selenium Tests Entry Point |
|
||||
| |
|
||||
| Copyright (C) The Roundcube Dev Team |
|
||||
| |
|
||||
| Licensed under the GNU General Public License version 3 or |
|
||||
| any later version with exceptions for skins & plugins. |
|
||||
| See the README file for a full license statement. |
|
||||
| |
|
||||
| PURPOSE: |
|
||||
| This is the public entry point for all HTTP requests to the |
|
||||
| Roundcube webmail application loading the 'tests' environment. |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Author: Thomas Bruederli <thomas@roundcube.net> |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
define('INSTALL_PATH', realpath(__DIR__) . '/');
|
||||
|
||||
$GLOBALS['env'] = 'test';
|
||||
|
||||
// include index.php from application root directory
|
||||
include INSTALL_PATH . 'index.php';
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 3.7 KiB |
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Plugins\Archive;
|
||||
|
||||
use Tests\Browser\Components\Popupmenu;
|
||||
|
||||
class MailTest extends \Tests\Browser\TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
\bootstrap::init_db();
|
||||
\bootstrap::init_imap();
|
||||
\bootstrap::purge_mailbox('INBOX');
|
||||
\bootstrap::purge_mailbox('Archive');
|
||||
|
||||
// import single email messages
|
||||
foreach (glob(TESTS_DIR . 'data/mail/list_00.eml') as $f) {
|
||||
\bootstrap::import_message($f, 'INBOX');
|
||||
}
|
||||
}
|
||||
|
||||
public function testMailUI()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->go('mail');
|
||||
|
||||
if (!$browser->isDesktop()) {
|
||||
$browser->click('.back-sidebar-button');
|
||||
}
|
||||
|
||||
// Folders list
|
||||
$browser->whenAvailable('#mailboxlist', function ($browser) {
|
||||
$browser->assertVisible('li.mailbox.archive')
|
||||
->assertMissing('li.mailbox.archive .unreadcount');
|
||||
});
|
||||
|
||||
if (!$browser->isDesktop()) {
|
||||
$browser->click('.back-list-button');
|
||||
}
|
||||
|
||||
// Toolbar menu (Archive button inactive)
|
||||
$browser->assertToolbarMenu([], ['archive']);
|
||||
|
||||
$browser->whenAvailable('#messagelist tbody', function ($browser) {
|
||||
$browser->ctrlClick('tr:last-child');
|
||||
});
|
||||
|
||||
$browser->clickToolbarMenuItem('archive')
|
||||
->waitForMessage('confirmation', 'Successfully archived')
|
||||
->closeMessage('confirmation');
|
||||
|
||||
if (!$browser->isDesktop()) {
|
||||
$browser->click('.back-sidebar-button');
|
||||
}
|
||||
|
||||
// Folders list
|
||||
$browser->whenAvailable('#mailboxlist', function ($browser) {
|
||||
$browser->assertSeeIn('li.mailbox.archive .unreadcount', '1')
|
||||
->click('li.mailbox.archive')
|
||||
->waitUntilNotBusy();
|
||||
});
|
||||
|
||||
// Messages list contains the moved message
|
||||
$browser->assertElementsCount('#messagelist tbody tr', 1);
|
||||
|
||||
// Toolbar menu (Archive button inactive again)
|
||||
$browser->assertToolbarMenu([], ['archive']);
|
||||
|
||||
// Test archive class on folder in folder selector
|
||||
$browser->ctrlClick('#messagelist tbody tr')
|
||||
->clickToolbarMenuItem('more')
|
||||
->with(new Popupmenu('message-menu'), function ($browser) {
|
||||
$browser->clickMenuItem('move');
|
||||
})
|
||||
->with(new Popupmenu('folder-selector'), function ($browser) {
|
||||
$browser->assertVisible('li.archive')
|
||||
->assertSeeIn('li.archive', 'Archive');
|
||||
})
|
||||
->click(); // close menus
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Plugins\Archive;
|
||||
|
||||
class SettingsTest extends \Tests\Browser\TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
\bootstrap::init_db();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Folders UI
|
||||
*/
|
||||
public function testFolders()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->go('settings', 'folders');
|
||||
|
||||
// Folders list
|
||||
$browser->with('#subscription-table', function ($browser) {
|
||||
$browser->assertHasClass('li:nth-child(7)', 'archive')
|
||||
->assertSeeIn('li:nth-child(7)', 'Archive')
|
||||
->assertPresent('li:nth-child(7) [type=checkbox][disabled]');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Preferences UI
|
||||
*/
|
||||
public function testPreferences()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->go('settings');
|
||||
|
||||
if (!$browser->isDesktop()) {
|
||||
$browser->click('#settings-menu li.preferences')
|
||||
->waitFor('#sections-table');
|
||||
}
|
||||
|
||||
$browser->click('#sections-table tr.folders');
|
||||
|
||||
if ($browser->isPhone()) {
|
||||
$browser->waitFor('#layout-content .footer a.button.submit:not(.disabled)');
|
||||
}
|
||||
|
||||
$browser->withinFrame('#preferences-frame', function ($browser) {
|
||||
if (!$browser->isPhone()) {
|
||||
$browser->waitFor('.formbuttons button.submit');
|
||||
}
|
||||
|
||||
// Main Options fieldset
|
||||
$browser->with('form.propform fieldset.main', function ($browser) {
|
||||
$browser->assertSeeIn('legend', 'Main Options');
|
||||
|
||||
$browser->assertSeeIn('label[for=_archive_mbox]', 'Archive')
|
||||
->assertVisible('select[name=_archive_mbox]')
|
||||
->assertSelected('select[name=_archive_mbox]', 'Archive');
|
||||
|
||||
$browser->select('_archive_mbox', 'Drafts');
|
||||
});
|
||||
|
||||
// Archive fieldset
|
||||
$browser->with('form.propform fieldset.archive', function ($browser) {
|
||||
$browser->assertSeeIn('legend', 'Archive');
|
||||
|
||||
$browser->assertSeeIn('label[for=ff_archive_type]', 'Divide archive by')
|
||||
->assertVisible('select[name=_archive_type]')
|
||||
->assertSelected('select[name=_archive_type]', '')
|
||||
->with('select[name=_archive_type]', function ($browser) {
|
||||
$browser->assertValue('option:nth-child(1)', '')
|
||||
->assertSeeIn('option:nth-child(1)', 'None')
|
||||
->assertValue('option:nth-child(2)', 'year')
|
||||
->assertSeeIn('option:nth-child(2)', 'Year (e.g. Archive/2012)')
|
||||
->assertValue('option:nth-child(3)', 'month')
|
||||
->assertSeeIn('option:nth-child(3)', 'Month (e.g. Archive/2012/06)')
|
||||
->assertValue('option:nth-child(4)', 'tbmonth')
|
||||
->assertSeeIn('option:nth-child(4)', 'Month - Thunderbird compatible (e.g. Archive/2012/2012-06)')
|
||||
->assertValue('option:nth-child(5)', 'sender')
|
||||
->assertSeeIn('option:nth-child(5)', 'Sender email')
|
||||
->assertValue('option:nth-child(6)', 'folder')
|
||||
->assertSeeIn('option:nth-child(6)', 'Original folder');
|
||||
});
|
||||
|
||||
$browser->select('_archive_type', 'year');
|
||||
});
|
||||
|
||||
// Submit form
|
||||
if (!$browser->isPhone()) {
|
||||
$browser->click('.formbuttons button.submit');
|
||||
}
|
||||
});
|
||||
|
||||
if ($browser->isPhone()) {
|
||||
$browser->click('#layout-content .footer a.submit');
|
||||
}
|
||||
|
||||
$browser->waitForMessage('confirmation', 'Successfully saved');
|
||||
|
||||
// Verify if every option has been updated
|
||||
$browser->withinFrame('#preferences-frame', function ($browser) {
|
||||
$browser->assertSelected('_archive_mbox', 'Drafts');
|
||||
$browser->assertSelected('_archive_type', 'year');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Preferences UI (Server Settings)
|
||||
*/
|
||||
public function testServerSettings()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->go('settings', 'preferences');
|
||||
|
||||
$browser->click('#sections-table tr.server');
|
||||
|
||||
$browser->withinFrame('#preferences-frame', function ($browser) {
|
||||
if (!$browser->isPhone()) {
|
||||
$browser->waitFor('.formbuttons button.submit');
|
||||
}
|
||||
|
||||
// Main Options fieldset
|
||||
$browser->with('form.propform fieldset.main', function ($browser) {
|
||||
$browser->assertSeeIn('label[for=ff_read_on_archive]', 'Mark the message as read on archive')
|
||||
->assertCheckboxState('_read_on_archive', false)
|
||||
->setCheckboxState('_read_on_archive', true);
|
||||
});
|
||||
|
||||
// Submit form
|
||||
if (!$browser->isPhone()) {
|
||||
$browser->click('.formbuttons button.submit');
|
||||
}
|
||||
});
|
||||
|
||||
if ($browser->isPhone()) {
|
||||
$browser->click('#layout-content .footer a.submit');
|
||||
}
|
||||
|
||||
$browser->waitForMessage('confirmation', 'Successfully saved');
|
||||
|
||||
// Verify if every option has been updated
|
||||
$browser->withinFrame('#preferences-frame', function ($browser) {
|
||||
$browser->assertCheckboxState('_read_on_archive', true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Plugins\AttachmentReminder;
|
||||
|
||||
use Tests\Browser\Components\Dialog;
|
||||
|
||||
class PluginTest extends \Tests\Browser\TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
\bootstrap::init_db();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Preferences UI (Composing Messages)
|
||||
*/
|
||||
public function testPreferences()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->go('settings', 'preferences');
|
||||
|
||||
$browser->click('#sections-table tr.compose');
|
||||
|
||||
$browser->withinFrame('#preferences-frame', function ($browser) {
|
||||
if (!$browser->isPhone()) {
|
||||
$browser->waitFor('.formbuttons button.submit');
|
||||
}
|
||||
|
||||
// Main Options fieldset
|
||||
$browser->with('form.propform fieldset.main', function ($browser) {
|
||||
$browser->assertSeeIn('label[for=rcmfd_attachment_reminder]', 'Remind about forgotten attachments')
|
||||
->assertCheckboxState('_attachment_reminder', false)
|
||||
->setCheckboxState('_attachment_reminder', true);
|
||||
});
|
||||
|
||||
// Submit form
|
||||
if (!$browser->isPhone()) {
|
||||
$browser->click('.formbuttons button.submit');
|
||||
}
|
||||
});
|
||||
|
||||
if ($browser->isPhone()) {
|
||||
$browser->click('#layout-content .footer a.submit');
|
||||
}
|
||||
|
||||
$browser->waitForMessage('confirmation', 'Successfully saved');
|
||||
|
||||
// Verify if every option has been updated
|
||||
$browser->withinFrame('#preferences-frame', function ($browser) {
|
||||
$browser->assertCheckboxState('_attachment_reminder', true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Mail Compose page
|
||||
*
|
||||
* @depends testPreferences
|
||||
*/
|
||||
public function testMailCompose()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$send_btn = $browser->isPhone() ? '.buttons a.send' : '.formbuttons button.send';
|
||||
|
||||
$browser->go('mail', 'compose');
|
||||
|
||||
$browser->waitFor('#compose_to')
|
||||
->type('#compose_to input', 'test@domain.tld')
|
||||
->type('#compose-subject', 'subject')
|
||||
->type('#composebody', 'File attached')
|
||||
->click($send_btn);
|
||||
|
||||
// Expect a dialog, Click "Attach a file" button
|
||||
$browser->with(new Dialog(), function ($browser) {
|
||||
$browser->assertDialogTitle('Missing attachment?')
|
||||
->assertDialogContent('Did you forget to attach a file?')
|
||||
->assertButton('mainaction.attach', 'Attach a file')
|
||||
->assertButton('send', 'Send')
|
||||
->clickButton('mainaction.attach');
|
||||
});
|
||||
|
||||
// Click the Send button again
|
||||
$browser->click($send_btn);
|
||||
|
||||
// Expect the dialog again, click Send button (in the dialog)
|
||||
$browser->with(new Dialog(), function ($browser) {
|
||||
$browser->assertDialogTitle('Missing attachment?')
|
||||
->clickButton('send');
|
||||
});
|
||||
|
||||
$browser->waitForMessage('confirmation', 'Message sent successfully.');
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Plugins\Markasjunk;
|
||||
|
||||
use Tests\Browser\Components\Popupmenu;
|
||||
|
||||
class MailTest extends \Tests\Browser\TestCase
|
||||
{
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
\bootstrap::init_db();
|
||||
\bootstrap::init_imap();
|
||||
\bootstrap::purge_mailbox('INBOX');
|
||||
\bootstrap::purge_mailbox('Junk');
|
||||
|
||||
// import single email message
|
||||
\bootstrap::import_message(TESTS_DIR . 'data/mail/list_00.eml', 'INBOX');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test plugin functionality in Mail UI
|
||||
*/
|
||||
public function testMailUI()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->go('mail');
|
||||
|
||||
// Toolbar menu (Spam button inactive)
|
||||
$browser->assertToolbarMenu([], ['junk']);
|
||||
|
||||
$browser->whenAvailable('#messagelist tbody', function ($browser) {
|
||||
$browser->ctrlClick('tr:last-child');
|
||||
});
|
||||
|
||||
$browser->clickToolbarMenuItem('junk')
|
||||
->waitForMessage('confirmation', 'Successfully reported as junk')
|
||||
->closeMessage('confirmation')
|
||||
->assertElementsCount('#messagelist tbody tr', 0) // empty list
|
||||
->waitForMessage('confirmation', 'Message(s) moved successfully.')
|
||||
->closeMessage('confirmation');
|
||||
|
||||
if (!$browser->isDesktop()) {
|
||||
$browser->click('.back-sidebar-button');
|
||||
}
|
||||
|
||||
// Folders list
|
||||
$browser->whenAvailable('#mailboxlist', function ($browser) {
|
||||
$browser->assertSeeIn('li.mailbox.junk .unreadcount', '1')
|
||||
->assertMissing('li.mailbox.inbox .unreadcount')
|
||||
->click('li.mailbox.junk')
|
||||
->waitUntilNotBusy();
|
||||
});
|
||||
|
||||
// Toolbar menu (Non-Junk button inactive)
|
||||
$browser->assertToolbarMenu([], ['notjunk']);
|
||||
|
||||
// Messages list contains the moved message
|
||||
$browser->whenAvailable('#messagelist tbody', function ($browser) {
|
||||
$browser->assertElementsCount('tr', 1)
|
||||
->ctrlClick('tr:last-child');
|
||||
});
|
||||
|
||||
$browser->clickToolbarMenuItem('notjunk')
|
||||
->waitForMessage('confirmation', 'Successfully reported as not junk')
|
||||
->closeMessage('confirmation')
|
||||
->assertElementsCount('#messagelist tbody tr', 0) // empty list
|
||||
->waitForMessage('confirmation', 'Message(s) moved successfully.')
|
||||
->closeMessage('confirmation');
|
||||
|
||||
if (!$browser->isDesktop()) {
|
||||
$browser->click('.back-sidebar-button');
|
||||
}
|
||||
|
||||
// Folders list, the message is back in INBOX
|
||||
$browser->whenAvailable('#mailboxlist', function ($browser) {
|
||||
$browser->assertMissing('li.mailbox.junk .unreadcount')
|
||||
->assertSeeIn('li.mailbox.inbox .unreadcount', '1')
|
||||
->click('li.mailbox.inbox')
|
||||
->waitUntilNotBusy();
|
||||
});
|
||||
|
||||
// Messages list contains the moved message
|
||||
$browser->whenAvailable('#messagelist tbody', function ($browser) {
|
||||
$browser->assertElementsCount('tr', 1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test plugin functionality on email preview page
|
||||
*
|
||||
* @depends testMailUI
|
||||
*/
|
||||
public function testMailView()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->go('mail');
|
||||
|
||||
$browser->whenAvailable('#messagelist tbody', function ($browser) {
|
||||
$browser->mouseover('tr:last-child')->doubleClick();
|
||||
});
|
||||
|
||||
$browser->waitFor('#message-content');
|
||||
|
||||
// Toolbar menu (Junk button active), click it
|
||||
$browser->clickToolbarMenuItem('junk')
|
||||
->waitFor('#messagelist')
|
||||
->waitUntilNotBusy()
|
||||
->assertElementsCount('#messagelist tbody tr', 0); // empty list
|
||||
|
||||
if (!$browser->isDesktop()) {
|
||||
$browser->click('.back-sidebar-button');
|
||||
}
|
||||
|
||||
// Folders list
|
||||
$browser->whenAvailable('#mailboxlist', function ($browser) {
|
||||
$browser->click('li.mailbox.junk')
|
||||
->waitUntilNotBusy();
|
||||
});
|
||||
|
||||
$browser->whenAvailable('#messagelist tbody', function ($browser) {
|
||||
$browser->mouseover('tr:last-child')->doubleClick();
|
||||
});
|
||||
|
||||
$browser->waitFor('#message-content');
|
||||
|
||||
// Toolbar menu (Junk button active), click it
|
||||
$browser->clickToolbarMenuItem('notjunk')
|
||||
->waitFor('#messagelist')
|
||||
->waitUntilNotBusy()
|
||||
->assertElementsCount('#messagelist tbody tr', 0); // empty list
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Have I Been Pwned Password Strength Driver
|
||||
*
|
||||
* Driver to check passwords using HIBP:
|
||||
* https://haveibeenpwned.com/Passwords
|
||||
*
|
||||
* This driver will return a strength of:
|
||||
* 3: if the password WAS NOT found in HIBP
|
||||
* 1: if the password WAS found in HIBP
|
||||
* 2: if there was an ERROR retrieving data.
|
||||
*
|
||||
* To use this driver, configure (in ../config.inc.php):
|
||||
*
|
||||
* $config['password_strength_driver'] = 'pwned';
|
||||
* $config['password_minimum_score'] = 3;
|
||||
*
|
||||
* Set the minimum score to 3 if you want to make sure that all
|
||||
* passwords are successfully checked against HIBP (recommended).
|
||||
*
|
||||
* Set it to 2 if you still want to accept passwords in case a
|
||||
* HIBP check fails for some (technical) reason.
|
||||
*
|
||||
* Setting the minimum score to 1 or less effectively renders
|
||||
* the checks useless, as all passwords would be accepted.
|
||||
* Setting it to 4 or more will effectively reject all passwords.
|
||||
*
|
||||
* This driver will only return a maximum score of 3 because not
|
||||
* being listed in HIBP does not necessarily mean that the
|
||||
* password is a good one. It is therefore recommended to also
|
||||
* configure a minimum length for the password.
|
||||
*
|
||||
* Background reading (don't worry, your passwords are not sent anywhere):
|
||||
* https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/#cloudflareprivacyandkanonymity
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Christoph Langguth
|
||||
*
|
||||
* Copyright (C) The Roundcube Dev Team
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
class rcube_pwned_password
|
||||
{
|
||||
// API URL. Note: the trailing slash is mandatory.
|
||||
const API_URL = 'https://api.pwnedpasswords.com/range/';
|
||||
|
||||
// See https://www.troyhunt.com/enhancing-pwned-passwords-privacy-with-padding/
|
||||
const ENHANCED_PRIVACY_CURL = 1;
|
||||
|
||||
// Score constants, these directly correspond to the score that is returned.
|
||||
const SCORE_LISTED = 1;
|
||||
const SCORE_ERROR = 2;
|
||||
const SCORE_NOT_LISTED = 3;
|
||||
|
||||
/**
|
||||
* Rule description.
|
||||
*
|
||||
* @return array human-readable description of the check rule.
|
||||
*/
|
||||
function strength_rules()
|
||||
{
|
||||
$rc = rcmail::get_instance();
|
||||
return array($rc->gettext('password.pwned_mustnotbedisclosed'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Password strength check.
|
||||
* Return values:
|
||||
* 1 - if password is definitely compromised.
|
||||
* 2 - if status for password can't be determined (network failures etc.)
|
||||
* 3 - if password is not publicly known to be compromised.
|
||||
*
|
||||
* @param string $passwd Password
|
||||
*
|
||||
* @return array password score (1 to 3) and (optional) reason message
|
||||
*/
|
||||
function check_strength($passwd)
|
||||
{
|
||||
$score = $this->check_pwned($passwd);
|
||||
$message = null;
|
||||
|
||||
if ($score !== self::SCORE_NOT_LISTED) {
|
||||
$rc = rcmail::get_instance();
|
||||
if ($score === self::SCORE_LISTED) {
|
||||
$message = $rc->gettext('password.pwned_isdisclosed');
|
||||
}
|
||||
else {
|
||||
$message = $rc->gettext('password.pwned_fetcherror');
|
||||
}
|
||||
}
|
||||
|
||||
return array($score, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check password using HIBP.
|
||||
*
|
||||
* @param string $passwd
|
||||
*
|
||||
* @return int score, one of the SCORE_* constants (between 1 and 3).
|
||||
*/
|
||||
function check_pwned($passwd)
|
||||
{
|
||||
// initialize with error score
|
||||
$result = self::SCORE_ERROR;
|
||||
|
||||
if (!$this->can_retrieve()) {
|
||||
// Log the fact that we cannot check because of configuration error.
|
||||
rcube::raise_error("Need curl or allow_url_fopen to check password strength with 'pwned'", true, true);
|
||||
}
|
||||
else {
|
||||
list($prefix, $suffix) = $this->hash_split($passwd);
|
||||
|
||||
$suffixes = $this->retrieve_suffixes(self::API_URL . $prefix);
|
||||
|
||||
if ($suffixes) {
|
||||
$result = $this->check_suffix_in_list($suffix, $suffixes);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function hash_split($passwd)
|
||||
{
|
||||
$hash = strtolower(sha1($passwd));
|
||||
$prefix = substr($hash, 0, 5);
|
||||
$suffix = substr($hash, 5);
|
||||
|
||||
return array($prefix, $suffix);
|
||||
}
|
||||
|
||||
function can_retrieve()
|
||||
{
|
||||
return $this->can_curl() || $this->can_fopen();
|
||||
}
|
||||
|
||||
function can_curl()
|
||||
{
|
||||
return function_exists('curl_init');
|
||||
}
|
||||
|
||||
function can_fopen()
|
||||
{
|
||||
return ini_get('allow_url_fopen');
|
||||
}
|
||||
|
||||
function retrieve_suffixes($url)
|
||||
{
|
||||
if ($this->can_curl()) {
|
||||
return $this->retrieve_curl($url);
|
||||
}
|
||||
else {
|
||||
return $this->retrieve_fopen($url);
|
||||
}
|
||||
}
|
||||
|
||||
function retrieve_curl($url)
|
||||
{
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
if (self::ENHANCED_PRIVACY_CURL == 1) {
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Add-Padding: true'));
|
||||
}
|
||||
$output = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function retrieve_fopen($url)
|
||||
{
|
||||
$output = '';
|
||||
$ch = fopen($url, 'r');
|
||||
while (!feof($ch)) {
|
||||
$output .= fgets($ch);
|
||||
}
|
||||
fclose($ch);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function check_suffix_in_list($candidate, $list)
|
||||
{
|
||||
// initialize to error in case there are no lines at all
|
||||
$result = self::SCORE_ERROR;
|
||||
|
||||
foreach (preg_split('/[\r\n]+/', $list) as $line) {
|
||||
$line = strtolower($line);
|
||||
|
||||
if (preg_match('/^([0-9a-f]{35}):(\d+)$/', $line, $matches)) {
|
||||
if ($matches[2] > 0 && $matches[1] === $candidate) {
|
||||
// more than 0 occurrences, and suffix matches
|
||||
// -> password is compromised
|
||||
return self::SCORE_LISTED;
|
||||
}
|
||||
|
||||
// valid line, not matching the current password
|
||||
$result = self::SCORE_NOT_LISTED;
|
||||
}
|
||||
else {
|
||||
// invalid line
|
||||
return self::SCORE_ERROR;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit d56529721ad8a4bbfb81972c70ee697131fd89b4
|
||||
@ -1 +0,0 @@
|
||||
Subproject commit 884c2bd51b747465a8b1d340cb4186082da1f786
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue