Compare commits

..

344 Commits

Author SHA1 Message Date
Aleksander Machniak 0ba44f0d92 Fix bug in remote content blocking on HTML image and style tags (#6178) 6 years ago
Aleksander Machniak e252736ef1 Merge branch 'release-1.0' of github.com:roundcube/roundcubemail into release-1.0 6 years ago
Thomas Bruederli 0b42424e41 Bump version + add CVE ID 7 years ago
Aleksander Machniak 4f5d8ab015 Update changelog 7 years ago
Aleksander Machniak 8d87bb34f3 Fix file disclosure vulnerability caused by insuficient input validation in relation with attachment plugins (#6026) 7 years ago
Thomas Bruederli ca74231733 Bump version to 1.0.11 7 years ago
Aleksander Machniak 62edcc6283 Add CVE ident 7 years ago
Aleksander Machniak 271426429b Password: Fix security issue in virtualmin and sasl drivers 7 years ago
Thomas Bruederli 511793c25f Update Changelog + bump version to 1.0.10 7 years ago
Thomas Bruederli 37cae3ecfa Strip HTML tags inside CSS style definitions 7 years ago
Aleksander Machniak b0f57a7edc Fix XSS issue in handling of a style tag inside of an svg element 7 years ago
Aleksander Machniak a54dde834c Fix vulnerability in handling of mail()'s 5th argument 8 years ago
Aleksander Machniak 5d2aaa68c3 Fix _from argument validation 8 years ago
Aleksander Machniak dc0c6067b7 Update changelog 8 years ago
Aleksander Machniak 1e275ac13a Wash position:fixed style in HTML mail for better security (#5264) 8 years ago
Aleksander Machniak f1ca20d993 Don't create multipart/alternative messages with empty text/plain part (#5283)
Conflicts:
	CHANGELOG
	program/steps/mail/sendmail.inc
8 years ago
Thomas Bruederli 7b37ef8a33 Avoid sending completely empty text parts for multipart/alternative messages (#5283) 8 years ago
Aleksander Machniak acf633c73b Fix XSS issue in href attribute on area tag (#5240, #5241)
Conflicts:

	CHANGELOG
8 years ago
Thomas Bruederli cde7a9eb74 Bump version to 1.0.9 8 years ago
Thomas Bruederli b76d8e91d6 Transliterate ticket IDs after migration to Github issues 8 years ago
Aleksander Machniak 74c75ee529 Refer to Github issues instead of Trac 8 years ago
Thomas Bruederli fca89f0e77 Refer to Github issues instead of Trac 8 years ago
Aleksander Machniak 10f24c034b Hide DSN option in Preferences when smtp_server is not used (#1490666) 8 years ago
Aleksander Machniak 3c988b0f08 Update changelog 8 years ago
Aleksander Machniak 5466f71dd6 Fix a regression where some contact data was missing in export and PHP warnings were logged (Kolab #4522) 8 years ago
Aleksander Machniak efe06f2b12 Bring back additional_message_headers compatibility with Mail_Mime < 1.9 8 years ago
Aleksander Machniak b2d4cfa89a Fix additional_message_headers plugin compatibility with Mail_Mime >= 1.9 (#1490657)
Conflicts:

	CHANGELOG
	plugins/additional_message_headers/composer.json
8 years ago
Aleksander Machniak 3e12784cc2 Fix bug in long recipients list parsing for cases where recipient name contained @-char (#1490653) 8 years ago
Aleksander Machniak 7496302945 Fix bug where Archive/Junk buttons were not active after page jump with select=all mode (#1490647)
Conflicts:

	program/js/app.js
8 years ago
Aleksander Machniak a7fac6afb6 Fix (again) security issue in DBMail driver of password plugin [CVE-2015-2181] (#1490643)
Unify the C program code with the one used by other drivers.

Conflicts:
	CHANGELOG
8 years ago
Aleksander Machniak 889989db06 Fix regression where xml mode could be used to parse xhtml messages causing empty result 8 years ago
Aleksander Machniak 73f8b524f3 Improved SVG cleanup code 8 years ago
Aleksander Machniak 190c658fe3 Refactor wash_attribs() - fix regressions 8 years ago
Aleksander Machniak ffd5ffc30a Extend rcube_washtml with SVG support
Conflicts:

	program/lib/Roundcube/rcube_washtml.php
8 years ago
Aleksander Machniak 3faf89c354 Fix XSS issue in SVG images handling (#1490625)
Conflicts:

	CHANGELOG
	program/steps/mail/get.inc
8 years ago
Francis Russell e77b5f7dd7 Make TLS method for IMAP parameterisable. 9 years ago
Francis Russell 6a70e56e5e Enable use of TLSv1.1 and TLSv1.2 for IMAP.
Conflicts:

	CHANGELOG
9 years ago
Thomas Bruederli 2c0a550105 Bump version to 1.0.8; update Changelog 9 years ago
Aleksander Machniak 222f47c042 Fix .htaccess rewrite rules to not block .well-known URIs (#1490615)
Conflicts:

	.htaccess
9 years ago
Aleksander Machniak 82fcd4e757 Fix so drag-n-drop of text (e.g. recipient addresses) on compose page actually works (#1490619)
Conflicts:

	program/js/app.js
9 years ago
Aleksander Machniak 21b523c29b Fix path traversal vulnerability in setting a skin (#1490620) 9 years ago
Aleksander Machniak 50403d66e0 Fix PDF support detection in Firefox > 19 (#1490610)
Conflicts:
	CHANGELOG
	program/js/app.js
9 years ago
Aleksander Machniak 5579ef6621 Fix handling of message/rfc822 attachments on replies and forwards (#1490607)
Conflicts:

	CHANGELOG
	program/lib/Roundcube/rcube_message.php
	program/steps/mail/compose.inc
	program/steps/mail/func.inc
9 years ago
Aleksander Machniak 6402eb7f78 Fix charset encoding of message/rfc822 part bodies (#1490606) 9 years ago
Aleksander Machniak e7d1a80a80 Fix HTML sanitizer to skip <!-- node type X --> in output (#1490583)
Conflicts:

	CHANGELOG
9 years ago
Aleksander Machniak 48ab1add35 Add workaround for https://bugs.php.net/bug.php?id=70757 (#1490582)
Conflicts:

	CHANGELOG
9 years ago
Thomas Bruederli 7bd7d60add Bump version to 1.0.7 9 years ago
Aleksander Machniak 969547784e Fix issue where Content-Length of some attachments could be set to wrong value causing browser errors (#1490482) 9 years ago
Aleksander Machniak 4ec947715d Fix XSS issue in drag-n-drop file uploads (#1490530)
Conflicts:

	CHANGELOG
9 years ago
Aleksander Machniak 175ca6fd65 Fix so In-Reply-To header is set also for MDN receipts (#1490523) 9 years ago
Aleksander Machniak 98a61c74ee Fix various issues with Turkish (and similar) locales (#1490519)
Conflicts:

	program/include/rcmail.php
9 years ago
Aleksander Machniak 3b59a32026 Fix support for Mozilla-based browsers, e.g. Pale Moon (#1490517)
Conflicts:
	program/js/app.js
9 years ago
Aleksander Machniak e6939619f7 Fix so gc.sh script removes also expired sessions from sql database (#1490512)
Conflicts:
	CHANGELOG
9 years ago
Aleksander Machniak 6ab1553b5e Fix so gc.sh script removes also expired sessions from sql database (#1490512)
Conflicts:
	CHANGELOG
9 years ago
Aleksander Machniak 8cded09621 Fix handling of plus character in mailto: links (#1490510)
Conflicts:

	CHANGELOG
9 years ago
Aleksander Machniak eb318205fc Fix compatibility with Mail_Mime >= 1.9.0 9 years ago
Aleksander Machniak 67229a86df Don't use private properties of Net_SMTP object
Conflicts:
	program/lib/Roundcube/rcube_smtp.php
9 years ago
Aleksander Machniak d1fa2f7f7a Add missing labels (#1490496) 9 years ago
Thomas Bruederli ccaf87415e Add localization alias for tr => tr_TR 9 years ago
Aleksander Machniak 4b61f35dc9 Remove Mail_mimeDecode package 9 years ago
Aleksander Machniak a7e552b5a4 Get rid of Mail_mimeDecode package dependency (#1490416)
Conflicts:

	CHANGELOG
	composer.json-dist
	installer/check.php
	program/lib/Roundcube/rcube_mime.php
9 years ago
Aleksander Machniak c5157fb74a Fix draft removal after a message is sent and storing sent message is disabled (#1490467)
Conflicts:
	CHANGELOG
9 years ago
Aleksander Machniak e94f5c023c Fix so plain text signature field uses monospace font (#1490435)
Conflicts:

	CHANGELOG
9 years ago
Aleksander Machniak fb71e73933 Fix SQL error on logout when using session_storage=php (#1490421)
Conflicts:
	CHANGELOG
9 years ago
Thomas Bruederli f3277e072e Bump version to 1.0.6 9 years ago
Aleksander Machniak bfe6570cb0 Fix issues when using moduserprefs.sh without --user argument (#1490399)
Conflicts:

	program/include/rcmail_utils.php
9 years ago
Aleksander Machniak 7fdc341a22 Fix attached file path unsetting in database_attachments plugin (#1490393)
Conflicts:

	CHANGELOG
9 years ago
Aleksander Machniak 6d571ee561 Update changelog 9 years ago
Aleksander Machniak ead2368b71 Fix bug where database_attachments_cache setting was not working 9 years ago
Aleksander Machniak 6ccd4c54bc Fix security issue in contact photo handling (#1490379) 9 years ago
Aleksander Machniak 3aba794f70 Fix bug where messages count was not updated after message move/delete with skip_deleted=false (#1490372)
Conflicts:
	CHANGELOG
9 years ago
Aleksander Machniak c2e41a6dd5 Fix handling of %-encoded entities in mailto: URLs (#1490346)
Conflicts:

	CHANGELOG
9 years ago
Aleksander Machniak 997ff77ea1 Fix "PHP Fatal error: Call to a member function getMessage() on a non-object" 9 years ago
Aleksander Machniak 331f1d9e20 Update changelog 9 years ago
Aleksander Machniak b022d7b0d4 Fix rowcount if search fails (#1490266) 9 years ago
Aleksander Machniak 23bcfc5849 Fix "Add response" button title, remove wrong identities_level checks in Responses, fix cursor on some lists
Conflicts:
	skins/classic/settings.css
9 years ago
Aleksander Machniak 8defdaf0b1 Fix duplicate entry on timezones list in rcube_config::timezone_name_from_abbr() (#1490293)
Conflicts:

	CHANGELOG
9 years ago
Aleksander Machniak 5321cbd498 Fix missing or not up-to-date CATEGORIES entry in vCard export (#1490277)
Conflicts:
	CHANGELOG
9 years ago
Aleksander Machniak ac93924b1f Fix handling of some improper constructs in format=flowed text as per the RFC3676[4.5] (#1490284)
Conflicts:
	CHANGELOG
9 years ago
Aleksander Machniak f6336f7f7e Fix security issue in DBMail driver of password plugin (#1490261)
Conflicts:

	CHANGELOG
9 years ago
Aleksander Machniak 2646758314 Fix handling of GETANNOTATION errors - return NULL on error as documented 9 years ago
Aleksander Machniak 0ec46f3d40 Update changelog 9 years ago
Aleksander Machniak 78f948f7b9 Make logged SMTP errors more verbose - log also real server response and codes 9 years ago
Thomas Bruederli bd3e202787 Bump version to 1.0.5 9 years ago
Aleksander Machniak 2109fc94fb Fix bug where empty fieldmap config entries caused empty results of ldap search (#1490229)
Conflicts:

	CHANGELOG
9 years ago
Aleksander Machniak 7c26dbd36f Fix javascript error in "IE 8.0/Tablet PC" browser (#1490210) 10 years ago
Aleksander Machniak f640e144dc Fix bug where search was reset after returning from compose opened by reply button(s)
Conflicts:

	program/js/app.js
10 years ago
Aleksander Machniak 56caf85079 Fix so "set as default" option is hidden if identities_level > 1 (#1490226) 10 years ago
Aleksander Machniak db780e10e4 Fix bug where Drafts list wasn't updated on draft-save action in new window (#1490225)
That if the window was opened using "Edit" button, not double-click on a message.

Conflicts:

	CHANGELOG
10 years ago
Aleksander Machniak 04994005e7 Fix XSS issue in style attribute handling (#1490227)
Conflicts:

	CHANGELOG
10 years ago
Aleksander Machniak b134f59eb1 Fix checks based on window.ActiveXObject in IE > 10
Conflicts:
	CHANGELOG
10 years ago
Thomas Bruederli 37757464fd Correctly handle DateTime values in Vcard export 10 years ago
Aleksander Machniak ed32835aba Fix bug where sent message was saved in Sent folder even if disabled by user (#1490208) 10 years ago
Aleksander Machniak cbacfb30a9 Update changelog 10 years ago
Aleksander Machniak f2d28ebbbb Fix offset of download icon 10 years ago
Thomas Bruederli be363cdf92 Use current year for timezone offset display 10 years ago
Aleksander Machniak acbf70d5bd Add _mbox parameter to the 'mark' request sent after opening a message 10 years ago
Aleksander Machniak c608ae1ffe Update changelog 10 years ago
Aleksander Machniak fa5dabb574 Merge pull request #252 from corbosman/uufix
fix uupart handling
10 years ago
corbosman 242d3c520b fix uupart handling 10 years ago
Thomas Bruederli 1f7e63f786 Bump version 10 years ago
Aleksander Machniak 2ae677afd7 Read page and page_size before check_recent hook is executed
- some plugins may change them to invalid values (in mail context)
10 years ago
Aleksander Machniak 376cbfd4f2 Fix bugs where CSRF attacks were still possible on some requests 10 years ago
Aleksander Machniak 753c8849ac Fix generation of Blowfish-based password hashes (#1490184)
Added password_blowfish_cost config option.

Conflicts:
	CHANGELOG
10 years ago
Aleksander Machniak 35502e04a8 Update changelog 10 years ago
David Carter 94d8fb5a42 The following:
program/steps/mail/compose.inc :: rcmail_store_target_selection()
  program/steps/settings/edit_folder.inc :: rcmail_folder_form()

both try to localise mailbox names.

Push the logic down into the folder_selector() method which can use:

  $this->config->get('show_real_foldernames')

to decide the correct default behaviour.

Clients functions and methods can still override by adding 'realnames'
named parameter to the folder_selector() call. The obvious example is
the Settings -> Preferences -> Special Folders screen.
10 years ago
Aleksander Machniak 7e34e4c5b5 Merge branch 'release-1.0' of github.com:roundcube/roundcubemail into release-1.0 10 years ago
Aleksander Machniak 9f1fd39695 Fix issue where Archive folder wasn't protected in Folder Manager (#1490154) 10 years ago
Thomas Bruederli ced9e5a5bf Updated localizations from Transifex 10 years ago
Aleksander Machniak 4446aea1e6 Fix lack of delimiter for recipient addresses in smtp_log (#1490150) 10 years ago
Aleksander Machniak 33f8bd6918 Fix bug where cancelling switch from HTML to plain text didn't set editor type selector properly (#1490141) 10 years ago
Aleksander Machniak 1852f984c0 Call exif_read_data() only on JPEG images 10 years ago
Aleksander Machniak a4289060e6 Fixed typo 10 years ago
Aleksander Machniak e03bcf3406 More get_folder() -> $MESSAGE->folder 10 years ago
Aleksander Machniak bc42d0a041 Don't trust get_folder(), use $MESSAGE->folder if available 10 years ago
Aleksander Machniak 73b14686fc Fix possible issues in skin/skin_path config handling (#1490125)
Conflicts:

	program/lib/Roundcube/rcube_plugin.php
10 years ago
Aleksander Machniak 080f560e0f Fix reply scrolling issue with text mode and start message below the quote (#1490114)
Conflicts:

	program/js/app.js
10 years ago
Aleksander Machniak b5fd858eb2 Fix bug where creating subfolders in shared folders wasn't possible without ACL extension (#1490113) 10 years ago
Aleksander Machniak 50341eab43 Disable TinyMCE contextmenu plugin as there are more cons than pros in using it (#1490118) 10 years ago
Bartlomiej Nogas 281ca0ea2a Fix of really fix UNKNOWN-CTE handling 10 years ago
Aleksander Machniak 7653ed107e Fix compatibility with PHP 5.2. in rcube_imap_generic (#1490115) 10 years ago
Aleksander Machniak a23c233db6 Really fix UNKNOWN-CTE handling 10 years ago
Aleksander Machniak cbac33113a Fix "PHP Fatal error: Cannot redeclare class PEAR" if both program/lib/PEAR.php and composer loaders exist (#1490112) 10 years ago
Aleksander Machniak 89984d01ba Fix handling of UNKNOWN-CTE response, try do decode content client-side (#1490046) 10 years ago
Aleksander Machniak 4efc69e7fd Fix handling of base64-encoded attachments with extra spaces (#1490111) 10 years ago
Aleksander Machniak 793642ed76 Fix handling of uuencoded messages if messages_cache is enabled (#1490108)
Conflicts:
	program/lib/Roundcube/rcube_message.php
10 years ago
Aleksander Machniak 3db1599538 Fix download of attachments that are part of TNEF message (#1490091) 10 years ago
Aleksander Machniak 6bdbca3879 Fix font style display issue in HTML messages with styled <span> elements (#1490101) 10 years ago
Aleksander Machniak 3eab20980a Fix displaying of HTML messages with absolutely positioned elements in Larry skin (#1490103) 10 years ago
Aleksander Machniak 047fc190f3 Fix regression in SHAA password generation in ldap driver of password plugin (#1490094) 10 years ago
Aleksander Machniak 0d6c673546 Fix setting flags on servers with no PERMANENTFLAGS response (#1490087)
Conflicts:
	CHANGELOG
10 years ago
Aleksander Machniak 34d179a69a Fix handling of smart list inputs 10 years ago
Aleksander Machniak 5c3bbb9e0d Support hashing algorithms without mhash() and even hash() extension (#1490076) 10 years ago
Thomas Bruederli 3febefe03a Updated Changelog + bump version 10 years ago
Thomas Bruederli fef904c6b1 Enable/disable siganture commands before exiting the function in new compose window (#1490074) 10 years ago
Thomas Bruederli 1070bdb389 Update Changelog 10 years ago
Thomas Bruederli 6c96b1b7cd Initialize TinyMCE editor in rcmail.init() instead of a separate call after. This makes the edior ready when restoring a HTML message from localStorage (#1490016) 10 years ago
Thomas Bruederli 1f4b06a853 Set comm_path env variable after reset 10 years ago
Thomas Bruederli a4dc96e73e Add 'sig_max_lines' config option to defaults (#1490071) 10 years ago
Thomas Bruederli 7d5a1c20e8 Fix splitter code to properly work with 1px size borders 10 years ago
Thomas Bruederli a5ce2d8ae2 Make noshow attribute for roundcube:label tags actually work as supposed 10 years ago
Thomas Bruederli e1db66a4b4 Avoid errors when contacts widget is missing (in derived skins for example) 10 years ago
Thomas Bruederli 2fa50dce32 Access list body through abstract property 10 years ago
Aleksander Machniak 9a49821244 Fix validation of email addresses with IDNA domains (#1490067) 10 years ago
Aleksander Machniak d6867490ab Index IX_contactgroups_user_id was created on the wrong table 10 years ago
Thomas Bruederli 728e6ffb69 Don't override argument variable when collecting results 10 years ago
Aleksander Machniak 871a26d328 Merge branch 'release-1.0' of github.com:roundcube/roundcubemail into release-1.0 10 years ago
Aleksander Machniak 1dafdff79a Fix call to a member function get_compressed() on a non-object 10 years ago
Aleksander Machniak 25207f5a65 Fix error in MSSQL update script 2013061000.sql (#1490061) 10 years ago
Aleksander Machniak 574f416076 Fix merging folder annotations for folders with numeric names (only digits) 10 years ago
Aleksander Machniak 3b55da7ba6 Add config option to specify IMAP connection socket parameters - imap_conn_options (#1489948)
Conflicts:
	CHANGELOG
10 years ago
Aleksander Machniak 4922ebda5c Fix PERMANENTFLAGS checking in modFlag() 10 years ago
Aleksander Machniak 847f5b9a77 Fix comm_path update on task switch (#1490041) 10 years ago
Aleksander Machniak dbf70cc7db Fix handling of email addresses with quoted domain part (#1490040) 10 years ago
Aleksander Machniak e6f21118b8 Fix contacts list update after adding/deleting/moving a contact (#1490028, #1490033) 10 years ago
Thomas Bruederli 2d284df861 Don't read attachment contents from cache when downloading. Cache might have line endings converted 10 years ago
Aleksander Machniak ef4e6b9aed Cleanup after PR merge, updated changelog 10 years ago
brendan braybrook 7cf6524590 changes suggested by aleks 10 years ago
brendan braybrook 9cbdb6cd69 rotate image with GD if exit rotation data present 10 years ago
brendan braybrook eff2a2768d wrong type returned for gif 10 years ago
Aleksander Machniak a1bb59d601 Add support for groups 10 years ago
Aleksander Machniak dddb9dee61 Fix errors when adding/updating contacts in active search (#1490015) 10 years ago
Aleksander Machniak f5f056e7f2 Fix default vacation status (#1490019) - improve error message
Conflicts:

	plugins/managesieve/Changelog
10 years ago
Aleksander Machniak 8d4b4897df Fix invalid Content-Type header when send_format_flowed=false (#1489992) 10 years ago
Aleksander Machniak 1fac787d2c Fix various iCloud vCard issues, added fallback for external photos (#1489993)
Conflicts:

	program/steps/addressbook/func.inc
10 years ago
Aleksander Machniak d1749659d2 Backported option to set default message list mode - default_list_mode (#1487312) 10 years ago
Aleksander Machniak 057444bd41 Fix bug where $Forwarded flag was being set even if server didn't support it (#1490000) 10 years ago
Aleksander Machniak 5d92a6540a Fix missing css/js scripts in filter form in mail task
Conflicts:

	plugins/managesieve/Changelog
10 years ago
Thomas Bruederli 39bd9b8e29 Set 'compose_extwin' env property on every step; accept a list of URL parameters for the 'compose' command 10 years ago
Aleksander Machniak 835638037a Fix errors when using localStorage in Safari's private browsing mode (#1489996)
Conflicts:

	program/js/app.js
10 years ago
Aleksander Machniak b78ecabaa1 Enable contextmenu plugin for TinyMCE editor (#1487014) 10 years ago
Aleksander Machniak 9cf50d16d4 Fix some mime-type to extension mapping checks in Installer (#1489983)
Conflicts:

	CHANGELOG
10 years ago
Aleksander Machniak ae502b364d Use jQuery.each instead of "for (i in Array)" (#1489988)
Conflicts:

	program/js/app.js
10 years ago
Thomas Bruederli 7515a28ee9 Update Changelog and bump version 10 years ago
Thomas Bruederli d461ae0e8a Iterate over all drafts saved in localStorage when asking for restoring. Delege/Ignore buttons will display the next item, if any 10 years ago
Thomas Bruederli 007f1b4438 Warn for unsent/unsaved message when closing compose window; remove localStorage copy if page was left intentionally but not on session errors (#1489818) 10 years ago
Thomas Bruederli 29723da95b Merge branch 'release-1.0' of github.com:roundcube/roundcubemail into release-1.0 10 years ago
Thomas Bruederli 60eba5df3a Add title attribute for skins/modes hiding the actual button text 10 years ago
Aleksander Machniak eef107be30 Fix a.deletebutton outline (#1489929) 10 years ago
Aleksander Machniak a8282f1359 Fix sorting messages by size on servers without SORT capability (#1489981) 10 years ago
Thomas Bruederli 86fe5378ae Don't override background color 10 years ago
Thomas Bruederli 5a3f8636ec Fix displaying error messages without timeout 10 years ago
Aleksander Machniak d323e30a57 Revert "Fix bug where compose storage wasn't cleared on page unload (#1489818)"
This reverts commit 8437d76389.
10 years ago
Aleksander Machniak 8437d76389 Fix bug where compose storage wasn't cleared on page unload (#1489818) 10 years ago
Aleksander Machniak 118a170dbc Fix images import from various vCard formats (#1489977) 10 years ago
Aleksander Machniak 224278cc4d Fix bug where contacts with no email address were listed on compose addressbook (#1489970) 10 years ago
Aleksander Machniak bda3e7d239 - Fix Delete button state after deleting identity/response (#1489972) 10 years ago
Aleksander Machniak 7152d0fdef Fix security issue in delete-response action - allow only ajax request.
Unify code for identities and responses deletion.

Conflicts:

	program/steps/settings/func.inc
10 years ago
Aleksander Machniak c627d3bb02 Fix incorrect label translation in return receipt (#1489963) 10 years ago
Aleksander Machniak 2a700d7c00 Allow anonymous LDAP searches 10 years ago
Aleksander Machniak 64ce35e2a9 Fix bug where non-existing (or unsubscribed) folder wasn't listed in folder selector (#1489956) 10 years ago
Aleksander Machniak db2c1a53cb Fix so address format errors are ignored when saving a draft (#1489954) 10 years ago
Aleksander Machniak a862e9996b Fix redundant horizontal scrollbar in HTML editor (#1489950) 10 years ago
Aleksander Machniak 702ce09f89 Add notes about messages_cache setting requirements (#1489946) 10 years ago
Aleksander Machniak ee83a48d04 Fix list reload after sending message in another window (#1489931) - use checkmail instead of list command 10 years ago
Aleksander Machniak 4162430a43 Fix malformed recipient name when composing a message by clicking on mailto link (#1489942) 10 years ago
Aleksander Machniak f105dbb769 Fix PHP error in Preferences when default_folders was in dont_override (#1489940) 10 years ago
Aleksander Machniak 0a5088758e Fix "PHP Fatal error: Cannot break/continue 1 level" when ldap_start_tls() fails 10 years ago
Aleksander Machniak 53df26f447 Fixed Save button in classic skin of Vacation interface (#1489926) 10 years ago
Aleksander Machniak bbce9f5a2e Fix so message list and counters are updated when a message is opened in new window (#1489919) 10 years ago
corbosman 04089eed1c add preferences_section_header hook 10 years ago
Aleksander Machniak abb405ab5b Support csv contacts import in German localization (#1489920) 10 years ago
Aleksander Machniak d4df56557a Update changelog 10 years ago
Aleksander Machniak dbd5c18471 Fix broken normalize_string(), add support for ISO-8859-2 10 years ago
Aleksander Machniak 4f3f85da39 Add more tests for normalize_string() - some failing 10 years ago
Aleksander Machniak 49e260ba58 Fix unintentional line-height style modification in HTML messages (#1489917) 10 years ago
Aleksander Machniak 599434f770 Fix so responses menu hides on click in classic skin (#1489915) 10 years ago
Aleksander Machniak ec62e8a7ee Silence PHP Warning: strtolower() expects parameter 1 to be string 10 years ago
Aleksander Machniak 2911ca3e96 Silence possible PHP Warning: file_exists(): open_basedir restriction in effect. 10 years ago
Aleksander Machniak 8b93fc9284 Use POST for refresh/check-recent request
Conflicts:

	program/steps/mail/check_recent.inc
10 years ago
Aleksander Machniak 54b4790fcd Fix so current page is reset on list-mode change (#1489907)
Conflicts:

	program/steps/mail/func.inc
10 years ago
Aleksander Machniak 2d233bf49c Fix incorrect handling of HTML comments in messages sanitization code (#1489904) 10 years ago
Aleksander Machniak 5c8e60d45d Fix handling unicode characters in links (#1489898) 10 years ago
Aleksander Machniak c9feba8917 Fix malformed References: header in send/saved mail (#1489891) - update Mail_mime to 1.8.9 version 10 years ago
Aleksander Machniak 70ba547d10 Fix unintentional draft autosave request if autosave is disabled (#1489882)
Conflicts:

	CHANGELOG
10 years ago
Aleksander Machniak f92cccac38 Add configurable LDAP_OPT_DEREF option (#1489864) - patch from Stuart C. Naifeh
Conflicts:

	CHANGELOG
10 years ago
Thomas Bruederli 0b70f509fc Declare LOGIN commands to be anonymized in debug logging 10 years ago
Thomas Bruederli 0d9ccfd8f7 Don't EVER log passwords 10 years ago
Thomas Bruederli c94971bc6f Update copyright year in about template 10 years ago
Thomas Bruederli e4d87a07b7 Bump version for 1.0.1 10 years ago
Aleksander Machniak 16ce146d88 Fix IMAP connection test in installer so it is aware of imap_auth_type (#1489746) 10 years ago
Aleksander Machniak 9b0173c881 Improve spellcheck_engine hint about 'googie' option 10 years ago
Aleksander Machniak ac828b735b Support identities_level=4 in Installer 10 years ago
Aleksander Machniak 4765b261f8 Add all possible options in spellcheck_engine selector 10 years ago
Aleksander Machniak a88f241250 Ignore words containing only <> chars 10 years ago
Aleksander Machniak b5beb1888f Fix unwanted horizontal scrollbar in spellcheck languages list in Chrome browser 10 years ago
Aleksander Machniak 80acbd62df Replace setSelectionRange() call with universal rcmail.set_caret_pos() 10 years ago
Aleksander Machniak 2ff8b45c48 Add changelog line removed by mistake in last commit 10 years ago
Aleksander Machniak 8b5d16d30a Support 'error' and 'body_file' return attribs in 'message_before_send' hook (#1489595)
Conflicts:

	CHANGELOG
10 years ago
Aleksander Machniak 34e6526c95 Fix invalid host validation on login (#1489841) 10 years ago
Aleksander Machniak 50fee948fd Fix redundant warning when switching from html to text in empty editor (#1489819)
We also skip ajax request in such a case. We assume "empty" here means "with no text excluding whitespace".

Conflicts:

	program/js/app.js
10 years ago
Aleksander Machniak 08953a46d9 Fix too small length of users.preferences column data type on MySQL 10 years ago
Aleksander Machniak 720e7d376f Fix varius db_prefix issues (#1489839)
- Move DDL script execution code to rcube_db class(es).
- Improve prefix replacement code, so index names are also modified
10 years ago
Aleksander Machniak 7e3af82c4f Add splitter in Settings > Responses 10 years ago
Aleksander Machniak f25f6cde39 Fix identities_level=4 handling in new_user_dialog plugin (#1489840) 10 years ago
Aleksander Machniak cbd5388d2e Make sure mbstring susbtitute character is set to empty string in rcube_charset::clean() 10 years ago
Thomas Bruederli e947955367 Accept broken vcards from Outlook that only supply ORG but not the required N or FN properties 10 years ago
Felix Eckhofer 8a4234d2fc Fix typo in comment 10 years ago
Felix Eckhofer f58a294949 Add config variable 'proxy_whitelist'
HTTP headers X_FORWARDED_* and X_REAL_IP are only evaluated when
received from an IP listed in proxy_whitelist. Furthermore, only the
last non-trusted IP from X-Forwarded-For is used in place of the real
ip.

Without this, an attacker can easily spoof the headers and control the
result of the ip or ssl check.

This fixes several problems with [3a4c9f42], [4d480b36] and [a520f331] as
mentioned in #1489729.

Conflicts:
	CHANGELOG
10 years ago
Felix Eckhofer d71a711ab0 Remove usage of $RCMAIL global variable 10 years ago
Thomas Bruederli c3c4842c5f Update changelog 10 years ago
Thomas Bruederli 6c7452d667 Avoid popupmenus being closed when scrollbar is clicked (#1489832) 10 years ago
Aleksander Machniak 7fface125e Fix error when spell-checking an empty text (#1489831) 10 years ago
Aleksander Machniak 115ba30dcd Fix possibly wrong error message when contact with the same email exists on move/copy 10 years ago
Aleksander Machniak e965185265 Fixed notify/enotify extension handling 10 years ago
Aleksander Machniak 0f820efd6a Update changelog 10 years ago
Aleksander Machniak adeee1455c email:main -> email:pref 10 years ago
Aleksander Machniak 847e7548d5 Fix missing Mail-Followup-To header in sent mail (#1489829) 10 years ago
Aleksander Machniak 293d61b16f Fix so browser capabilities check is done really only once a session
Conflicts:

	program/steps/mail/func.inc
10 years ago
Aleksander Machniak 437c0dadd0 Set register_globals=off in .htaccess file and add note to INSTALL 10 years ago
Aleksander Machniak a70234f375 Add _mbox argument to headers action URL 10 years ago
Aleksander Machniak 36a154e934 Fix next message display after removing a message (#1489800) 10 years ago
Aleksander Machniak e1e65c4980 Fix redundant alert message on over-size uploads (#1489817) 10 years ago
Aleksander Machniak 701d7a369b Fix compat. with PHP 5.2. (#1489813) 10 years ago
Aleksander Machniak ee3dd89c04 Fix invalid and infinite redirect for unsupported browsers
Conflicts:

	program/js/app.js
10 years ago
Aleksander Machniak 3a04a3d710 Fix regression where title attribute for long message subjects wasn't used on IE
Conflicts:

	program/js/app.js
10 years ago
Aleksander Machniak ef925bb49c Fix invalid page title for some folders (1489804) 10 years ago
Aleksander Machniak fd309c3650 Fix XSS issue in plain text spellchecker (#1489806) 10 years ago
Aleksander Machniak f4bd85b8d0 Fix disabled create filter action 10 years ago
Aleksander Machniak 4c7daf5cea Fix lack of translation of special folders in some configurations (#1489799) 10 years ago
Aleksander Machniak d9588ff228 Fix messages index cache update under some conditions (e.g. proxy) (#1489756) 10 years ago
Aleksander Machniak 7e3b5ef8f3 Update changelog 10 years ago
Aleksander Machniak 05d419a340 Fix "washing" of unicoded style attributes (#1489777)
Conflicts:

	tests/Framework/Washtml.php
10 years ago
Thomas Bruederli dbe4eff8d2 Avoid unexpected redirects to inbox after auto-saving a draft (#1489789) 10 years ago
Thomas Bruederli 59d7f87a05 Update Changelog 10 years ago
Thomas Bruederli 0268829299 Append group parameter to attachments set by plugins if not present 10 years ago
Thomas Bruederli d61731e1a3 Foward locking parameter 10 years ago
Aleksander Machniak 5381636fc4 Make sure preformance info logged in devel_mode uses locale-independent number format 10 years ago
Thomas Bruederli 8d956fd455 Apply user-spefici replacements to group's base_dn property (#1489779) 10 years ago
Aleksander Machniak c7357ea320 Merge branch 'release-1.0' of github.com:roundcube/roundcubemail into release-1.0 10 years ago
Aleksander Machniak d22d119e38 Fix compatibility with PHP 5.2 10 years ago
Aleksander Machniak 7a6dd9ad84 Hide PHP Warning: substr_compare() The length cannot exceed initial string length 10 years ago
Aleksander Machniak ceff79b14a Fix bug where "With attachment" option in search filter wasn't selected after return from mail view (#1489774)
Conflicts:

	CHANGELOG
10 years ago
Aleksander Machniak 7883ecb8ec Fix again xdebug.max_nesting_level limit handling (#1489110) 10 years ago
Aleksander Machniak 92e81cbf22 Improve error message on failed http connection 10 years ago
Aleksander Machniak 4044be4f19 Fix list-input fields in Vacation interface 10 years ago
Aleksander Machniak fda13f337c Remove debug code 10 years ago
Aleksander Machniak 390eacc2af Added optional separate interface for out-of-office management (#1488266) 10 years ago
Thomas Bruederli 2f43fe94cb Implement ArrayAccess interface for conveniently accessing rcube_result_set as array 10 years ago
Thomas Bruederli 56be9c50ea Allow to force-load plugins which have been loaded but not initialized before 10 years ago
Thomas Bruederli de3c333f4e Don't trigger 'select' event twice when selecting a list item 10 years ago
Thomas Bruederli 548b0ddee9 Replace &nbsp; entities when converting to text 10 years ago
Thomas Bruederli 3138879ddb Improve mbox format import: don't expect empty lines after each message 10 years ago
Aleksander Machniak 677fb747c1 Fix fatal error in database_attachments plugin under some conditions (#1489726)
Conflicts:

	CHANGELOG
10 years ago
Aleksander Machniak 5fefe78f75 Make sure parent folder selector always contains parent folder
of current folder, even if it does not exist
10 years ago
Thomas Bruederli eb9c51018d Update Changelog and bump version to 1.0.0 10 years ago
Thomas Bruederli 5934e23824 Disable link registering mailto: protocol handler if not supported by the browser (#1489569) 10 years ago
Thomas Bruederli e5bb1357a5 Synchrnonized translations from Transifex 10 years ago
Thomas Bruederli ab8bad44d0 Map fr => fr_FR for transifex pulling 10 years ago
Thomas Bruederli b7f95b7efe Don't hide upload dialog if no file was selected. Display an alert message for all empty file uploads (#1489685) 10 years ago
Aleksander Machniak 920322a609 Trim search filter to prevent from creating invalid search criteria when skip_deleted = true. 10 years ago
Thomas Bruederli 39d3ab17aa Update changelog 10 years ago
Thomas Bruederli 8d3b27b9e8 Fix message import dialog (#1489685):
- Display alert if no file is chosen
- Unlock the UI if form is not submitted
- Avoid duplicate error messages
- Fix javascript error due to missing attachments list widget
10 years ago
Aleksander Machniak f4564ae20d Add labels for 'n' ACL (RFC 5257) 10 years ago
Aleksander Machniak 70eafd53c6 Make sure attachment ID is really unique when uploading multiple files (#1489546) 10 years ago
Aleksander Machniak b23f2007a3 Add id for login submit button (#1489676) - make it skin independent 10 years ago
Thomas Bruederli 1394025bdf Re-arrange buttons in import dialog to match the rest of the appplication 10 years ago
Thomas Bruederli 238c6a0f55 Fix input-button disabled state; add support for jquery UI buttons of type 'uibutton' 10 years ago
Thomas Bruederli 5ba53819cf Revert "Support structured data for autocompletion results; map 'type' attribute to CSS class for autocomplete list items"
This reverts commit e3773d46cb.
10 years ago
Thomas Bruederli 881d6b0375 Revert "Implement ArrayAccess interface for conveniently accessing rcube_result_set as array"
This reverts commit a7d68eaf1a.
10 years ago
Thomas Bruederli e3773d46cb Support structured data for autocompletion results; map 'type' attribute to CSS class for autocomplete list items 10 years ago
Thomas Bruederli a7d68eaf1a Implement ArrayAccess interface for conveniently accessing rcube_result_set as array 10 years ago
Aleksander Machniak 3505d57641 Fix dbmail driver (hints from https://github.com/roundcube/roundcubemail/pull/169) 10 years ago
Takika 4b859649ea Fix default mailbox sort order 10 years ago
Thomas Bruederli 0b1bb84799 Updated Changelog 10 years ago
Thomas Bruederli 66c2ff9e1a Fix opening compose screen in new window after saving as draft (#1489643) 10 years ago
Aleksander Machniak 1edb6bbc25 Fix filter creation from an email when preview frame is disabled (#1489647) 10 years ago
Aleksander Machniak 1c715f79b4 Fix some PDO::MYSQL_* constants (wrongly described in PHP manual before 5.3.21) 10 years ago
Aleksander Machniak 55d9d5e0b7 Improvement in handling invalid email address strings 10 years ago
Thomas Bruederli 5f5174e3b5 Suppress IE's default behavior of opening links in a new tab on ctrl-click by wrapping the clickable content in <span> tag 10 years ago
Aleksander Machniak 7f28120768 Prevent from "Call to undefined method rcmail_output_json::add_footer()" error 10 years ago
Aleksander Machniak 6345f34565 Fix issue where msgexport.sh printed the message to STDOUT instead of a file (#1489634) 10 years ago
Aleksander Machniak a16cbb204e Fix regression in handling of 'attachments' result in message_compose hook (#1489627) 10 years ago
Aleksander Machniak 7c61ba4953 Fix wrong action folder selection if managesieve_domains is not empty (#1489617) 10 years ago
Aleksander Machniak ef76ce576c Bump version number 10 years ago
Aleksander Machniak ce57ca8c5e Fix issue in displaying filter form when managesieve_kolab_master=true
and sieve variables extension is supported by the server (#1489599)
10 years ago
Thomas Bruederli dd34e478b3 Update toolbar buttons sprite with new move icon 10 years ago
Thomas Bruederli e7bcd945bd Re-locate the move-message toolbar button to be next to the related delete icon; synchronize toolbars in larry and classic skin 10 years ago
Aleksander Machniak a4cd91f6b2 Added tests for html::attrib_string() method 10 years ago
Aleksander Machniak 59865f3259 Added toolbar button to move message in message view
Conflicts:

	CHANGELOG
10 years ago
Till Krüss dc52ae0b02 prevent unwanted code execution via CURLOPT_POSTFIELDS (again) 10 years ago
Aleksander Machniak 6f079094d2 Fix issue where multi-select fields were not visible in new filter action rows (#1489600) 10 years ago
Aleksander Machniak 21f6f468d6 Fix issue where folder selector wasn't visible on new filter form 10 years ago
Thomas Bruederli ce29296fa9 Update env in main window for ACL dialog autocompletion (#1489594) 10 years ago
Aleksander Machniak e089c5adc8 Fix invalid X-Draft-Info on forwarded message draft (#1489587) 10 years ago
Aleksander Machniak c4c3e7822d Update changelog 10 years ago
Till Krüss 01014a20b9 prevent unwanted code execution via CURLOPT_POSTFIELDS 10 years ago
Aleksander Machniak 6fdf1f2072 Add more tests for framework classes 10 years ago
Aleksander Machniak 4bcb8ac002 Add dummy tests for rcube_spellcheck_* classes 10 years ago
Aleksander Machniak f130f9116e Fix directories check in Installer on Windows (#1489576)
Added rcube_utils::is_absolute_path() method
10 years ago
Aleksander Machniak 8c32f88193 Fixed typo in script output 10 years ago
Aleksander Machniak b37954110d Bring back unit tests (they should be removed when creating a package) 10 years ago
Aleksander Machniak e445e0acb5 Fix possible javascript error on drag-n-drop (#1489560) 10 years ago
Thomas Bruederli 92eb72dafc Hide autocompletion results when closing ACL dialog; use default table styles 10 years ago
Aleksander Machniak af15c60f88 Fix issue when default_addressbook option is set to integer value (#1489407) 10 years ago
Thomas Bruederli f8a57ebd94 Use standard dialog popups for the ACL permissions form; that will open it in the main window with enoough space and better UI integration 10 years ago
Thomas Bruederli 63eae4a196 Forward all arguments of the function call 10 years ago
Thomas Bruederli d3583f0c0e Fix some glitches in ACL table display 10 years ago
Thomas Bruederli a7d42915a4 Fix infinite loop when converting invalid html to plaintext (#1489566) 10 years ago
Aleksander Machniak bd3f5745f0 Fixed Opera > 15 detection (#1489562)
Conflicts:

	tests/Framework/Browser.php
10 years ago
Aleksander Machniak 59373ce9cd Add missing box-shadow style (#1489556) 10 years ago
Aleksander Machniak c0d8ec001b Fix bug where it wasn't possible to focus the messages list with
mouse click on a record after the focus was put on preview frame.
10 years ago
Thomas Bruederli 50217a9eb5 Point to the new public URI for online help 10 years ago
Thomas Bruederli 8c893b79d2 Branching off for release 1.0 10 years ago

@ -1,30 +0,0 @@
<?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';

@ -1,22 +0,0 @@
#!/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

@ -1,25 +0,0 @@
#!/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

@ -1,30 +0,0 @@
#!/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

8
.gitignore vendored

@ -13,11 +13,3 @@ composer.json
composer.phar
composer.lock
vendor
# javascript dependencies
plugins/enigma/openpgp.min.js
plugins/managesieve/codemirror/
program/js/jquery.min.js
program/js/jstz.min.js
program/js/publickey.js
program/js/tinymce/

@ -1,24 +1,52 @@
# This is a sample with suggested security and performance options
# AddDefaultCharset UTF-8
AddType text/x-component .htc
<IfModule mod_php5.c>
php_flag display_errors Off
php_flag log_errors On
# php_value error_log logs/errors
php_value upload_max_filesize 5M
php_value post_max_size 6M
php_value memory_limit 64M
php_flag register_globals Off
php_flag zlib.output_compression Off
php_flag magic_quotes_gpc Off
php_flag magic_quotes_runtime Off
php_flag zend.ze1_compatibility_mode Off
php_flag suhosin.session.encrypt Off
#php_value session.cookie_path /
php_flag session.auto_start Off
php_value session.gc_maxlifetime 21600
php_value session.gc_divisor 500
php_value session.gc_probability 1
</IfModule>
<IfModule mod_rewrite.c>
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteRule ^favicon\.ico$ skins/larry/images/favicon.ico
# security rules:
# - deny access to files not containing a dot or starting with a dot
# in all locations except installer directory
RewriteRule ^(?!installer|\.well-known\/|[a-zA-Z0-9]{16})(\.?[^\.]+)$ - [F]
RewriteRule ^(?!installer|\.well-known\/)(\.?[^\.]+)$ - [F]
# - deny access to some locations
RewriteRule ^/?(\.git|\.tx|SQL|bin|config|logs|temp|tests|vendor|program\/(include|lib|localization|steps)) - [F]
RewriteRule ^/?(\.git|\.tx|SQL|bin|config|logs|temp|tests|program\/(include|lib|localization|steps)) - [F]
# - deny access to some documentation files
RewriteRule /?(README.*|meta\.json|composer\..*|jsdeps.json)$ - [F]
RewriteRule /?(README\.md|composer\.json-dist|composer\.json|package\.xml)$ - [F]
</IfModule>
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
</IfModule>
<IfModule mod_headers.c>
# replace 'append' with 'merge' for Apache version 2.2.9 and later
#Header append Cache-Control public env=!NO_CACHE
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month"
@ -28,42 +56,4 @@ FileETag MTime Size
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>
<IfModule mod_headers.c>
# Disable page indexing
Header set X-Robots-Tag "noindex, nofollow"
# replace 'merge' with 'append' for Apache < 2.2.9
#Header merge Cache-Control public env=!NO_CACHE
# Optional security headers
# Only provides increased security if the browser supports those features
# Be careful! Testing is required! They should be adjusted to your installation / user environment
# HSTS - HTTP Strict Transport Security
#Header always set Strict-Transport-Security "max-age=31536000; preload" env=HTTPS
# HPKP - HTTP Public Key Pinning
# Only template - fill with your values
#Header always set Public-Key-Pins "max-age=3600; report-uri=\"\"; pin-sha256=\"\"; pin-sha256=\"\"" env=HTTPS
# X-Xss-Protection
# This header is used to configure the built in reflective XSS protection found in Internet Explorer, Chrome and Safari (Webkit).
#Header set X-XSS-Protection "1; mode=block"
# X-Frame-Options
# The X-Frame-Options header (RFC), or XFO header, protects your visitors against clickjacking attacks
# Already set by php code! Do not activate both options
#Header set X-Frame-Options SAMEORIGIN
# X-Content-Type-Options
# It prevents Google Chrome and Internet Explorer from trying to mime-sniff the content-type of a response away from the one being declared by the server.
#Header set X-Content-Type-Options: "nosniff"
# CSP - Content Security Policy
# for better privacy/security ask browsers to not set the Referer
# more flags for script, stylesheets and images available, read RFC for more information
# Note: "Referrer-Policy: same-origin" is already set by php code.
#Header set Content-Security-Policy "referrer no-referrer"
</IfModule>
</ifModule>

@ -1,37 +0,0 @@
language: php
dist: trusty #
sudo: false
matrix:
fast_finish: true
include:
- php: 5.4
- php: 5.5
- php: 5.6
- php: 7.0
- php: 7.1
env: CODE_COVERAGE=1
- php: 7.2
- php: 7.3
dist: bionic # for proper node-less version
env: BROWSER_TESTS=1
addons:
chrome: stable
apt:
packages:
- node-less
- php: 7.4
cache:
directories:
- $HOME/.composer
install:
- .ci/install.sh
script:
- .ci/run.sh
notifications:
email: false

@ -13,11 +13,6 @@ file_filter = program/localization/<lang>/messages.inc
source_file = program/localization/en_US/messages.inc
source_lang = en_US
[roundcube-webmail.timezones]
file_filter = program/localization/<lang>/timezones.inc
source_file = program/localization/en_US/timezones.inc
source_lang = en_US
[roundcube-webmail.plugin-acl]
file_filter = plugins/acl/localization/<lang>.inc
source_file = plugins/acl/localization/en_US.inc
@ -33,16 +28,6 @@ file_filter = plugins/attachment_reminder/localization/<lang>.inc
source_file = plugins/attachment_reminder/localization/en_US.inc
source_lang = en_US
[roundcube-webmail.plugin-emoticons]
file_filter = plugins/emoticons/localization/<lang>.inc
source_file = plugins/emoticons/localization/en_US.inc
source_lang = en_US
[roundcube-webmail.plugin-enigma]
file_filter = plugins/enigma/localization/<lang>.inc
source_file = plugins/enigma/localization/en_US.inc
source_lang = en_US
[roundcube-webmail.plugin-help]
file_filter = plugins/help/localization/<lang>.inc
source_file = plugins/help/localization/en_US.inc
@ -97,3 +82,4 @@ source_lang = en_US
file_filter = plugins/zipdownload/localization/<lang>.inc
source_file = plugins/zipdownload/localization/en_US.inc
source_lang = en_US

File diff suppressed because it is too large Load Diff

@ -3,104 +3,79 @@ INTRODUCTION
This file describes the basic steps to install Roundcube Webmail on your
web server. For additional information, please also consult the project's
wiki page at https://github.com/roundcube/roundcubemail/wiki
wiki page at http://trac.roundcube.net/wiki
REQUIREMENTS
============
* An IMAP, HTTP and SMTP server
* The Apache, Lighttpd, Cherokee or Hiawatha web server
* .htaccess support allowing overrides for DirectoryIndex
* PHP Version 5.4 or greater including:
- PCRE, DOM, JSON, Session, Sockets, OpenSSL, Mbstring, Filter, Ctype (required)
- PHP PDO with driver for either MySQL, PostgreSQL, SQL Server, Oracle or SQLite (required)
- Zip, Fileinfo, Intl, Exif (recommended)
- LDAP for LDAP addressbook support (optional)
- GD, Imagick (optional thumbnails generation, QR-code)
* PEAR and PEAR packages distributed with Roundcube or external:
- Mail_Mime 1.10.0 or newer
- Net_SMTP 1.8.1 or newer
- Net_Socket 1.0.12 or newer
* PHP Version 5.2.1 or greater including
- PCRE, DOM, JSON, XML, Session, Sockets (required)
- PHP Data Objects (PDO) with driver for either MySQL, PostgreSQL or SQLite (required)
Note: MySQL database driver requires PHP 5.3.7 or newer.
- Libiconv, Zip (recommended)
- Fileinfo, Mcrypt, mbstring (optional)
* PEAR packages distributed with Roundcube or external:
- Mail_Mime 1.8.1 or newer
- Net_SMTP (latest from https://github.com/pear/Net_SMTP/)
- Net_IDNA2 0.1.1 or newer
- Auth_SASL 1.0.6 or newer
- Net_Sieve 1.4.3 or newer (for managesieve plugin)
- Crypt_GPG 1.6.3 or newer (for enigma plugin)
- Endroid/QrCode 1.6.0 or newer (https://github.com/endroid/QrCode)
- Kolab/Net_LDAP3 1.0.6 or newer (for LDAP addressbook)
- Masterminds/HTML5 2.5.x (optional HTML parser)
* php.ini options:
- error_reporting E_ALL & ~E_NOTICE & ~E_STRICT
- memory_limit > 16MB
- file_uploads enabled (for uploading attachments and import files)
- Net_Sieve 1.3.2 or newer (for managesieve plugin)
- Crypt_GPG 1.2.0 or newer (for enigma plugin)
* php.ini options (see .htaccess file):
- error_reporting E_ALL & ~E_NOTICE (or lower)
- memory_limit > 16MB (increase as suitable to support large attachments)
- file_uploads enabled (for attachment upload features)
- session.auto_start disabled
- zend.ze1_compatibility_mode disabled
- suhosin.session.encrypt disabled
- mbstring.func_overload disabled
- pcre.backtrack_limit >= 100000
* A MySQL, PostgreSQL, MS SQL Server (2005 or newer), Oracle database
or SQLite support in PHP - with permission to create tables
* Composer installed either locally or globally (https://getcomposer.org)
- magic_quotes_runtime disabled
- magic_quotes_sybase disabled
- register_globals disabled (PHP < 5.4)
* PHP compiled with OpenSSL to connect to IMAPS and to use the spell checker
* A MySQL (4.0.8 or newer), PostgreSQL, MS SQL Server (2005 or newer) database engine
or SQLite support in PHP
* One of the above databases with permission to create tables
* An SMTP server (recommended) or PHP configured for mail delivery
INSTALLATION
============
1. Decompress and put this folder somewhere inside your document root.
Note: Make sure files have proper owner/group for your setup. If you use
tar command `--no-same-owner` option might be helpful.
2. In case you don't use the so-called "complete" release package,
you have to install PHP and javascript dependencies.
2.1. Install PHP dependencies using composer:
- get composer from https://getcomposer.org/download/
- rename the composer.json-dist file into composer.json
- if you want to use LDAP address books, enable the LDAP libraries in your
composer.json file by moving the items from "suggest" to the "require"
section (remove the explanation texts after the version!).
- run `php composer.phar install --no-dev`
2.2. Install Javascript dependencies by executing `bin/install-jsdeps.sh` script.
3. Make sure that the following directories (and the files within)
1. Decompress and put this folder somewhere inside your document root
2. Make sure that the following directories (and the files within)
are writable by the webserver
- /temp
- /logs
4. Create a new database and a database user for Roundcube (see DATABASE SETUP)
5. Point your browser to http://url-to-roundcube/installer/
6. Follow the instructions of the install script (or see MANUAL CONFIGURATION)
7. After creating and testing the configuration, remove the installer directory
------------------------------------------
IMPORTANT: REMOVE THE INSTALLER DIRECTORY!
------------------------------------------
8. If you use git sources compile css files for the Elastic skin (required
lessc >= 1.5.0):
$ cd skins/elastic
$ lessc -x styles/styles.less > styles/styles.css
$ lessc -x styles/print.less > styles/print.css
$ lessc -x styles/embed.less > styles/embed.css
9. Check Known Issues section of this file
3. Create a new database and a database user for Roundcube (see DATABASE SETUP)
4. Point your browser to http://url-to-roundcube/installer/
5. Follow the instructions of the install script (or see MANUAL CONFIGURATION)
6. After creating and testing the configuration, remove the installer directory
7. Check Known Issues section of this file
8. Done!
CONFIGURATION HINTS
===================
IMPORTANT! Read all comments in defaults.inc.php, understand them
and configure your installation to be not surprised by default behaviour.
Roundcube writes internal errors to the 'errors.log' log file located in the logs
Roundcube writes internal errors to the 'errors' log file located in the logs
directory which can be configured in config/config.inc.php. If you want ordinary
PHP errors to be logged there as well, set error_log in php.ini or .htaccess file.
Roundcube forces display_errors=Off and log_errors=On.
PHP errors to be logged there as well, enable the 'php_value error_log' line
in the .htaccess file and set the path to the log file accordingly.
By default the session cookie settings of PHP are not modified by Roundcube.
By default the session_path settings of PHP are not modified by Roundcube.
However if you want to limit the session cookies to the directory where
Roundcube resides you can set session.cookie_path in the php.ini or .htaccess file.
More about PHP settings: https://github.com/roundcube/roundcubemail/wiki/Installation#php-configuration
Roundcube resides you can uncomment and configure the according line
in the .htaccess file.
DATABASE SETUP
==============
Note: Database for Roundcube must use UTF-8 character set.
Note: See defaults.inc.php file for examples of DSN configuration.
* MySQL
-------
@ -109,9 +84,9 @@ importing the table layout and granting the proper permissions to the
roundcube user. Here is an example of that procedure:
# mysql
> CREATE DATABASE roundcubemail CHARACTER SET utf8 COLLATE utf8_general_ci;
> CREATE USER roundcube@localhost IDENTIFIED BY 'password';
> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost;
> CREATE DATABASE roundcubemail /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost
IDENTIFIED BY 'password';
> quit
# mysql roundcubemail < SQL/mysql.initial.sql
@ -120,11 +95,6 @@ Note 1: 'password' is the master password for the roundcube user. It is strongly
recommended you replace this with a more secure password. Please keep in
mind: You need to specify this password later in 'config/db.inc.php'.
Note 2: When using MySQL < 5.7.7 or MariaDB < 10.2.2 it is required to configure
the database engine with:
innodb_large_prefix=true
innodb_file_format=Barracuda
* SQLite
--------
@ -151,7 +121,7 @@ createuser and createdb commands.
* Microsoft SQL Server
----------------------
Language/locale of the database must be set to us_english (1033). More info
on this at https://github.com/roundcube/roundcubemail/issues/4078.
on this at http://trac.roundcube.net/ticket/1488918.
Database cleaning
@ -169,42 +139,12 @@ to config/config.inc.php and make the necessary adjustments according to your
environment and your needs. More configuration options can be copied from the
config/defaults.inc.php file into your local config.inc.php file as needed.
Read the comments above the individual configuration options to find out what
they do or read https://github.com/roundcube/roundcubemail/wiki/Installation
for even more guidance.
The maximum size of email attachments and other file uploads is controlled by
PHP settings: upload_max_filesize and post_max_size. Read more about PHP
settings at https://github.com/roundcube/roundcubemail/wiki/Installation#php-configuration.
SECURE YOUR INSTALLATION
========================
Access through the webserver to the following directories should be denied:
/config
/temp
/logs
Roundcube uses .htaccess files to protect these directories, so be sure to
allow override of the Limit directives to get them taken into account. The
package also ships a .htaccess file in the root directory which defines some
rewrite rules. In order to properly secure your installation, please enable
mod_rewrite for Apache webserver and double check access to the above listed
directories and their contents is denied.
they do or read http://trac.roundcube.net/wiki/Howto_Install for even more
guidance.
NOTE: In Apache 2.4, support for .htaccess files has been disabled by
default. Therefore you first need to enable this in your Apache main or
virtual host config by with:
AllowOverride all
For non-apache web servers add equivalent configuration parameters to deny
direct access to these private resources.
It is also recommended to change the document root to <install path>/public_html
after installation if Roundcube runs at root of a dedicated virtual host. This
will automatically keep sensitive files out of reach for http requests.
You can also modify the default .htaccess file. This is necessary to
increase the allowed size of file attachments, for example:
php_value upload_max_filesize 2M
UPGRADING
@ -255,6 +195,11 @@ To enable these features in apache the following modules need to be enabled:
The optimisation is already included in the .htaccess file in the top
directory of your installation.
If you are using Apache version 2.2.9 and later, in the .htaccess file
change the 'append' word to 'merge' for a more correct response. Keeping
as 'append' shouldn't cause any problems though changing to merge will
eliminate the possibility of duplicate 'public' headers in Cache-control.
Lighttpd:
---------
With Lightty the addition of Expire: tags by mod_expire is incompatible with
@ -291,25 +236,3 @@ KNOWN ISSUES
Installations with uw-imap server should set imap_disabled_caps = array('ESEARCH')
in main configuration file. ESEARCH implementation in this server is broken (#1489184).
PHP >= 5.6 validates the ssl certificates by default. It means that
if IMAP/SMTP certificates are self-signed or use wrong host name you'll get
connection errors. A solution in such cases is to set imap_conn_options,
smtp_conn_options and managesieve_conn_options in a way described in config/defaults.inc.php.
If you have problems with temp files or non-working logs make sure temp and logs folders
are writeable to the user used by http server. Access to them may also be blocked by
SELINUX. Here's some sample commands for SELINUX:
$ semanage fcontext -a -t httpd_sys_rw_content_t "/path_to_roundcube/logs(/.*)?"
$ semanage fcontext -a -t httpd_sys_rw_content_t "/path_to_roundcube/temp(/.*)?"
$ restorecon -Rv /path_to_roundcube/
Microsoft IIS Server by default does not support WOFF fonts used in Elastic skin. It might be
needed to add following MIME Types definitions (via web.config or IIS Manager):
.woff application/font-woff
.woff2 application/font-woff2
When installing on Windows be aware we're using symbolic links which may need an additional
attention. See https://github.com/roundcube/roundcubemail/issues/7151.

@ -1,15 +1,6 @@
Roundcube Webmail
=================
[roundcube.net](https://roundcube.net)
[![Build Status](https://api.travis-ci.org/roundcube/roundcubemail.svg?branch=master)](https://travis-ci.org/roundcube/roundcubemail)
ATTENTION
---------
This is just a snapshot from the GIT repository and is **NOT A STABLE
version of Roundcube**. It's not recommended to replace an existing installation
of Roundcube with this version. Also using a separate database for this
installation is highly recommended.
[roundcube.net](http://roundcube.net)
INTRODUCTION
@ -19,11 +10,17 @@ application-like user interface. It provides full functionality you expect
from an email client, including MIME support, address book, folder management,
message searching and spell checking. Roundcube Webmail is written in PHP and
requires the MySQL, PostgreSQL or SQLite database. With its plugin API it is
easily extendable and the user interface is fully customizable using skins.
easily extendable and the user interface is fully customizable using skins
which are pure XHTML and CSS 2.
The code is mainly written in PHP and is designed to run on a webserver.
It includes other open-source classes/libraries from [PEAR][pear],
an IMAP library derived from [IlohaMail][iloha] the [TinyMCE][tinymce] rich
text editor, [Googiespell][googiespell] library for spell checking or
the [WASHTML][washtml] sanitizer by Frederic Motte.
The code designed to run on a webserver is mainly written in PHP and Javascript.
It includes a custom framework with an IMAP library derived from [IlohaMail][iloha]
and requires a set of external libraries (see composer.json and jsdeps.json files).
The current default skin uses icons designed by Stephen Horlander and [Kevin
Gerich][kmgerich] for Mozilla.org.
INSTALLATION
@ -35,19 +32,6 @@ If you're updating an older version of Roundcube please follow the steps
described in the UPGRADING file.
BROWSER SUPPORT
---------------
Roundcube uses jQuery 3.x for its client and therefore inherits the browser
support from there. This currently includes:
- Chrome: (Current - 1) and Current
- Edge: (Current - 1) and Current
- Firefox: (Current - 1) and Current, ESR
- Internet Explorer: 9+ (11+ for the Elastic skin)
- Safari: (Current - 1) and Current
- Opera: Current
LICENSE
-------
This program is free software: you can redistribute it and/or modify
@ -96,9 +80,14 @@ You're always welcome to send a message to the project admin:
hello(at)roundcube(dot)net
[iloha]: https://sourceforge.net/projects/ilohamail/
[gpl]: https://www.gnu.org/licenses/
[license]: https://roundcube.net/license
[contrib]: https://roundcube.net/contribute
[support]: https://roundcube.net/support
[pear]: http://pear.php.net
[iloha]: http://sourceforge.net/projects/ilohamail/
[tinymce]: http://www.tinymce.com/
[googiespell]: http://orangoo.com/labs/GoogieSpell/
[washtml]: http://www.ubixis.com/washtml/
[kmgerich]: http://kmgerich.com/
[gpl]: http://www.gnu.org/licenses/
[license]: http://roundcube.net/license
[contrib]: http://roundcube.net/contribute
[support]: http://roundcube.net/support
[githubissues]: https://github.com/roundcube/roundcubemail/issues

@ -1,13 +1,15 @@
CREATE TABLE [dbo].[cache] (
[user_id] [int] NOT NULL ,
[cache_key] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL ,
[cache_key] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[created] [datetime] NOT NULL ,
[expires] [datetime] NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[cache_shared] (
[cache_key] [varchar] (255) COLLATE Latin1_General_CS_AS NOT NULL ,
[cache_key] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL ,
[created] [datetime] NOT NULL ,
[expires] [datetime] NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
@ -15,7 +17,7 @@ GO
CREATE TABLE [dbo].[cache_index] (
[user_id] [int] NOT NULL ,
[mailbox] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL ,
[mailbox] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[expires] [datetime] NULL ,
[valid] [char] (1) COLLATE Latin1_General_CI_AI NOT NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL
@ -24,7 +26,7 @@ GO
CREATE TABLE [dbo].[cache_thread] (
[user_id] [int] NOT NULL ,
[mailbox] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL ,
[mailbox] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[expires] [datetime] NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
@ -32,7 +34,7 @@ GO
CREATE TABLE [dbo].[cache_messages] (
[user_id] [int] NOT NULL ,
[mailbox] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL ,
[mailbox] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[uid] [int] NOT NULL ,
[expires] [datetime] NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL ,
@ -88,6 +90,7 @@ GO
CREATE TABLE [dbo].[session] (
[sess_id] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[created] [datetime] NOT NULL ,
[changed] [datetime] NULL ,
[ip] [varchar] (40) COLLATE Latin1_General_CI_AI NOT NULL ,
[vars] [text] COLLATE Latin1_General_CI_AI NOT NULL
@ -96,20 +99,18 @@ GO
CREATE TABLE [dbo].[users] (
[user_id] [int] IDENTITY (1, 1) NOT NULL ,
[username] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL ,
[username] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[mail_host] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[created] [datetime] NOT NULL ,
[last_login] [datetime] NULL ,
[failed_login] [datetime] NULL ,
[failed_login_counter] [int] NULL ,
[language] [varchar] (16) COLLATE Latin1_General_CI_AI NULL ,
[language] [varchar] (5) COLLATE Latin1_General_CI_AI NULL ,
[preferences] [text] COLLATE Latin1_General_CI_AI NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[dictionary] (
[user_id] [int] ,
[language] [varchar] (16) COLLATE Latin1_General_CI_AI NOT NULL ,
[language] [varchar] (5) COLLATE Latin1_General_CI_AI NOT NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
@ -123,36 +124,12 @@ CREATE TABLE [dbo].[searches] (
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[filestore] (
[file_id] [int] IDENTITY (1, 1) NOT NULL ,
[user_id] [int] NOT NULL ,
[context] [varchar] (32) COLLATE Latin1_General_CI_AI NOT NULL ,
[filename] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[mtime] [int] NOT NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NULL ,
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[system] (
[name] [varchar] (64) COLLATE Latin1_General_CI_AI NOT NULL ,
[value] [text] COLLATE Latin1_General_CI_AI NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[cache] WITH NOCHECK ADD
PRIMARY KEY CLUSTERED
(
[user_id],[cache_key]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[cache_shared] WITH NOCHECK ADD
PRIMARY KEY CLUSTERED
(
[cache_key]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[cache_index] WITH NOCHECK ADD
PRIMARY KEY CLUSTERED
(
@ -223,13 +200,6 @@ ALTER TABLE [dbo].[searches] WITH NOCHECK ADD
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[filestore] WITH NOCHECK ADD
CONSTRAINT [PK_filestore_file_id] PRIMARY KEY CLUSTERED
(
[file_id]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[system] WITH NOCHECK ADD
CONSTRAINT [PK_system_name] PRIMARY KEY CLUSTERED
(
@ -239,7 +209,12 @@ GO
ALTER TABLE [dbo].[cache] ADD
CONSTRAINT [DF_cache_user_id] DEFAULT ('0') FOR [user_id],
CONSTRAINT [DF_cache_cache_key] DEFAULT ('') FOR [cache_key]
CONSTRAINT [DF_cache_cache_key] DEFAULT ('') FOR [cache_key],
CONSTRAINT [DF_cache_created] DEFAULT (getdate()) FOR [created]
GO
ALTER TABLE [dbo].[cache_shared] ADD
CONSTRAINT [DF_cache_shared_created] DEFAULT (getdate()) FOR [created]
GO
ALTER TABLE [dbo].[cache_index] ADD
@ -250,6 +225,12 @@ ALTER TABLE [dbo].[cache_messages] ADD
CONSTRAINT [DF_cache_messages_flags] DEFAULT (0) FOR [flags]
GO
CREATE INDEX [IX_cache_user_id] ON [dbo].[cache]([user_id]) ON [PRIMARY]
GO
CREATE INDEX [IX_cache_cache_key] ON [dbo].[cache]([cache_key]) ON [PRIMARY]
GO
CREATE INDEX [IX_cache_shared_cache_key] ON [dbo].[cache_shared]([cache_key]) ON [PRIMARY]
GO
@ -332,15 +313,13 @@ GO
ALTER TABLE [dbo].[session] ADD
CONSTRAINT [DF_session_sess_id] DEFAULT ('') FOR [sess_id],
CONSTRAINT [DF_session_created] DEFAULT (getdate()) FOR [created],
CONSTRAINT [DF_session_ip] DEFAULT ('') FOR [ip]
GO
CREATE INDEX [IX_session_changed] ON [dbo].[session]([changed]) ON [PRIMARY]
GO
CREATE INDEX [IX_filestore_user_id] ON [dbo].[filestore]([user_id]) ON [PRIMARY]
GO
ALTER TABLE [dbo].[users] ADD
CONSTRAINT [DF_users_username] DEFAULT ('') FOR [username],
CONSTRAINT [DF_users_mail_host] DEFAULT ('') FOR [mail_host],
@ -361,9 +340,6 @@ GO
CREATE UNIQUE INDEX [IX_searches_user_type_name] ON [dbo].[searches]([user_id],[type],[name]) ON [PRIMARY]
GO
CREATE UNIQUE INDEX [IX_filestore_user_id_context_filename] ON [dbo].[filestore]([user_id],[context],[filename]) ON [PRIMARY]
GO
ALTER TABLE [dbo].[identities] ADD CONSTRAINT [FK_identities_user_id]
FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
ON DELETE CASCADE ON UPDATE CASCADE
@ -409,11 +385,6 @@ ALTER TABLE [dbo].[searches] ADD CONSTRAINT [FK_searches_user_id]
ON DELETE CASCADE ON UPDATE CASCADE
GO
ALTER TABLE [dbo].[filestore] ADD CONSTRAINT [FK_filestore_user_id]
FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
ON DELETE CASCADE ON UPDATE CASCADE
GO
-- Use trigger instead of foreign key (#1487112)
-- "Introducing FOREIGN KEY constraint ... may cause cycles or multiple cascade paths."
CREATE TRIGGER [contact_delete_member] ON [dbo].[contacts]
@ -422,6 +393,6 @@ CREATE TRIGGER [contact_delete_member] ON [dbo].[contacts]
WHERE [contact_id] IN (SELECT [contact_id] FROM deleted)
GO
INSERT INTO [dbo].[system] ([name], [value]) VALUES ('roundcube-version', '2020020101')
INSERT INTO [dbo].[system] ([name], [value]) VALUES ('roundcube-version', '2014042900')
GO

@ -1,4 +0,0 @@
ALTER TABLE [dbo].[users] ADD [failed_login] [datetime] NULL
GO
ALTER TABLE [dbo].[users] ADD [failed_login_counter] [int] NULL
GO

@ -1,2 +0,0 @@
ALTER TABLE [dbo].[session] DROP COLUMN [created]
GO

@ -1,2 +0,0 @@
ALTER TABLE [dbo].[session] ALTER COLUMN [ip] [varchar] (40) COLLATE Latin1_General_CI_AI NOT NULL
GO

@ -1,36 +0,0 @@
DROP TABLE [dbo].[cache]
GO
DROP TABLE [dbo].[cache_shared]
GO
CREATE TABLE [dbo].[cache] (
[user_id] [int] NOT NULL ,
[cache_key] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[expires] [datetime] NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[cache_shared] (
[cache_key] [varchar] (255) COLLATE Latin1_General_CI_AI NOT NULL ,
[expires] [datetime] NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[cache] ADD
CONSTRAINT [DF_cache_user_id] DEFAULT ('0') FOR [user_id],
CONSTRAINT [DF_cache_cache_key] DEFAULT ('') FOR [cache_key],
GO
CREATE INDEX [IX_cache_expires] ON [dbo].[cache]([expires]) ON [PRIMARY]
GO
CREATE INDEX [IX_cache_shared_expires] ON [dbo].[cache_shared]([expires]) ON [PRIMARY]
GO
ALTER TABLE [dbo].[cache] WITH NOCHECK ADD
PRIMARY KEY CLUSTERED (
[user_id],[cache_key]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[cache_shared] WITH NOCHECK ADD
PRIMARY KEY CLUSTERED (
[cache_key]
) ON [PRIMARY]
GO

@ -1,24 +0,0 @@
CREATE TABLE [dbo].[filestore] (
[file_id] [int] IDENTITY (1, 1) NOT NULL ,
[user_id] [int] NOT NULL ,
[filename] [varchar] (128) COLLATE Latin1_General_CI_AI NOT NULL ,
[mtime] [int] NOT NULL ,
[data] [text] COLLATE Latin1_General_CI_AI NULL ,
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[filestore] WITH NOCHECK ADD
CONSTRAINT [PK_filestore_file_id] PRIMARY KEY CLUSTERED
(
[file_id]
) ON [PRIMARY]
GO
CREATE INDEX [IX_filestore_user_id] ON [dbo].[filestore]([user_id]) ON [PRIMARY]
GO
ALTER TABLE [dbo].[filestore] ADD CONSTRAINT [FK_filestore_user_id]
FOREIGN KEY ([user_id]) REFERENCES [dbo].[users] ([user_id])
ON DELETE CASCADE ON UPDATE CASCADE
GO

@ -1,9 +0,0 @@
ALTER TABLE [dbo].[filestore] ADD COLUMN [context] [varchar] (32) COLLATE Latin1_General_CI_AI NOT NULL
GO
UPDATE [dbo].[filestore] SET [dbo].[context] = 'enigma'
GO
CREATE UNIQUE INDEX [IX_filestore_user_id_context_filename] ON [dbo].[filestore]([user_id],[context],[filename]) ON [PRIMARY]
GO

@ -1,18 +0,0 @@
ALTER TABLE [dbo].[cache] ALTER COLUMN
[cache_key] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
GO
ALTER TABLE [dbo].[cache_shared] ALTER COLUMN
[cache_key] [varchar] (255) COLLATE Latin1_General_CS_AS NOT NULL
GO
ALTER TABLE [dbo].[cache_index] ALTER COLUMN
[mailbox] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
GO
ALTER TABLE [dbo].[cache_messages] ALTER COLUMN
[mailbox] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
GO
ALTER TABLE [dbo].[cache_thread] ALTER COLUMN
[mailbox] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
GO
ALTER TABLE [dbo].[users] ALTER COLUMN
[username] [varchar] (128) COLLATE Latin1_General_CS_AS NOT NULL
GO

@ -1,4 +0,0 @@
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

@ -7,12 +7,13 @@
CREATE TABLE `session` (
`sess_id` varchar(128) NOT NULL,
`created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
`changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
`ip` varchar(40) NOT NULL,
`vars` mediumtext NOT NULL,
PRIMARY KEY(`sess_id`),
INDEX `changed_index` (`changed`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `users`
@ -23,38 +24,38 @@ CREATE TABLE `users` (
`mail_host` varchar(128) NOT NULL,
`created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
`last_login` datetime DEFAULT NULL,
`failed_login` datetime DEFAULT NULL,
`failed_login_counter` int(10) UNSIGNED DEFAULT NULL,
`language` varchar(16),
`language` varchar(5),
`preferences` longtext,
PRIMARY KEY(`user_id`),
UNIQUE `username` (`username`, `mail_host`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `cache`
CREATE TABLE `cache` (
`user_id` int(10) UNSIGNED NOT NULL,
`cache_key` varchar(128) BINARY NOT NULL,
`cache_key` varchar(128) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
`created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
`expires` datetime DEFAULT NULL,
`data` longtext NOT NULL,
PRIMARY KEY (`user_id`, `cache_key`),
CONSTRAINT `user_id_fk_cache` FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
INDEX `expires_index` (`expires`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
INDEX `expires_index` (`expires`),
INDEX `user_cache_index` (`user_id`,`cache_key`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `cache_shared`
CREATE TABLE `cache_shared` (
`cache_key` varchar(255) BINARY NOT NULL,
`cache_key` varchar(255) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
`created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
`expires` datetime DEFAULT NULL,
`data` longtext NOT NULL,
PRIMARY KEY (`cache_key`),
INDEX `expires_index` (`expires`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
INDEX `expires_index` (`expires`),
INDEX `cache_key_index` (`cache_key`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `cache_index`
@ -69,7 +70,7 @@ CREATE TABLE `cache_index` (
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
INDEX `expires_index` (`expires`),
PRIMARY KEY (`user_id`, `mailbox`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `cache_thread`
@ -83,7 +84,7 @@ CREATE TABLE `cache_thread` (
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
INDEX `expires_index` (`expires`),
PRIMARY KEY (`user_id`, `mailbox`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `cache_messages`
@ -99,7 +100,7 @@ CREATE TABLE `cache_messages` (
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
INDEX `expires_index` (`expires`),
PRIMARY KEY (`user_id`, `mailbox`, `uid`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `contacts`
@ -119,7 +120,7 @@ CREATE TABLE `contacts` (
CONSTRAINT `user_id_fk_contacts` FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
INDEX `user_contacts_index` (`user_id`,`del`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `contactgroups`
@ -133,7 +134,7 @@ CREATE TABLE `contactgroups` (
CONSTRAINT `user_id_fk_contactgroups` FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
INDEX `contactgroups_user_index` (`user_id`,`del`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
CREATE TABLE `contactgroupmembers` (
`contactgroup_id` int(10) UNSIGNED NOT NULL,
@ -161,27 +162,26 @@ CREATE TABLE `identities` (
`email` varchar(128) NOT NULL,
`reply-to` varchar(128) NOT NULL DEFAULT '',
`bcc` varchar(128) NOT NULL DEFAULT '',
`signature` longtext,
`signature` text,
`html_signature` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY(`identity_id`),
CONSTRAINT `user_id_fk_identities` FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
INDEX `user_identities_index` (`user_id`, `del`),
INDEX `email_identities_index` (`email`, `del`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `dictionary`
CREATE TABLE `dictionary` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, -- redundant, for compat. with Galera Cluster
`user_id` int(10) UNSIGNED DEFAULT NULL, -- NULL here is for "shared dictionaries"
`language` varchar(16) NOT NULL,
`user_id` int(10) UNSIGNED DEFAULT NULL,
`language` varchar(5) NOT NULL,
`data` longtext NOT NULL,
CONSTRAINT `user_id_fk_dictionary` FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
UNIQUE `uniqueness` (`user_id`, `language`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-- Table structure for table `searches`
@ -196,22 +196,8 @@ CREATE TABLE `searches` (
CONSTRAINT `user_id_fk_searches` FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
UNIQUE `uniqueness` (`user_id`, `type`, `name`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
-- Table structure for table `filestore`
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
CREATE TABLE `filestore` (
`file_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` int(10) UNSIGNED NOT NULL,
`context` varchar(32) NOT NULL,
`filename` varchar(128) NOT NULL,
`mtime` int(10) NOT NULL,
`data` longtext NOT NULL,
PRIMARY KEY (`file_id`),
CONSTRAINT `user_id_fk_filestore` FOREIGN KEY (`user_id`)
REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
UNIQUE `uniqueness` (`user_id`, `context`, `filename`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
-- Table structure for table `system`
@ -219,8 +205,8 @@ CREATE TABLE `system` (
`name` varchar(64) NOT NULL,
`value` mediumtext,
PRIMARY KEY(`name`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
/*!40014 SET FOREIGN_KEY_CHECKS=1 */;
INSERT INTO `system` (`name`, `value`) VALUES ('roundcube-version', '2020020101');
INSERT INTO system (name, value) VALUES ('roundcube-version', '2014042900');

@ -1 +0,0 @@
ALTER TABLE `identities` CHANGE `signature` `signature` longtext;

@ -1,3 +0,0 @@
ALTER TABLE `users`
ADD `failed_login` datetime DEFAULT NULL,
ADD `failed_login_counter` int(10) UNSIGNED DEFAULT NULL;

@ -1 +0,0 @@
ALTER TABLE `session` DROP COLUMN `created`;

@ -1 +0,0 @@
ALTER TABLE `session` MODIFY `ip` varchar(40) NOT NULL;

@ -1,24 +0,0 @@
ALTER TABLE `dictionary` ADD COLUMN `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST; -- redundant, for compat. with Galera Cluster
DROP TABLE `cache`;
DROP TABLE `cache_shared`;
CREATE TABLE `cache` (
`user_id` int(10) UNSIGNED NOT NULL,
`cache_key` varchar(128) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
`expires` datetime DEFAULT NULL,
`data` longtext NOT NULL,
PRIMARY KEY (`user_id`, `cache_key`),
CONSTRAINT `user_id_fk_cache` FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
INDEX `expires_index` (`expires`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
CREATE TABLE `cache_shared` (
`cache_key` varchar(255) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
`expires` datetime DEFAULT NULL,
`data` longtext NOT NULL,
PRIMARY KEY (`cache_key`),
INDEX `expires_index` (`expires`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;

@ -1,11 +0,0 @@
CREATE TABLE `filestore` (
`file_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` int(10) UNSIGNED NOT NULL,
`filename` varchar(128) NOT NULL,
`mtime` int(10) NOT NULL,
`data` longtext NOT NULL,
PRIMARY KEY (`file_id`),
CONSTRAINT `user_id_fk_filestore` FOREIGN KEY (`user_id`)
REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
UNIQUE `uniqueness` (`user_id`, `filename`)
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;

@ -1,7 +0,0 @@
ALTER TABLE `filestore` ADD COLUMN `context` varchar(32) NOT NULL;
UPDATE `filestore` SET `context` = 'enigma';
ALTER TABLE `filestore` DROP FOREIGN KEY `user_id_fk_filestore`;
ALTER TABLE `filestore` DROP INDEX `uniqueness`;
ALTER TABLE `filestore` ADD UNIQUE INDEX `uniqueness` (`user_id`, `context`, `filename`);
ALTER TABLE `filestore` ADD CONSTRAINT `user_id_fk_filestore` FOREIGN KEY (`user_id`)
REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE;

@ -1,2 +0,0 @@
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;

@ -1,2 +0,0 @@
ALTER TABLE `users` MODIFY `language` varchar(16);
ALTER TABLE `dictionary` MODIFY `language` varchar(16) NOT NULL;

@ -1,21 +0,0 @@
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;

@ -1,241 +0,0 @@
-- Roundcube Webmail initial database structure
-- This was tested with Oracle 11g
CREATE TABLE "users" (
"user_id" integer PRIMARY KEY,
"username" varchar(128) NOT NULL,
"mail_host" varchar(128) NOT NULL,
"created" timestamp with time zone DEFAULT current_timestamp NOT NULL,
"last_login" timestamp with time zone DEFAULT NULL,
"failed_login" timestamp with time zone DEFAULT NULL,
"failed_login_counter" integer DEFAULT NULL,
"language" varchar(16),
"preferences" long DEFAULT NULL,
CONSTRAINT "users_username_key" UNIQUE ("username", "mail_host")
);
CREATE SEQUENCE "users_seq"
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
CREATE TRIGGER "users_seq_trig"
BEFORE INSERT ON "users" FOR EACH ROW
BEGIN
:NEW."user_id" := "users_seq".nextval;
END;
/
CREATE TABLE "session" (
"sess_id" varchar(128) NOT NULL PRIMARY KEY,
"changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
"ip" varchar(41) NOT NULL,
"vars" long NOT NULL
);
CREATE INDEX "session_changed_idx" ON "session" ("changed");
CREATE TABLE "identities" (
"identity_id" integer PRIMARY KEY,
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
"del" smallint DEFAULT 0 NOT NULL,
"standard" smallint DEFAULT 0 NOT NULL,
"name" varchar(128) NOT NULL,
"organization" varchar(128),
"email" varchar(128) NOT NULL,
"reply-to" varchar(128),
"bcc" varchar(128),
"signature" long,
"html_signature" integer DEFAULT 0 NOT NULL
);
CREATE INDEX "identities_user_id_idx" ON "identities" ("user_id", "del");
CREATE INDEX "identities_email_idx" ON "identities" ("email", "del");
CREATE SEQUENCE "identities_seq"
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
CREATE TRIGGER "identities_seq_trig"
BEFORE INSERT ON "identities" FOR EACH ROW
BEGIN
:NEW."identity_id" := "identities_seq".nextval;
END;
/
CREATE TABLE "contacts" (
"contact_id" integer PRIMARY KEY,
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
"del" smallint DEFAULT 0 NOT NULL,
"name" varchar(128) DEFAULT NULL,
"email" varchar(4000) DEFAULT NULL,
"firstname" varchar(128) DEFAULT NULL,
"surname" varchar(128) DEFAULT NULL,
"vcard" long,
"words" varchar(4000)
);
CREATE INDEX "contacts_user_id_idx" ON "contacts" ("user_id", "del");
CREATE SEQUENCE "contacts_seq"
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
CREATE TRIGGER "contacts_seq_trig"
BEFORE INSERT ON "contacts" FOR EACH ROW
BEGIN
:NEW."contact_id" := "contacts_seq".nextval;
END;
/
CREATE TABLE "contactgroups" (
"contactgroup_id" integer PRIMARY KEY,
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"changed" timestamp with time zone DEFAULT current_timestamp NOT NULL,
"del" smallint DEFAULT 0 NOT NULL,
"name" varchar(128) NOT NULL
);
CREATE INDEX "contactgroups_user_id_idx" ON "contactgroups" ("user_id", "del");
CREATE SEQUENCE "contactgroups_seq"
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
CREATE TRIGGER "contactgroups_seq_trig"
BEFORE INSERT ON "contactgroups" FOR EACH ROW
BEGIN
:NEW."contactgroup_id" := "contactgroups_seq".nextval;
END;
/
CREATE TABLE "contactgroupmembers" (
"contactgroup_id" integer NOT NULL
REFERENCES "contactgroups" ("contactgroup_id") ON DELETE CASCADE,
"contact_id" integer NOT NULL
REFERENCES "contacts" ("contact_id") ON DELETE CASCADE,
"created" timestamp with time zone DEFAULT current_timestamp NOT NULL,
PRIMARY KEY ("contactgroup_id", "contact_id")
);
CREATE INDEX "contactgroupmembers_idx" ON "contactgroupmembers" ("contact_id");
CREATE TABLE "cache" (
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"cache_key" varchar(128) NOT NULL,
"expires" timestamp with time zone DEFAULT NULL,
"data" long NOT NULL,
PRIMARY KEY ("user_id", "cache_key")
);
CREATE INDEX "cache_expires_idx" ON "cache" ("expires");
CREATE TABLE "cache_shared" (
"cache_key" varchar(255) NOT NULL,
"expires" timestamp with time zone DEFAULT NULL,
"data" long NOT NULL,
PRIMARY KEY ("cache_key")
);
CREATE INDEX "cache_shared_expires_idx" ON "cache_shared" ("expires");
CREATE TABLE "cache_index" (
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"mailbox" varchar(255) NOT NULL,
"expires" timestamp with time zone DEFAULT NULL,
"valid" smallint DEFAULT 0 NOT NULL,
"data" long NOT NULL,
PRIMARY KEY ("user_id", "mailbox")
);
CREATE INDEX "cache_index_expires_idx" ON "cache_index" ("expires");
CREATE TABLE "cache_thread" (
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"mailbox" varchar(255) NOT NULL,
"expires" timestamp with time zone DEFAULT NULL,
"data" long NOT NULL,
PRIMARY KEY ("user_id", "mailbox")
);
CREATE INDEX "cache_thread_expires_idx" ON "cache_thread" ("expires");
CREATE TABLE "cache_messages" (
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"mailbox" varchar(255) NOT NULL,
"uid" integer NOT NULL,
"expires" timestamp with time zone DEFAULT NULL,
"data" long NOT NULL,
"flags" integer DEFAULT 0 NOT NULL,
PRIMARY KEY ("user_id", "mailbox", "uid")
);
CREATE INDEX "cache_messages_expires_idx" ON "cache_messages" ("expires");
CREATE TABLE "dictionary" (
"user_id" integer DEFAULT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"language" varchar(16) NOT NULL,
"data" long DEFAULT NULL,
CONSTRAINT "dictionary_user_id_lang_key" UNIQUE ("user_id", "language")
);
CREATE TABLE "searches" (
"search_id" integer PRIMARY KEY,
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"type" smallint DEFAULT 0 NOT NULL,
"name" varchar(128) NOT NULL,
"data" long NOT NULL,
CONSTRAINT "searches_user_id_key" UNIQUE ("user_id", "type", "name")
);
CREATE SEQUENCE "searches_seq"
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
CREATE TRIGGER "searches_seq_trig"
BEFORE INSERT ON "searches" FOR EACH ROW
BEGIN
:NEW."search_id" := "searches_seq".nextval;
END;
/
CREATE TABLE "filestore" (
"file_id" integer PRIMARY KEY,
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE ON UPDATE CASCADE,
"context" varchar(32) NOT NULL,
"filename" varchar(128) NOT NULL,
"mtime" integer NOT NULL,
"data" long,
CONSTRAINT "filestore_user_id_key" UNIQUE ("user_id", "context", "filename")
);
CREATE SEQUENCE "filestore_seq"
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
CREATE TRIGGER "filestore_seq_trig"
BEFORE INSERT ON "filestore" FOR EACH ROW
BEGIN
:NEW."user_id" := "filestore_seq".nextval;
END;
/
CREATE TABLE "system" (
"name" varchar(64) NOT NULL PRIMARY KEY,
"value" long
);
INSERT INTO "system" ("name", "value") VALUES ('roundcube-version', '2020020101');

@ -1,2 +0,0 @@
ALTER TABLE "users" ADD "failed_login" timestamp with time zone DEFAULT NULL;
ALTER TABLE "users" ADD "failed_login_counter" integer DEFAULT NULL;

@ -1 +0,0 @@
ALTER TABLE "session" DROP COLUMN "created";

@ -1 +0,0 @@
ALTER TABLE "session" MODIFY "ip" varchar(41) NOT NULL;

@ -1,23 +0,0 @@
DROP TABLE "cache";
DROP TABLE "cache_shared";
CREATE TABLE "cache" (
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE,
"cache_key" varchar(128) NOT NULL,
"expires" timestamp with time zone DEFAULT NULL,
"data" long NOT NULL,
PRIMARY KEY ("user_id", "cache_key")
);
CREATE INDEX "cache_expires_idx" ON "cache" ("expires");
CREATE TABLE "cache_shared" (
"cache_key" varchar(255) NOT NULL,
"expires" timestamp with time zone DEFAULT NULL,
"data" long NOT NULL,
PRIMARY KEY ("cache_key")
);
CREATE INDEX "cache_shared_expires_idx" ON "cache_shared" ("expires");

@ -1,19 +0,0 @@
CREATE TABLE "filestore" (
"file_id" integer PRIMARY KEY,
"user_id" integer NOT NULL
REFERENCES "users" ("user_id") ON DELETE CASCADE ON UPDATE CASCADE,
"filename" varchar(128) NOT NULL,
"mtime" integer NOT NULL,
"data" long,
CONSTRAINT "filestore_user_id_key" UNIQUE ("user_id", "filename")
);
CREATE SEQUENCE "filestore_seq"
START WITH 1 INCREMENT BY 1 NOMAXVALUE;
CREATE TRIGGER "filestore_seq_trig"
BEFORE INSERT ON "filestore" FOR EACH ROW
BEGIN
:NEW."user_id" := "filestore_seq".nextval;
END;
/

@ -1,4 +0,0 @@
ALTER TABLE "filestore" ADD COLUMN "context" varchar(32) NOT NULL;
UPDATE "filestore" SET "context" = 'enigma';
ALTER TABLE "filestore" DROP CONSTRAINT "filestore_user_id_key";
ALTER TABLE "filestore" ADD CONSTRAINT "filestore_user_id_key" UNIQUE ("user_id", "context", "filename");

@ -1,2 +0,0 @@
ALTER TABLE "users" MODIFY "language" varchar(16) NOT NULL;
ALTER TABLE "dictionary" MODIFY "language" varchar(16);

@ -22,9 +22,7 @@ CREATE TABLE users (
mail_host varchar(128) DEFAULT '' NOT NULL,
created timestamp with time zone DEFAULT now() NOT NULL,
last_login timestamp with time zone DEFAULT NULL,
failed_login timestamp with time zone DEFAULT NULL,
failed_login_counter integer DEFAULT NULL,
"language" varchar(16),
"language" varchar(5),
preferences text DEFAULT ''::text NOT NULL,
CONSTRAINT users_username_key UNIQUE (username, mail_host)
);
@ -37,6 +35,7 @@ CREATE TABLE users (
CREATE TABLE "session" (
sess_id varchar(128) DEFAULT '' PRIMARY KEY,
created timestamp with time zone DEFAULT now() NOT NULL,
changed timestamp with time zone DEFAULT now() NOT NULL,
ip varchar(41) NOT NULL,
vars text NOT NULL
@ -167,11 +166,12 @@ CREATE TABLE "cache" (
user_id integer NOT NULL
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
cache_key varchar(128) DEFAULT '' NOT NULL,
created timestamp with time zone DEFAULT now() NOT NULL,
expires timestamp with time zone DEFAULT NULL,
data text NOT NULL,
PRIMARY KEY (user_id, cache_key)
data text NOT NULL
);
CREATE INDEX cache_user_id_idx ON "cache" (user_id, cache_key);
CREATE INDEX cache_expires_idx ON "cache" (expires);
--
@ -180,11 +180,13 @@ CREATE INDEX cache_expires_idx ON "cache" (expires);
--
CREATE TABLE "cache_shared" (
cache_key varchar(255) NOT NULL PRIMARY KEY,
cache_key varchar(255) NOT NULL,
created timestamp with time zone DEFAULT now() NOT NULL,
expires timestamp with time zone DEFAULT NULL,
data text NOT NULL
);
CREATE INDEX cache_shared_cache_key_idx ON "cache_shared" (cache_key);
CREATE INDEX cache_shared_expires_idx ON "cache_shared" (expires);
--
@ -246,7 +248,7 @@ CREATE INDEX cache_messages_expires_idx ON cache_messages (expires);
CREATE TABLE dictionary (
user_id integer DEFAULT NULL
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
"language" varchar(16) NOT NULL,
"language" varchar(5) NOT NULL,
data text NOT NULL,
CONSTRAINT dictionary_user_id_language_key UNIQUE (user_id, "language")
);
@ -277,32 +279,6 @@ CREATE TABLE searches (
CONSTRAINT searches_user_id_key UNIQUE (user_id, "type", name)
);
--
-- Sequence "filestore_seq"
-- Name: filestore_seq; Type: SEQUENCE; Schema: public; Owner: postgres
--
CREATE SEQUENCE "filestore_seq"
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
--
-- Table "filestore"
-- Name: filestore; Type: TABLE; Schema: public; Owner: postgres
--
CREATE TABLE "filestore" (
file_id integer DEFAULT nextval('filestore_seq'::text) PRIMARY KEY,
user_id integer NOT NULL
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
context varchar(32) NOT NULL,
filename varchar(128) NOT NULL,
mtime integer NOT NULL,
data text NOT NULL,
CONSTRAINT filestore_user_id_filename UNIQUE (user_id, context, filename)
);
--
-- Table "system"
@ -314,4 +290,4 @@ CREATE TABLE "system" (
value text
);
INSERT INTO "system" (name, value) VALUES ('roundcube-version', '2020020101');
INSERT INTO system (name, value) VALUES ('roundcube-version', '2014042900');

@ -1,2 +0,0 @@
ALTER TABLE "users" ADD failed_login timestamp with time zone DEFAULT NULL;
ALTER TABLE "users" ADD failed_login_counter integer DEFAULT NULL;

@ -1 +0,0 @@
ALTER TABLE "session" DROP COLUMN created;

@ -1 +0,0 @@
ALTER TABLE session ALTER COLUMN ip TYPE character varying(41);

@ -1,21 +0,0 @@
DROP TABLE "cache";
DROP TABLE "cache_shared";
CREATE TABLE "cache" (
user_id integer NOT NULL
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
cache_key varchar(128) DEFAULT '' NOT NULL,
expires timestamp with time zone DEFAULT NULL,
data text NOT NULL,
PRIMARY KEY (user_id, cache_key)
);
CREATE INDEX cache_expires_idx ON "cache" (expires);
CREATE TABLE "cache_shared" (
cache_key varchar(255) NOT NULL PRIMARY KEY,
expires timestamp with time zone DEFAULT NULL,
data text NOT NULL
);
CREATE INDEX cache_shared_expires_idx ON "cache_shared" (expires);

@ -1,15 +0,0 @@
CREATE SEQUENCE "filestore_seq"
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
CREATE TABLE "filestore" (
file_id integer DEFAULT nextval('filestore_seq'::text) PRIMARY KEY,
user_id integer NOT NULL
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
filename varchar(128) NOT NULL,
mtime integer NOT NULL,
data text NOT NULL,
CONSTRAINT filestore_user_id_filename UNIQUE (user_id, filename)
);

@ -1,4 +0,0 @@
ALTER TABLE "filestore" ADD COLUMN context varchar(32) NOT NULL;
UPDATE "filestore" SET context = 'enigma';
ALTER TABLE "filestore" DROP CONSTRAINT "filestore_user_id_filename";
ALTER TABLE "filestore" ADD CONSTRAINT "filestore_user_id_context_filename" UNIQUE (user_id, context, filename);

@ -1,2 +0,0 @@
ALTER TABLE "dictionary" ALTER COLUMN "language" TYPE varchar(16);
ALTER TABLE "users" ALTER COLUMN "language" TYPE varchar(16);

@ -72,9 +72,7 @@ CREATE TABLE users (
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),
language varchar(5),
preferences text NOT NULL default ''
);
@ -86,6 +84,7 @@ CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host);
CREATE TABLE session (
sess_id varchar(128) NOT NULL PRIMARY KEY,
created datetime NOT NULL default '0000-00-00 00:00:00',
changed datetime NOT NULL default '0000-00-00 00:00:00',
ip varchar(40) NOT NULL default '',
vars text NOT NULL
@ -99,11 +98,11 @@ CREATE INDEX ix_session_changed ON session (changed);
CREATE TABLE dictionary (
user_id integer DEFAULT NULL,
language varchar(16) NOT NULL,
"language" varchar(5) NOT NULL,
data text NOT NULL
);
CREATE UNIQUE INDEX ix_dictionary_user_language ON dictionary (user_id, language);
CREATE UNIQUE INDEX ix_dictionary_user_language ON dictionary (user_id, "language");
--
-- Table structure for table searches
@ -126,11 +125,12 @@ CREATE UNIQUE INDEX ix_searches_user_type_name ON searches (user_id, type, name)
CREATE TABLE cache (
user_id integer NOT NULL default 0,
cache_key varchar(128) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
expires datetime DEFAULT NULL,
data text NOT NULL,
PRIMARY KEY (user_id, cache_key)
data text NOT NULL
);
CREATE INDEX ix_cache_user_cache_key ON cache(user_id, cache_key);
CREATE INDEX ix_cache_expires ON cache(expires);
--
@ -139,11 +139,12 @@ CREATE INDEX ix_cache_expires ON cache(expires);
CREATE TABLE cache_shared (
cache_key varchar(255) NOT NULL,
created datetime NOT NULL default '0000-00-00 00:00:00',
expires datetime DEFAULT NULL,
data text NOT NULL,
PRIMARY KEY (cache_key)
data text NOT NULL
);
CREATE INDEX ix_cache_shared_cache_key ON cache_shared(cache_key);
CREATE INDEX ix_cache_shared_expires ON cache_shared(expires);
--
@ -191,21 +192,6 @@ CREATE TABLE cache_messages (
CREATE INDEX ix_cache_messages_expires ON cache_messages (expires);
--
-- Table structure for table filestore
--
CREATE TABLE filestore (
file_id integer NOT NULL PRIMARY KEY,
user_id integer NOT NULL,
context varchar(32) NOT NULL,
filename varchar(128) NOT NULL,
mtime integer NOT NULL,
data text NOT NULL
);
CREATE UNIQUE INDEX ix_filestore_user_id ON filestore(user_id, context, filename);
--
-- Table structure for table system
--
@ -215,4 +201,4 @@ CREATE TABLE system (
value text NOT NULL
);
INSERT INTO system (name, value) VALUES ('roundcube-version', '2020020101');
INSERT INTO system (name, value) VALUES ('roundcube-version', '2014042900');

@ -1,35 +0,0 @@
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(5),
preferences text NOT NULL default ''
);
INSERT INTO tmp_users (user_id, username, mail_host, created, last_login, language, preferences)
SELECT user_id, username, mail_host, created, last_login, 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(5),
preferences text NOT NULL default ''
);
INSERT INTO users (user_id, username, mail_host, created, last_login, language, preferences)
SELECT user_id, username, mail_host, created, last_login, language, preferences FROM tmp_users;
CREATE UNIQUE INDEX ix_users_username ON users(username, mail_host);
DROP TABLE tmp_users;

@ -1,9 +0,0 @@
DROP TABLE session;
CREATE TABLE session (
sess_id varchar(128) NOT NULL PRIMARY KEY,
changed datetime NOT NULL default '0000-00-00 00:00:00',
ip varchar(40) NOT NULL default '',
vars text NOT NULL
);
CREATE INDEX ix_session_changed ON session (changed);

@ -1,21 +0,0 @@
DROP TABLE cache;
DROP TABLE cache_shared;
CREATE TABLE cache (
user_id integer NOT NULL default 0,
cache_key varchar(128) NOT NULL default '',
expires datetime DEFAULT NULL,
data text NOT NULL,
PRIMARY KEY (user_id, cache_key)
);
CREATE INDEX ix_cache_expires ON cache(expires);
CREATE TABLE cache_shared (
cache_key varchar(255) NOT NULL,
expires datetime DEFAULT NULL,
data text NOT NULL,
PRIMARY KEY (cache_key)
);
CREATE INDEX ix_cache_shared_expires ON cache_shared(expires);

@ -1,9 +0,0 @@
CREATE TABLE filestore (
file_id integer PRIMARY KEY,
user_id integer NOT NULL,
filename varchar(128) NOT NULL,
mtime integer NOT NULL,
data text NOT NULL
);
CREATE UNIQUE INDEX ix_filestore_user_id ON filestore(user_id, filename);

@ -1,29 +0,0 @@
CREATE TABLE tmp_filestore (
file_id integer PRIMARY KEY,
user_id integer NOT NULL,
filename varchar(128) NOT NULL,
mtime integer NOT NULL,
data text NOT NULL
);
INSERT INTO tmp_filestore (file_id, user_id, filename, mtime, data)
SELECT file_id, user_id, filename, mtime, data FROM filestore;
DROP TABLE filestore;
CREATE TABLE filestore (
file_id integer NOT NULL PRIMARY KEY,
user_id integer NOT NULL,
context varchar(32) NOT NULL,
filename varchar(128) NOT NULL,
mtime integer NOT NULL,
data text NOT NULL
);
INSERT INTO filestore (file_id, user_id, filename, mtime, data, context)
SELECT file_id, user_id, filename, mtime, data, 'enigma' FROM tmp_filestore;
CREATE UNIQUE INDEX ix_filestore_user_id ON filestore(user_id, context, filename);
DROP TABLE tmp_filestore;

@ -1,57 +0,0 @@
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;

@ -14,23 +14,18 @@ and cd into that directory. From there, run the following command in a shell:
./bin/installto.sh <TARGET-FOLDER>
For <TARGET-FOLDER> you specify the path to the Roundcube installation
which should be updated. The update script will then copy all new files to the
For <TARGET-FOLDER> you specify the path to the Roundcube installation
which should be updated. The update script will then copy all new files to the
target location and check and update the configuration and database schema.
After all is done, the temporary folder with the new Roundcube files can be
After all is done, the temporary folder with the new Roundcube files can be
removed again.
WARNING: Make sure files have proper owner/group for your setup. If you use
tar to extract the package, `--no-same-owner` option might be helpful.
WARNING: See Post-Upgrade Activities section below.
WARNING: If you use MySQL < 5.7.7 or MariaDB < 10.2.2 make sure to configure it with:
innodb_large_prefix=true
innodb_file_format=Barracuda
Updating manually
-----------------
If you don't have shell access to the Roundcube installation or if not running
If you don't have shell access to the Roundcube installation or if not running
it on a unix system, you need to do the following operations by hand:
1. Replace index.php and all files in
@ -45,46 +40,25 @@ it on a unix system, you need to do the following operations by hand:
directory into the target folder:
./skins/
./plugins/
./vendor/
4. Update dependencies:
4a. If you previously installed plugins through composer, update dependencies
by running `php composer.phar update --no-dev`.
4b. Install/update dependencies using composer:
- get composer from https://getcomposer.org/download/
- rename the composer.json-dist file into composer.json
- if you want to use LDAP address books, enable the LDAP libraries in your
composer.json file by moving the items from "suggest" to the "require"
section (remove the explanation texts after the version!).
- run `php composer.phar install --no-dev`.
4c. If you use git sources or the release package without dependencies
update javascript dependencies by executing `bin/install-jsdeps.sh` script.
4d. If you use git sources compile css files for the Elastic skin (required
lessc >= 1.5.0):
$ cd skins/elastic
$ lessc -x styles/styles.less > styles/styles.css
$ lessc -x styles/print.less > styles/print.css
$ lessc -x styles/embed.less > styles/embed.css
5. Run `./bin/update.sh` from the commandline OR
4. Run ./bin/update.sh from the commandline OR
open http://url-to-roundcube/installer/ in a browser and choose "3 Test config".
To enable the latter one, you have to temporary set 'enable_installer'
to true in your local config/config.inc.php file.
WARNING: See SQLite database upgrade below.
6. Let the update script/installer check your configuration and
5. Let the update script/installer check your configuration and
update your config files and database schema as suggested by the updater.
7. Make sure 'enable_installer' is set to false again.
8. See Post-Upgrade Activities section.
6. Make sure 'enable_installer' is set to false again.
7. See Post-Upgrade Activities section.
Post-Upgrade Activities
-----------------------
1. Check system requirements in INSTALL file.
1. Check .htaccess settings (some php settings could become required)
2. If you're using build-in addressbook, run indexing script /bin/indexcontacts.sh.
3. When upgrading from version older than 0.6-beta you should make sure
your folder settings contain namespace prefix. For example Courier users
should add INBOX. prefix to folder names in main configuration file.
4. When upgrading from version older than 1.4.0 make sure old files
in configured temp_dir are removed. Since this version we use constant filename
prefix and do not remove files not starting with "RCMTEMP".
4. Check system requirements in INSTALL file.
SQLite database upgrade
-----------------------

@ -2,9 +2,10 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/cleandb.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2010, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -12,18 +13,66 @@
| |
| PURPOSE: |
| Finally remove all db records marked as deleted some time ago |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require INSTALL_PATH.'program/include/clisetup.php';
// mapping for table name => primary key
$primary_keys = array(
'contacts' => "contact_id",
'contactgroups' => "contactgroup_id",
);
// connect to DB
$RCMAIL = rcmail::get_instance();
$db = $RCMAIL->get_dbh();
$db->db_connect('w');
if (!$db->is_connected() || $db->is_error()) {
rcube::raise_error("No DB connection", false, true);
}
if (!empty($_SERVER['argv'][1]))
$days = intval($_SERVER['argv'][1]);
else
$days = 7;
rcmail_utils::db_clean($days);
// remove all deleted records older than two days
$threshold = date('Y-m-d 00:00:00', time() - $days * 86400);
foreach (array('contacts','contactgroups','identities') as $table) {
$sqltable = $db->table_name($table);
// also delete linked records
// could be skipped for databases which respect foreign key constraints
if ($db->db_provider == 'sqlite'
&& ($table == 'contacts' || $table == 'contactgroups')
) {
$pk = $primary_keys[$table];
$memberstable = get_table_name('contactgroupmembers');
$db->query(
"DELETE FROM $memberstable".
" WHERE $pk IN (".
"SELECT $pk FROM $sqltable".
" WHERE del=1 AND changed < ?".
")",
$threshold);
echo $db->affected_rows() . " records deleted from '$memberstable'\n";
}
// delete outdated records
$db->query("DELETE FROM $sqltable WHERE del=1 AND changed < ?", $threshold);
echo $db->affected_rows() . " records deleted from '$table'\n";
}
?>

@ -5,42 +5,42 @@ VERSION='2.4.8'
COMPILER_URL="https://github.com/yui/yuicompressor/releases/download/v${VERSION}/yuicompressor-${VERSION}.zip"
do_shrink() {
rm -f "$2"
java -jar $JAR_DIR/yuicompressor.jar -v -o "$2" "$1"
rm -f "$2"
java -jar $JAR_DIR/yuicompressor.jar -v -o "$2" "$1"
}
if [ ! -w "$JAR_DIR" ]; then
JAR_DIR=$PWD
JAR_DIR=$PWD
fi
if java -version >/dev/null 2>&1; then
:
:
else
echo "Java not found. Please ensure that the 'java' program is in your PATH."
exit 1
echo "Java not found. Please ensure that the 'java' program is in your PATH."
exit 1
fi
if [ ! -r "$JAR_DIR/yuicompressor.jar" ]; then
if which wget >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
wget "$COMPILER_URL" -O "/tmp/$$.zip"
elif which curl >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
curl -L "$COMPILER_URL" -o "/tmp/$$.zip"
else
echo "Please download $COMPILER_URL and extract compiler.jar to $JAR_DIR/."
exit 1
fi
(cd $JAR_DIR && unzip "/tmp/$$.zip" && mv "yuicompressor-${VERSION}.jar" "yuicompressor.jar")
rm -f "/tmp/$$.zip"
if which wget >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
wget "$COMPILER_URL" -O "/tmp/$$.zip"
elif which curl >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
curl "$COMPILER_URL" -o "/tmp/$$.zip"
else
echo "Please download $COMPILER_URL and extract compiler.jar to $JAR_DIR/."
exit 1
fi
(cd $JAR_DIR && unzip "/tmp/$$.zip" && mv "yuicompressor-${VERSION}.jar" "yuicompressor.jar")
rm -f "/tmp/$$.zip"
fi
# compress single file from argument
if [ $# -gt 0 ]; then
CSS_FILE="$1"
CSS_FILE="$1"
echo "Shrinking $CSS_FILE"
echo "Shrinking $CSS_FILE"
minfile=`echo $CSS_FILE | sed -e 's/\.css$/\.min\.css/'`
do_shrink "$CSS_FILE" "$minfile"
exit
do_shrink "$CSS_FILE" "$minfile"
exit
fi
DIRS="$PWD/../skins/* $PWD/../plugins/* $PWD/../plugins/*/skins/*"

@ -2,9 +2,10 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/decrypt.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2005-2009, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -12,6 +13,7 @@
| |
| PURPOSE: |
| Decrypt the encrypted parts of the HTTP Received: headers |
| |
+-----------------------------------------------------------------------+
| Author: Tomas Tevesz <ice@extreme.hu> |
+-----------------------------------------------------------------------+
@ -50,16 +52,16 @@
* - you are dealing with counterfeit header data.
*/
define('INSTALL_PATH', realpath(__DIR__ .'/..') . '/');
define('INSTALL_PATH', realpath(dirname(__FILE__).'/..') . '/');
require INSTALL_PATH . 'program/include/clisetup.php';
if ($argc < 2) {
die("Usage: " . basename($argv[0]) . " encrypted-hdr-part [encrypted-hdr-part ...]\n");
die("Usage: " . basename($argv[0]) . " encrypted-hdr-part [encrypted-hdr-part ...]\n");
}
$RCMAIL = rcube::get_instance();
$RCMAIL = rcmail::get_instance();
for ($i = 1; $i < $argc; $i++) {
printf("%s\n", $RCMAIL->decrypt($argv[$i]));
printf("%s\n", $RCMAIL->decrypt($argv[$i]));
};

@ -1,144 +0,0 @@
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| 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: |
| Utility script to remove all data related to a certain user |
| from the local database. |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <thomas@roundcube.net> |
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
require_once INSTALL_PATH . 'program/include/clisetup.php';
function print_usage()
{
print "Usage: deluser.sh [--host=HOST][--age=DAYS][--dry-run] [username]\n";
print "--host=HOST The IMAP hostname or IP the given user is related to\n";
print "--age=DAYS Delete all users who have not logged in for more than X days\n";
print "--dry-run List users but do not delete them (for use with --age)\n";
}
function _die($msg, $usage=false)
{
fwrite(STDERR, $msg . "\n");
if ($usage) print_usage();
exit(1);
}
$rcmail = rcube::get_instance();
// get arguments
$args = rcube_utils::get_opt(array('h' => 'host', 'a' => 'age', 'd' => 'dry-run:bool'));
if (!empty($args['age']) && ($age = intval($args['age']))) {
$db = $rcmail->get_dbh();
$db->db_connect('r');
$query = $db->query("SELECT `username`, `mail_host` FROM " . $db->table_name('users', true)
. " WHERE `last_login` < " . $db->now($age * -1 * 86400)
. ($args['host'] ? " AND `mail_host` = " . $db->quote($args['host']) : '')
);
while ($user = $db->fetch_assoc($query)) {
if (!empty($args['dry-run'])) {
printf("%s (%s)\n", $user['username'], $user['mail_host']);
continue;
}
system(sprintf("php %s/deluser.sh --host=%s %s", INSTALL_PATH . 'bin', $user['mail_host'], $user['username']));
}
exit(1);
}
$username = trim($args[0]);
if (empty($username)) {
_die("Missing required parameters", true);
}
if (empty($args['host'])) {
$hosts = $rcmail->config->get('default_host', '');
if (is_string($hosts)) {
$args['host'] = $hosts;
}
else if (is_array($hosts) && count($hosts) == 1) {
$args['host'] = reset($hosts);
}
else {
_die("Specify a host name", true);
}
// host can be a URL like tls://192.168.12.44
$host_url = parse_url($args['host']);
if ($host_url['host']) {
$args['host'] = $host_url['host'];
}
}
// connect to DB
$db = $rcmail->get_dbh();
$db->db_connect('w');
$transaction = false;
if (!$db->is_connected() || $db->is_error()) {
_die("No DB connection\n" . $db->is_error());
}
// find user in local database
$user = rcube_user::query($username, $args['host']);
if (!$user) {
die("User not found.\n");
}
// inform plugins about approaching user deletion
$plugin = $rcmail->plugins->exec_hook('user_delete_prepare', array('user' => $user, 'username' => $username, 'host' => $args['host']));
// let plugins cleanup their own user-related data
if (!$plugin['abort']) {
$transaction = $db->startTransaction();
$plugin = $rcmail->plugins->exec_hook('user_delete', $plugin);
}
if ($plugin['abort']) {
if ($transaction) {
$db->rollbackTransaction();
}
_die("User deletion aborted by plugin");
}
// deleting the user record should be sufficient due to ON DELETE CASCADE foreign key references
// but not all database backends actually support this so let's do it by hand
foreach (array('identities','contacts','contactgroups','dictionary','cache','cache_index','cache_messages','cache_thread','searches','users') as $table) {
$db->query('DELETE FROM ' . $db->table_name($table, true) . ' WHERE `user_id` = ?', $user->ID);
}
if ($db->is_error()) {
$rcmail->plugins->exec_hook('user_delete_rollback', $plugin);
_die("DB error occurred: " . $db->is_error());
}
else {
// inform plugins about executed user deletion
$plugin = $rcmail->plugins->exec_hook('user_delete_commit', $plugin);
if ($plugin['abort']) {
unset($plugin['abort']);
$db->rollbackTransaction();
$rcmail->plugins->exec_hook('user_delete_rollback', $plugin);
}
else {
$db->endTransaction();
echo "Successfully deleted user $user->ID\n";
}
}

@ -0,0 +1,233 @@
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
| bin/exportgettext.sh |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2011, The Roundcube Dev Team |
| Licensed under the GNU General Public License |
| |
| PURPOSE: |
| Export PHP-based localization files to PO files for gettext |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require INSTALL_PATH.'program/include/clisetup.php';
if ($argc < 2) {
die("Usage: " . basename($argv[0]) . " SRCDIR DESTDIR\n");
}
$srcdir = unslashify(realpath($argv[1]));
$destdir = unslashify($argv[2]);
$layout = 'launchpad'; # or 'narro';
$langcode_map = array(
'hy_AM' => 'hy',
'ar_SA' => 'ar',
'az_AZ' => 'az',
'bg_BG' => 'bg',
'bs_BA' => 'bs',
'ca_ES' => 'ca',
'cs_CZ' => 'cs',
'cy_GB' => 'cy',
'da_DK' => 'da',
'et_EE' => 'et',
'el_GR' => 'el',
'eu_ES' => 'eu',
'fa_IR' => 'fa',
'ga_IE' => 'ga',
'ka_GE' => 'ka',
'gl_ES' => 'gl',
'he_IL' => 'he',
'hi_IN' => 'hi',
'hr_HR' => 'hr',
'ja_JP' => 'ja',
'ko_KR' => 'ko',
'km_KH' => 'km',
'ms_MY' => 'ms',
'mr_IN' => 'mr',
'ml_IN' => 'ml',
'pl_PL' => 'pl',
'si_LK' => 'si',
'sl_SI' => 'sl',
'sq_AL' => 'sq',
'sr_CS' => 'sr',
'sv_SE' => 'sv',
'uk_UA' => 'uk',
'vi_VN' => 'vi',
);
// converting roundcube localization dir
if (is_dir($srcdir.'/en_US')) {
load_en_US($srcdir.'/en_US');
foreach (glob($srcdir.'/*') as $locdir) {
if (is_dir($locdir)) {
$lang = basename($locdir);
//echo "$locdir => $destdir$lang\n";
convert_dir($locdir, $destdir . ($layout != 'launchpad' ? $lang : ''));
}
}
}
// converting single localization directory
else if (is_dir($srcdir)) {
if (is_file($srcdir.'/en_US.inc')) // plugin localization
load_en_US($srcdir.'/en_US.inc');
else
load_en_US(realpath($srcdir.'/../en_US')); // single language
convert_dir($srcdir, $destdir);
}
// converting a single file
else if (is_file($srcdir)) {
//load_en_US();
convert_file($srcdir, $destdir);
}
/**
* Load en_US localization which is used to build msgids
*/
function load_en_US($fn)
{
$texts = array();
if (is_dir($fn)) {
foreach (glob($fn.'/*.inc') as $ifn) {
include($ifn);
$texts = array_merge($texts, (array)$labels, (array)$messages);
}
}
else if (is_file($fn)) {
include($fn);
$texts = array_merge($texts, (array)$labels, (array)$messages);
}
$GLOBALS['en_US'] = $texts;
}
/**
* Convert all .inc files in the given src directory
*/
function convert_dir($indir, $outdir)
{
global $layout;
if (!is_dir($outdir)) // attempt to create destination dir
mkdir($outdir, 0777, true);
foreach (glob($indir.'/*.inc') as $fn) {
$filename = basename($fn);
// create subdir for each template (launchpad rules)
if ($layout == 'launchpad' && preg_match('/^(labels|messages)/', $filename, $m)) {
$lang = end(explode('/', $indir));
$destdir = $outdir . '/' . $m[1];
if (!is_dir($destdir))
mkdir($destdir, 0777, true);
$outfn = $destdir . '/' . $lang . '.po';
}
else {
$outfn = $outdir . '/' . preg_replace('/\.[a-z0-9]+$/i', '', basename($fn)) . '.po';
}
convert_file($fn, $outfn);
}
}
/**
* Convert the given Roundcube localization file into a gettext .po file
*/
function convert_file($fn, $outfn)
{
global $layout, $langcode_map;
$basename = basename($fn);
$srcname = str_replace(INSTALL_PATH, '', $fn);
$product = preg_match('!plugins/(\w+)!', $srcname, $m) ? 'roundcube-plugin-' . $m[1] : 'roundcubemail';
$lang = preg_match('!/([a-z]{2}(_[A-Z]{2})?)[./]!', $outfn, $m) ? $m[1] : '';
$labels = $messages = $seen = array();
if (is_dir($outfn))
$outfn .= '/' . $basename . '.po';
// launchpad requires the template file to have the same name as the directory
if (strstr($outfn, '/en_US') && $layout == 'launchpad') {
$a = explode('/', $outfn);
array_pop($a);
$templ = end($a);
$a[] = $templ . '.pot';
$outfn = join('/', $a);
$is_pot = true;
}
// launchpad is very picky about file names
else if ($layout == 'launchpad' && preg_match($regex = '!/([a-z]{2})_([A-Z]{2})!', $outfn, $m)) {
if ($shortlang = $langcode_map[$lang])
$outfn = preg_replace($regex, '/'.$shortlang, $outfn);
else if ($m[1] == strtolower($m[2]))
$outfn = preg_replace($regex, '/\1', $outfn);
}
include($fn);
$texts = array_merge($labels, $messages);
// write header
$header = <<<EOF
# Converted from Roundcube PHP localization files
# Copyright (C) 2011 The Roundcube Dev Team
# This file is distributed under the same license as the Roundcube package.
#
#: %s
msgid ""
msgstr ""
"Project-Id-Version: %s\\n"
"Report-Msgid-Bugs-To: \\n"
"%s: %s\\n"
"Last-Translator: \\n"
"Language-Team: Translations <hello@roundcube.net>\\n"
"Language: %s\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
EOF;
$out = sprintf($header, $srcname, $product, $is_pot ? "POT-Creation-Date" : "PO-Revision-Date", date('c'), $shortlang ? $shortlang : $lang);
$out .= "\n";
$messages = array();
foreach ((array)$texts as $label => $msgstr) {
$msgid = $is_pot ? $msgstr : ($GLOBALS['en_US'][$label] ?: $label);
$messages[$msgid][] = $label;
}
foreach ($messages as $msgid => $labels) {
$out .= "\n";
foreach ($labels as $label)
$out .= "#: $srcname:$label\n";
$msgstr = $texts[$label];
$out .= 'msgid ' . gettext_quote($msgid) . "\n";
$out .= 'msgstr ' . gettext_quote(!$is_pot ? $msgstr : '') . "\n";
}
if ($outfn == '-')
echo $out;
else {
echo "$fn\t=>\t$outfn\n";
file_put_contents($outfn, $out);
}
}
function gettext_quote($str)
{
$out = "";
$lines = explode("\n", wordwrap(stripslashes($str)));
$last = count($lines) - 1;
foreach ($lines as $i => $line)
$out .= '"' . addcslashes($line, '"') . ($i < $last ? ' ' : '') . "\"\n";
return rtrim($out);
}
?>

@ -2,9 +2,10 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/gc.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2013, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -12,12 +13,13 @@
| |
| PURPOSE: |
| Trigger garbage collecting routines manually (e.g. via cronjob) |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require INSTALL_PATH.'program/include/clisetup.php';

@ -0,0 +1,196 @@
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
| bin/importgettext.sh |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2011, The Roundcube Dev Team |
| Licensed under the GNU General Public License |
| |
| PURPOSE: |
| Import localizations from gettext PO format |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require INSTALL_PATH.'program/include/clisetup.php';
if ($argc < 2) {
die("Usage: " . basename($argv[0]) . " SRCDIR\n");
}
$srcdir = unslashify(realpath($argv[1]));
if (is_dir($srcdir)) {
$out = import_dir($srcdir);
}
else if (is_file($srcdir)) {
$out = import_file($srcdir);
}
// write output files
foreach ($out as $outfn => $texts) {
$lang = preg_match('!/([a-z]{2}(_[A-Z]{2})?)[./]!', $outfn, $m) ? $m[1] : '';
$varname = strpos($outfn, 'messages.inc') !== false ? 'messages' : 'labels';
$header = <<<EOF
<?php
/*
+-----------------------------------------------------------------------+
| localization/%s/%-51s|
| |
| Language file of the Roundcube Webmail client |
| Copyright (C) %s, The Roundcube Dev Team |
| Licensed under the GNU General Public License |
| |
+-----------------------------------------------------------------------+
| Author: %-62s|
+-----------------------------------------------------------------------+
*/
$%s = array();
EOF;
$author = preg_replace('/\s*<Unknown>/i', '', $texts['_translator']);
$output = sprintf($header, $lang, $varname.'.inc', date('Y'), $author, $varname);
foreach ($texts as $label => $value) {
if (is_array($value)) { var_dump($outfn, $label, $value); exit; }
if ($label[0] != '_' && strlen($value))
$output .= sprintf("\$%s['%s'] = '%s';\n", $varname, $label, strtr(addcslashes($value, "'"), array("\r" => '', "\n" => '\n')));
}
$output .= "\n";
$dir = dirname($outfn);
@mkdir($dir, 0755, true);
if (file_put_contents($outfn, $output))
echo "-> $outfn\n";
}
/**
* Convert all .po files in the given src directory
*/
function import_dir($indir)
{
$out = array();
foreach (glob($indir.'/*.po') as $fn) {
$out = array_merge_recursive($out, import_file($fn));
}
return $out;
}
/**
* Convert the given .po file into a Roundcube localization array
*/
function import_file($fn)
{
$out = array();
$lines = file($fn);
$language = '';
$translator = '';
// get language code from file name
if (preg_match('/-([a-z_]+).po$/i', $fn, $m))
$language = expand_langcode($m[1]);
$is_header = true;
$msgid = null;
$msgstr = '';
$dests = array();
foreach ($lines as $i => $line) {
$line = trim($line);
// parse header
if ($is_header && $line[0] == '"') {
list($key, $val) = explode(": ", preg_replace('/\\\n$/', '', trim($line, '"')), 2);
switch (strtolower($key)) {
case 'language':
$language = expand_langcode($val);
break;
case 'last-translator':
$translator = $val;
break;
}
}
// empty line
if ($line == '') {
if ($msgid && $dests) {
foreach ($dests as $dest) {
list($file, $label) = explode(':', $dest);
$out[$file][$label] = $msgstr;
$out[$file]['_translator'] = $translator;
}
}
$msgid = null;
$msgstr = '';
$dests = array();
}
// meta line
if ($line[0] == '#') {
$value = trim(substr($line, 2));
if ($line[1] == ':')
$dests[] = str_replace('en_US', $language, $value);
}
else if (strpos($line, 'msgid') === 0) {
$msgid = gettext_decode(substr($line, 6));
if (!empty($msgid))
$is_header = false;
}
else if (strpos($line, 'msgstr') === 0) {
$msgstr = gettext_decode(substr($line, 7));
}
else if ($msgid && $line[0] == '"') {
$msgstr .= gettext_decode($line);
}
else if ($msgid !== null && $line[0] == '"') {
$msgid .= gettext_decode($line);
}
}
if ($msgid && $dests) {
foreach ($dests as $dest) {
list($file, $label) = explode(':', $dest);
$out[$file][$label] = $msgstr;
$out[$file]['_translator'] = $translator;
}
}
return $language ? $out : array();
}
function gettext_decode($str)
{
return stripslashes(trim($str, '"'));
}
/**
* Translate two-chars language codes to our internally used language identifiers
*/
function expand_langcode($lang)
{
static $rcube_language_aliases, $rcube_languages;
if (!$rcube_language_aliases)
include(INSTALL_PATH . 'program/localization/index.inc');
if ($rcube_language_aliases[$lang])
return $rcube_language_aliases[$lang];
else if (strlen($lang) == 2 && !isset($rcube_languages[$lang]))
return strtolower($lang) . '_' . strtoupper($lang);
else
return $lang;
}
?>

@ -2,9 +2,10 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/indexcontacts.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2011, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -18,9 +19,36 @@
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require_once INSTALL_PATH.'program/include/clisetup.php';
ini_set('memory_limit', -1);
rcmail_utils::indexcontacts();
// connect to DB
$RCMAIL = rcmail::get_instance();
$db = $RCMAIL->get_dbh();
$db->db_connect('w');
if (!$db->is_connected() || $db->is_error()) {
rcube::raise_error("No DB connection", false, true);
}
// iterate over all users
$sql_result = $db->query("SELECT user_id FROM " . $db->table_name('users') . " ORDER BY user_id");
while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) {
echo "Indexing contacts for user " . $sql_arr['user_id'] . "...";
$contacts = new rcube_contacts($db, $sql_arr['user_id']);
$contacts->set_pagesize(9999);
$result = $contacts->list_records();
while ($result->count && ($row = $result->next())) {
unset($row['words']);
$contacts->update($row['ID'], $row);
}
echo "done.\n";
}
?>

@ -1,39 +0,0 @@
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| Copyright (C) The Roundcube Dev Team |
| Copyright (C) Kolab Systems AG |
| |
| 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: |
| Create database schema |
+-----------------------------------------------------------------------+
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
require_once INSTALL_PATH . 'program/include/clisetup.php';
// get arguments
$opts = rcube_utils::get_opt(array(
'd' => 'dir',
));
if (empty($opts['dir'])) {
rcube::raise_error("Database schema directory not specified (--dir).", false, true);
}
// Check if directory exists
if (!file_exists($opts['dir'])) {
rcube::raise_error("Specified database schema directory doesn't exist.", false, true);
}
rcmail_utils::db_init($opts['dir']);

@ -1,385 +0,0 @@
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| 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: |
| Utility script to fetch and install all 3rd party javascript |
| libraries used in Roundcube from source. |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <thomas@roundcube.net> |
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
require_once INSTALL_PATH . 'program/include/clisetup.php';
if (!function_exists('exec')) {
rcube::raise_error("PHP exec() function is required. Check disable_functions in php.ini.", false, true);
}
$cfgfile = INSTALL_PATH . 'jsdeps.json';
$SOURCES = json_decode(file_get_contents($cfgfile), true);
if (empty($SOURCES['dependencies'])) {
rcube::raise_error("Failed to read dependencies list from $cfgfile", false, true);
}
$CURL = trim(`which curl`);
$WGET = trim(`which wget`);
$UNZIP = trim(`which unzip`);
if (($CACHEDIR = getenv("CACHEDIR")) && is_writeable($CACHEDIR)) {
// use $CACHEDIR
}
else if (is_writeable(INSTALL_PATH . 'temp/js_cache') || @mkdir(INSTALL_PATH . 'temp/js_cache', 0774, true)) {
$CACHEDIR = INSTALL_PATH . 'temp/js_cache';
}
else {
$CACHEDIR = sys_get_temp_dir();
}
//////////////// License definitions
$LICENSES = array();
$LICENSES['MIT'] = <<<EOM
* Licensed under the MIT licenses
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
EOM;
$LICENSES['GPLv3'] = <<<EOG
* The JavaScript code in this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License (GNU GPL) as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version. The code is distributed WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
*
* As additional permission under GNU GPL version 3 section 7, you
* may distribute non-source (e.g., minimized or compacted) forms of
* that code without the copy of the GNU GPL normally required by
* section 4, provided you include this license notice and a URL
* through which recipients can access the Corresponding Source.
EOG;
$LICENSES['LGPL'] = <<<EOL
* The JavaScript code in this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version.
EOL;
//////////////// Functions
/**
* Fetch package file from source
*/
function fetch_from_source($package, $useCache = true, &$filetype = null)
{
global $CURL, $WGET;
$cache_file = extract_filetype($package, $filetype);
if (!is_readable($cache_file) || !$useCache) {
if (empty($CURL) && empty($WGET)) {
rcube::raise_error("Required 'wget' or 'curl' program not found.", false, true);
}
$url = str_replace('$v', $package['version'], $package['url']);
echo "Fetching $url\n";
if ($CURL)
exec(sprintf('%s -L -s %s -o %s', $CURL, escapeshellarg($url), $cache_file), $out, $retval);
else
exec(sprintf('%s -q %s -O %s', $WGET, escapeshellarg($url), $cache_file), $out, $retval);
// Try Github API as a fallback (#6248)
if ($retval !== 0 && $package['api_url']) {
$url = str_replace('$v', $package['version'], $package['api_url']);
$header = 'Accept:application/vnd.github.v3.raw';
rcube::raise_error("Fetching failed. Using Github API on $url");
if ($CURL)
exec(sprintf('%s -L -H %s -s %s -o %s', $CURL, escapeshellarg($header), escapeshellarg($url), $cache_file), $out, $retval);
else
exec(sprintf('%s --header %s -q %s -O %s', $WGET, escapeshellarg($header), escapeshellarg($url), $cache_file), $out, $retval);
}
if ($retval !== 0) {
rcube::raise_error("Failed to download source file from $url", false, true);
}
}
return $cache_file;
}
/**
* Returns package source file location and type
*/
function extract_filetype($package, &$filetype = null)
{
global $CACHEDIR;
$filetype = pathinfo($package['url'], PATHINFO_EXTENSION) ?: 'tmp';
$cache_file = $CACHEDIR . '/' . $package['lib'] . '-' . $package['version'] . '.' . $filetype;
// Make sure it is a zip file
if (file_exists($cache_file)) {
$magic = file_get_contents($cache_file, false, null, 0, 4);
if ($magic === "PK\003\004") {
$filetype = 'zip';
}
}
return $cache_file;
}
/**
* Create a destination javascript file with copyright and license header
*/
function compose_destfile($package, $srcfile)
{
global $LICENSES;
$header = sprintf("/**\n * %s - v%s\n *\n", $package['name'], $package['version']);
if (!empty($package['source'])) {
$header .= " * @source " . str_replace('$v', $package['version'], $package['source']) . "\n";
$header .= " *\n";
}
if (!empty($package['license']) && isset($LICENSES[$package['license']])) {
$header .= " * @licstart The following is the entire license notice for the\n";
$header .= " * JavaScript code in this file.\n";
$header .= " *\n";
if (!empty($package['copyright'])) {
$header .= " * " . $package['copyright'] . "\n";
$header .= " *\n";
}
$header .= $LICENSES[$package['license']];
$header .= " *\n";
$header .= " * @licend The above is the entire license notice\n";
$header .= " * for the JavaScript code in this file.\n";
}
$header .= " */\n";
if (file_put_contents(INSTALL_PATH . $package['dest'], $header . file_get_contents($srcfile))) {
echo "Wrote file " . INSTALL_PATH . $package['dest'] . "\n";
}
else {
rcube::raise_error("Failed to write destination file " . INSTALL_PATH . $package['dest'], false, true);
}
}
/**
* Extract a Zip archive into the destination specified by the package config
*/
function extract_zipfile($package, $srcfile)
{
global $UNZIP, $CACHEDIR;
if (empty($UNZIP)) {
rcube::raise_error("Required 'unzip' program not found.", false, true);
}
$destdir = INSTALL_PATH . $package['dest'];
if (!is_dir($destdir)) {
mkdir($destdir, 0775, true);
}
if (!is_writeable($destdir)) {
rcube::raise_error("Cannot write to destination directory: $destdir", false, true);
}
// pick files from zip archive
if (!empty($package['pick'])) {
foreach ($package['pick'] as $pattern) {
echo "Extracting files $pattern into $destdir\n";
exec(sprintf('%s -o %s %s -d %s', $UNZIP, escapeshellarg($srcfile), escapeshellarg($pattern), $destdir), $out, $retval);
if ($retval !== 0) {
rcube::raise_error("Failed to unpack $pattern; " . implode('; ' . $out));
}
}
}
// unzip the archive and map source to dest files/directories
else if (!empty($package['map'])) {
$extract = $CACHEDIR . '/' . $package['lib'] . '-extract';
if (!is_dir($extract)) {
mkdir($extract, 0774, true);
}
$zip_command = '%s -' . ($package['flat'] ? 'j' : 'o') . ' %s -d %s';
exec(sprintf($zip_command, $UNZIP, escapeshellarg($srcfile), $extract), $out, $retval);
// get the root folder of the extracted package
$extract_tree = glob("$extract/*", GLOB_ONLYDIR);
$sourcedir = count($extract_tree) ? $extract_tree[0] : $extract;
foreach ($package['map'] as $src => $dest) {
echo "Installing $sourcedir/$src into $destdir/$dest\n";
$dest_file = $destdir . '/' . $dest;
$src_file = $sourcedir . '/' . $src;
// make sure the destination's parent directory exists
if (strpos($dest, '/') !== false) {
$parentdir = dirname($dest_file);
if (!is_dir($parentdir)) {
mkdir($parentdir, 0775, true);
}
}
// avoid copying source directory as a child into destination
if (is_dir($src_file) && is_dir($dest_file)) {
exec(sprintf('rm -rf %s', $dest_file));
}
exec(sprintf('mv -f %s %s', $src_file, $dest_file), $out, $retval);
if ($retval !== 0) {
rcube::raise_error("Failed to move $src into $dest_file; " . implode('; ' . $out));
}
// Remove sourceMappingURL
else if (isset($package['sourcemap']) && $package['sourcemap'] === false) {
if ($content = file($dest_file)) {
$index = count($content);
if (preg_match('|sourceMappingURL=|', $content[$index-1])) {
array_pop($content);
file_put_contents($dest_file, implode('', $content));
}
}
}
}
// remove temp extraction dir
exec('rm -rf ' . $extract);
}
// extract the archive into the destination directory
else {
echo "Extracting zip archive into $destdir\n";
exec(sprintf('%s -o %s -d %s', $UNZIP, escapeshellarg($srcfile), $destdir), $out, $retval);
if ($retval !== 0) {
rcube::raise_error("Failed to unzip $srcfile; " . implode('; ' . $out));
}
}
// remove some files from the destination
if (!empty($package['omit'])) {
foreach ((array)$package['omit'] as $glob) {
exec(sprintf('rm -rf %s/%s', $destdir, escapeshellarg($glob)));
}
}
// prepend license header to extracted files
if (!empty($package['addlicense'])) {
foreach ((array)$package['addlicense'] as $filename) {
$pkg = $package;
$pkg['dest'] = $package['dest'] . '/' . $filename;
compose_destfile($pkg, $destdir . '/' . $filename);
}
}
}
/**
* Delete the package destination file/dir
*/
function delete_destfile($package)
{
$destdir = INSTALL_PATH . ($package['rm'] ?: $package['dest']);
if (file_exists($destdir)) {
if (PHP_OS === 'Windows') {
exec(sprintf("rd /s /q %s", escapeshellarg($destdir)));
}
else {
exec(sprintf("rm -rf %s", escapeshellarg($destdir)));
}
}
}
//////////////// Execution
$args = rcube_utils::get_opt(array('f' => 'force:bool', 'd' => 'delete:bool', 'g' => 'get:bool', 'e' => 'extract:bool'))
+ array('force' => false, 'delete' => false, 'get' => false, 'extract' => false);
$WHAT = $args[0];
$useCache = !$args['force'] && !$args['get'];
if (!$args['get'] && !$args['extract'] && !$args['delete']) {
$args['get'] = $args['extract'] = 1;
}
foreach ($SOURCES['dependencies'] as $package) {
if (!isset($package['name'])) {
$package['name'] = $package['lib'];
}
if ($WHAT && $package['lib'] !== $WHAT) {
continue;
}
if ($args['delete']) {
delete_destfile($package);
continue;
}
if ($args['get']) {
$srcfile = fetch_from_source($package, $useCache, $filetype);
}
else {
$srcfile = extract_filetype($package, $filetype);
}
if (!empty($package['sha1']) && ($sum = sha1_file($srcfile)) !== $package['sha1']) {
rcube::raise_error("Incorrect sha1 sum of $srcfile. Expected: {$package['sha1']}, got: $sum", false, true);
}
if ($args['extract']) {
echo "Installing {$package['name']}...\n";
if ($filetype === 'zip') {
extract_zipfile($package, $srcfile);
}
else {
compose_destfile($package, $srcfile);
}
echo "Done.\n";
}
}

@ -2,9 +2,10 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/installto.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -18,131 +19,63 @@
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require_once INSTALL_PATH . 'program/include/clisetup.php';
if (!function_exists('system')) {
rcube::raise_error("PHP system() function is required. Check disable_functions in php.ini.", false, true);
}
$target_dir = unslashify(end($_SERVER['argv']));
$accept = in_array('-y', $_SERVER['argv']) ? 'y' : null;
$target_dir = unslashify($_SERVER['argv'][1]);
if (empty($target_dir) || !is_dir(realpath($target_dir)))
rcube::raise_error("Invalid target: not a directory\nUsage: installto.sh [-y] <TARGET>", false, true);
rcube::raise_error("Invalid target: not a directory\nUsage: installto.sh <TARGET>", false, true);
// read version from iniset.php
$iniset = @file_get_contents($target_dir . '/program/include/iniset.php');
if (!preg_match('/define\(.RCMAIL_VERSION.,\s*.([0-9.]+[a-z0-9-]*)/', $iniset, $m))
rcube::raise_error("No valid Roundcube installation found at $target_dir", false, true);
if (!preg_match('/define\(.RCMAIL_VERSION.,\s*.([0-9.]+[a-z-]*)/', $iniset, $m))
rcube::raise_error("No valid Roundcube installation found at $target_dir", false, true);
$oldversion = $m[1];
if (version_compare(version_parse($oldversion), version_parse(RCMAIL_VERSION), '>'))
rcube::raise_error("Target installation already in version $oldversion.", false, true);
if (version_compare(version_parse($oldversion), version_parse(RCMAIL_VERSION), '>='))
rcube::raise_error("Installation at target location is up-to-date!", false, true);
if (version_compare(version_parse($oldversion), version_parse(RCMAIL_VERSION), '==')) {
echo "Target installation already in version $oldversion. Do you want to update again? (y/N)\n";
}
else {
echo "Upgrading from $oldversion. Do you want to continue? (y/N)\n";
}
$input = $accept ?: trim(fgets(STDIN));
echo "Upgrading from $oldversion. Do you want to continue? (y/N)\n";
$input = trim(fgets(STDIN));
if (strtolower($input) == 'y') {
echo "Copying files to target location...";
$adds = array();
$dirs = array('bin','SQL','plugins','skins','program');
if (is_dir(INSTALL_PATH . 'vendor') && !is_file("$target_dir/composer.json")) {
$dirs[] = 'vendor';
}
if (file_exists("$target_dir/installer")) {
$dirs[] = 'installer';
}
foreach ($dirs as $dir) {
// @FIXME: should we use --delete for all directories?
$delete = in_array($dir, array('program', 'vendor', 'installer')) ? '--delete ' : '';
$command = "rsync -aC --out-format=%n " . $delete . INSTALL_PATH . "$dir/ $target_dir/$dir/";
if (system($command, $ret) === false || $ret > 0) {
rcube::raise_error("Failed to execute command: $command", false, true);
}
}
foreach (array('index.php','config/defaults.inc.php','composer.json-dist','jsdeps.json','CHANGELOG','README.md','UPGRADING','LICENSE','INSTALL') as $file) {
$command = "rsync -a --out-format=%n " . INSTALL_PATH . "$file $target_dir/$file";
if (file_exists(INSTALL_PATH . $file) && (system($command, $ret) === false || $ret > 0)) {
rcube::raise_error("Failed to execute command: $command", false, true);
}
$err = false;
echo "Copying files to target location...";
foreach (array('program','installer','bin','SQL','plugins','skins') as $dir) {
if (!system("rsync -avC " . INSTALL_PATH . "$dir/* $target_dir/$dir/")) {
$err = true;
break;
}
// Copy .htaccess or .user.ini if needed
foreach (array('.htaccess','.user.ini') as $file) {
if (file_exists(INSTALL_PATH . $file)) {
if (!file_exists("$target_dir/$file") || file_get_contents(INSTALL_PATH . $file) != file_get_contents("$target_dir/$file")) {
if (copy(INSTALL_PATH . $file, "$target_dir/$file.new")) {
echo "$file.new\n";
$adds[] = "NOTICE: New $file file saved as $file.new.";
}
}
}
}
// remove old (<1.0) .htaccess file
@unlink("$target_dir/program/.htaccess");
echo "done.\n\n";
if (is_dir("$target_dir/skins/default")) {
echo "Removing old default skin...";
system("rm -rf $target_dir/skins/default $target_dir/plugins/jqueryui/themes/default");
foreach (glob(INSTALL_PATH . "plugins/*/skins") as $plugin_skin_dir) {
$plugin_skin_dir = preg_replace('!^.*' . INSTALL_PATH . '!', '', $plugin_skin_dir);
if (is_dir("$target_dir/$plugin_skin_dir/classic")) {
system("rm -rf $target_dir/$plugin_skin_dir/default");
}
}
echo "done.\n\n";
}
// Warn about situation when using "complete" package to update "custom" installation (#7087)
// Note: "Complete" package do not include jsdeps.json nor install-jsdeps.sh
if (file_exists("$target_dir/jsdeps.json") && !file_exists(INSTALL_PATH . "jsdeps.json")) {
$adds[] = "WARNING: JavaScript dependencies update skipped.";
}
// check if js-deps are up-to-date
else if (file_exists("$target_dir/jsdeps.json") && file_exists("$target_dir/bin/install-jsdeps.sh")) {
$jsdeps = json_decode(file_get_contents("$target_dir/jsdeps.json"));
$package = $jsdeps->dependencies[0];
$dest_file = $target_dir . '/' . $package->dest;
if (!file_exists($dest_file) || sha1_file($dest_file) !== $package->sha1) {
echo "Installing JavaScript dependencies...";
system("cd $target_dir && bin/install-jsdeps.sh");
echo "done.\n\n";
}
}
foreach (array('index.php','.htaccess','config/defaults.inc.php','CHANGELOG','README.md','UPGRADING','LICENSE') as $file) {
if (!system("rsync -av " . INSTALL_PATH . "$file $target_dir/$file")) {
$err = true;
break;
}
else {
$adds[] = "NOTICE: JavaScript dependencies installation skipped.";
}
if (file_exists("$target_dir/installer")) {
$adds[] = "NOTICE: The 'installer' directory still exists. You should remove it after the upgrade.";
}
if (!empty($adds)) {
echo implode("\n", $adds) . "\n\n";
}
}
echo "done.\n\n";
if (is_dir("$target_dir/skins/default")) {
echo "Removing old default skin...";
system("rm -rf $target_dir/skins/default $target_dir/plugins/jqueryui/themes/default");
foreach (glob(INSTALL_PATH . "plugins/*/skins") as $plugin_skin_dir) {
$plugin_skin_dir = preg_replace('!^.*' . INSTALL_PATH . '!', '', $plugin_skin_dir);
if (is_dir("$target_dir/$plugin_skin_dir/classic"))
system("rm -rf $target_dir/$plugin_skin_dir/default");
}
echo "done.\n\n";
}
if (!$err) {
echo "Running update script at target...\n";
system("cd $target_dir && php bin/update.sh --version=$oldversion" . ($accept ? ' -y' : ''));
system("cd $target_dir && php bin/update.sh --version=$oldversion");
echo "All done.\n";
}
}
else {
echo "Update cancelled. See ya!\n";
}
else
echo "Update cancelled. See ya!\n";
?>

@ -2,61 +2,61 @@
PWD=`dirname "$0"`
JS_DIR="$PWD/../program/js"
JAR_DIR='/tmp'
LANG_IN='ECMASCRIPT5'
CLOSURE_COMPILER_URL='http://dl.google.com/closure-compiler/compiler-latest.zip'
LANG_IN='ECMASCRIPT3'
# latest version requires Java 7, we'll use an older one
#CLOSURE_COMPILER_URL='http://dl.google.com/closure-compiler/compiler-latest.zip'
CLOSURE_COMPILER_URL='http://dl.google.com/closure-compiler/compiler-20131014.zip'
do_shrink() {
rm -f "$2"
# copy the first comment block with license information for LibreJS
grep -q '@lic' $1 && sed -n '/\/\*/,/\*\// { p; /\*\//q; }' $1 > $2
java -jar $JAR_DIR/compiler.jar --compilation_level=SIMPLE_OPTIMIZATIONS --js="$1" --language_in="$3" >> $2
rm -f "$2"
java -jar $JAR_DIR/compiler.jar --compilation_level=SIMPLE_OPTIMIZATIONS --js="$1" --js_output_file="$2" --language_in="$3"
}
if [ ! -d "$JS_DIR" ]; then
echo "Directory $JS_DIR not found."
exit 1
echo "Directory $JS_DIR not found."
exit 1
fi
if [ ! -w "$JAR_DIR" ]; then
JAR_DIR=$PWD
JAR_DIR=$PWD
fi
if java -version >/dev/null 2>&1; then
:
:
else
echo "Java not found. Please ensure that the 'java' program is in your PATH."
exit 1
echo "Java not found. Please ensure that the 'java' program is in your PATH."
exit 1
fi
if [ ! -r "$JAR_DIR/compiler.jar" ]; then
if which wget >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
wget "$CLOSURE_COMPILER_URL" -O "/tmp/$$.zip"
elif which curl >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
curl "$CLOSURE_COMPILER_URL" -o "/tmp/$$.zip"
else
echo "Please download $CLOSURE_COMPILER_URL and extract compiler.jar to $JAR_DIR/."
exit 1
fi
unzip -p "/tmp/$$.zip" "*.jar" > "$JAR_DIR/compiler.jar"
rm -f "/tmp/$$.zip"
if which wget >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
wget "$CLOSURE_COMPILER_URL" -O "/tmp/$$.zip"
elif which curl >/dev/null 2>&1 && which unzip >/dev/null 2>&1; then
curl "$CLOSURE_COMPILER_URL" -o "/tmp/$$.zip"
else
echo "Please download $CLOSURE_COMPILER_URL and extract compiler.jar to $JAR_DIR/."
exit 1
fi
(cd $JAR_DIR && unzip "/tmp/$$.zip" "compiler.jar")
rm -f "/tmp/$$.zip"
fi
# compress single file from argument
if [ $# -gt 0 ]; then
JS_DIR=`dirname "$1"`
JS_FILE="$1"
JS_DIR=`dirname "$1"`
JS_FILE="$1"
if [ $# -gt 1 ]; then
LANG_IN="$2"
fi
if [ $# -gt 1 ]; then
LANG_IN="$2"
fi
echo "Shrinking $JS_FILE"
echo "Shrinking $JS_FILE"
minfile=`echo $JS_FILE | sed -e 's/\.js$/\.min\.js/'`
do_shrink "$JS_FILE" "$minfile" "$LANG_IN"
exit
do_shrink "$JS_FILE" "$minfile" "$LANG_IN"
exit
fi
DIRS="$PWD/../program/js $PWD/../skins/* $PWD/../plugins/* $PWD/../plugins/*/skins/* $PWD/../plugins/managesieve/codemirror/lib"
DIRS="$PWD/../program/js $PWD/../skins/* $PWD/../plugins/* $PWD/../plugins/*/skins/*"
# default: compress application scripts
for dir in $DIRS; do
for file in $dir/*.js; do

@ -1,23 +0,0 @@
#!/bin/sh
TITLE="Roundcube Webmail"
PACKAGES="Webmail"
INSTALL_PATH="`dirname $0`/.."
PATH_PROJECT=$INSTALL_PATH/program/include
PATH_FRAMEWORK=$INSTALL_PATH/program/lib/Roundcube
PATH_DOCS=$INSTALL_PATH/doc/phpdoc
BIN_PHPDOC="`/usr/bin/which phpdoc`"
if [ ! -x "$BIN_PHPDOC" ]
then
echo "phpdoc not found: $BIN_PHPDOC"
exit 1
fi
OUTPUTFORMAT=HTML
TEMPLATE=responsive-twig
# make documentation
$BIN_PHPDOC -d $PATH_PROJECT,$PATH_FRAMEWORK -t $PATH_DOCS --title "$TITLE" \
--defaultpackagename $PACKAGES --template=$TEMPLATE

@ -2,9 +2,10 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/moduserprefs.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -17,49 +18,65 @@
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require_once INSTALL_PATH.'program/include/clisetup.php';
function print_usage()
{
print "Usage: moduserprefs.sh [options] pref-name [pref-value]\n";
print "Options:\n";
print " --user=user-id User ID in local database\n";
print " --config=path Location of additional configuration file\n";
print " --delete Unset the given preference\n";
print " --type=type Pref-value type: int, bool, string\n";
print "Usage: moduserprefs.sh [--user=user-id] pref-name [pref-value|--delete]\n";
print "--user User ID in local database\n";
print "--delete Unset the given preference\n";
}
// get arguments
$args = rcube_utils::get_opt(array(
'u' => 'user',
'd' => 'delete:bool',
't' => 'type',
'c' => 'config',
));
$args = rcube_utils::get_opt(array('u' => 'user', 'd' => 'delete'));
if ($_SERVER['argv'][1] == 'help') {
print_usage();
exit;
print_usage();
exit;
}
else if (empty($args[0]) || (empty($args[1]) && empty($args['delete']))) {
print "Missing required parameters.\n";
print_usage();
exit;
else if (empty($args[0]) || (!isset($args[1]) && !$args['delete'])) {
print "Missing required parameters.\n";
print_usage();
exit;
}
$pref_name = trim($args[0]);
$pref_value = $args['delete'] ? null : trim($args[1]);
if ($pref_value === null) {
$args['type'] = null;
}
// connect to DB
$rcmail = rcmail::get_instance();
$db = $rcmail->get_dbh();
$db->db_connect('w');
if (!$db->is_connected() || $db->is_error())
die("No DB connection\n" . $db->is_error());
$query = '1=1';
if ($args['user'])
$query = 'user_id=' . intval($args['user']);
// iterate over all users
$sql_result = $db->query("SELECT * FROM " . $db->table_name('users') . " WHERE $query");
while ($sql_result && ($sql_arr = $db->fetch_assoc($sql_result))) {
echo "Updating prefs for user " . $sql_arr['user_id'] . "...";
$user = new rcube_user($sql_arr['user_id'], $sql_arr);
$prefs = $old_prefs = $user->get_prefs();
$prefs[$pref_name] = $pref_value;
if ($args['config']) {
$rcube = rcube::get_instance();
$rcube->config->load_from_file($args['config']);
if ($prefs != $old_prefs) {
$user->save_prefs($prefs, true);
echo "saved.\n";
}
else {
echo "nothing changed.\n";
}
}
rcmail_utils::mod_pref($pref_name, $pref_value, $args['user'], $args['type']);
?>

@ -1,104 +1,96 @@
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| 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. |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <thomas@roundcube.net> |
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
ini_set('memory_limit', -1);
require_once INSTALL_PATH.'program/include/clisetup.php';
function print_usage()
{
print "Usage: msgexport -h imap-host -u user-name -m mailbox name\n";
print "--host IMAP host\n";
print "--user IMAP user name\n";
print "--mbox Folder name, set to '*' for all\n";
print "--file Output file\n";
print "Usage: msgexport -h imap-host -u user-name -m mailbox name\n";
print "--host IMAP host\n";
print "--user IMAP user name\n";
print "--mbox Folder name, set to '*' for all\n";
print "--file Output file\n";
}
function vputs($str)
{
$out = $GLOBALS['args']['file'] ? STDOUT : STDERR;
fwrite($out, $str);
$out = $GLOBALS['args']['file'] ? STDOUT : STDERR;
fwrite($out, $str);
}
function progress_update($pos, $max)
{
$percent = round(100 * $pos / $max);
vputs(sprintf("%3d%% [%-51s] %d/%d\033[K\r", $percent, @str_repeat('=', $percent / 2) . '>', $pos, $max));
$percent = round(100 * $pos / $max);
vputs(sprintf("%3d%% [%-51s] %d/%d\033[K\r", $percent, @str_repeat('=', $percent / 2) . '>', $pos, $max));
}
function export_mailbox($mbox, $filename)
{
global $IMAP;
global $IMAP;
$IMAP->set_folder($mbox);
$IMAP->set_folder($mbox);
$index = $IMAP->index($mbox, null, 'ASC');
$count = $index->count();
$index = $index->get();
vputs("Getting message list of {$mbox}...");
vputs("$count messages\n");
if ($filename) {
if (!($out = fopen($filename, 'w'))) {
vputs("Cannot write to output file\n");
return;
}
vputs("Writing to $filename\n");
}
else {
$out = STDOUT;
}
for ($i = 0; $i < $count; $i++) {
$headers = $IMAP->get_message_headers($index[$i]);
$from = current(rcube_mime::decode_address_list($headers->from, 1, false));
fwrite($out, sprintf("From %s %s UID %d\n", $from['mailto'], $headers->date, $headers->uid));
$IMAP->get_raw_body($headers->uid, $out);
fwrite($out, "\n\n\n");
progress_update($i+1, $count);
}
vputs("\ncomplete.\n");
if ($filename) {
fclose($out);
}
vputs("Getting message list of {$mbox}...");
vputs("$count messages\n");
if ($filename)
{
if (!($out = fopen($filename, 'w')))
{
vputs("Cannot write to output file\n");
return;
}
vputs("Writing to $filename\n");
}
else
$out = STDOUT;
for ($i = 0; $i < $count; $i++)
{
$headers = $IMAP->get_message_headers($index[$i]);
$from = current(rcube_mime::decode_address_list($headers->from, 1, false));
fwrite($out, sprintf("From %s %s UID %d\n", $from['mailto'], $headers->date, $headers->uid));
$IMAP->get_raw_body($headers->uid, $out);
fwrite($out, "\n\n\n");
progress_update($i+1, $count);
}
vputs("\ncomplete.\n");
if ($filename)
fclose($out);
}
// get arguments
$opts = array('h' => 'host', 'u' => 'user', 'p' => 'pass', 'm' => 'mbox', 'f' => 'file');
$args = rcube_utils::get_opt($opts) + array('host' => 'localhost', 'mbox' => 'INBOX');
if ($_SERVER['argv'][1] == 'help') {
print_usage();
exit;
if ($_SERVER['argv'][1] == 'help')
{
print_usage();
exit;
}
else if (!$args['host']) {
vputs("Missing required parameters.\n");
print_usage();
exit;
else if (!$args['host'])
{
vputs("Missing required parameters.\n");
print_usage();
exit;
}
// prompt for username if not set
if (empty($args['user'])) {
vputs("IMAP user: ");
$args['user'] = trim(fgets(STDIN));
if (empty($args['user']))
{
vputs("IMAP user: ");
$args['user'] = trim(fgets(STDIN));
}
// prompt for password
@ -107,39 +99,45 @@ $args['pass'] = rcube_utils::prompt_silent("Password: ");
// parse $host URL
$a_host = parse_url($args['host']);
if ($a_host['host']) {
$host = $a_host['host'];
$imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE;
$imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : 143);
if ($a_host['host'])
{
$host = $a_host['host'];
$imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE;
$imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : 143);
}
else {
$host = $args['host'];
$imap_port = 143;
else
{
$host = $args['host'];
$imap_port = 143;
}
// instantiate IMAP class
$IMAP = new rcube_imap(null);
// try to connect to IMAP server
if ($IMAP->connect($host, $args['user'], $args['pass'], $imap_port, $imap_ssl)) {
vputs("IMAP login successful.\n");
if ($IMAP->connect($host, $args['user'], $args['pass'], $imap_port, $imap_ssl))
{
vputs("IMAP login successful.\n");
$filename = null;
$mailboxes = $args['mbox'] == '*' ? $IMAP->list_folders(null) : array($args['mbox']);
$filename = null;
$mailboxes = $args['mbox'] == '*' ? $IMAP->list_folders(null) : array($args['mbox']);
foreach ($mailboxes as $mbox) {
if ($args['file'])
$filename = preg_replace('/\.[a-z0-9]{3,4}$/i', '', $args['file']) . asciiwords($mbox) . '.mbox';
else if ($args['mbox'] == '*')
$filename = asciiwords($mbox) . '.mbox';
foreach ($mailboxes as $mbox)
{
if ($args['file'])
$filename = preg_replace('/\.[a-z0-9]{3,4}$/i', '', $args['file']) . asciiwords($mbox) . '.mbox';
else if ($args['mbox'] == '*')
$filename = asciiwords($mbox) . '.mbox';
if ($args['mbox'] == '*' && in_array(strtolower($mbox), array('junk','spam','trash'))) {
continue;
}
if ($args['mbox'] == '*' && in_array(strtolower($mbox), array('junk','spam','trash')))
continue;
export_mailbox($mbox, $filename);
}
export_mailbox($mbox, $filename);
}
}
else {
vputs("IMAP login failed.\n");
else
{
vputs("IMAP login failed.\n");
}
?>

@ -1,31 +1,18 @@
#!/usr/bin/env php
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| 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. |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <thomas@roundcube.net> |
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
ini_set('memory_limit', -1);
require_once INSTALL_PATH.'program/include/clisetup.php';
function print_usage()
{
print "Usage: msgimport -h imap-host -u user-name -m mailbox -f message-file\n";
print "--host IMAP host\n";
print "--user IMAP user name\n";
print "--mbox Target mailbox\n";
print "--file Message file to upload\n";
print "Usage: msgimport -h imap-host -u user-name -m mailbox -f message-file\n";
print "--host IMAP host\n";
print "--user IMAP user name\n";
print "--mbox Target mailbox\n";
print "--file Message file to upload\n";
}
@ -33,80 +20,94 @@ function print_usage()
$opts = array('h' => 'host', 'u' => 'user', 'p' => 'pass', 'm' => 'mbox', 'f' => 'file');
$args = rcube_utils::get_opt($opts) + array('host' => 'localhost', 'mbox' => 'INBOX');
if ($_SERVER['argv'][1] == 'help') {
print_usage();
exit;
if ($_SERVER['argv'][1] == 'help')
{
print_usage();
exit;
}
else if (!($args['host'] && $args['file'])) {
print "Missing required parameters.\n";
print_usage();
exit;
else if (!($args['host'] && $args['file']))
{
print "Missing required parameters.\n";
print_usage();
exit;
}
else if (!is_file($args['file'])) {
rcube::raise_error("Cannot read message file.", false, true);
else if (!is_file($args['file']))
{
rcube::raise_error("Cannot read message file.", false, true);
}
// prompt for username if not set
if (empty($args['user'])) {
//fwrite(STDOUT, "Please enter your name\n");
echo "IMAP user: ";
$args['user'] = trim(fgets(STDIN));
if (empty($args['user']))
{
//fwrite(STDOUT, "Please enter your name\n");
echo "IMAP user: ";
$args['user'] = trim(fgets(STDIN));
}
// prompt for password
if (empty($args['pass'])) {
$args['pass'] = rcube_utils::prompt_silent("Password: ");
if (empty($args['pass']))
{
$args['pass'] = rcube_utils::prompt_silent("Password: ");
}
// parse $host URL
$a_host = parse_url($args['host']);
if ($a_host['host']) {
$host = $a_host['host'];
$imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE;
$imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : 143);
if ($a_host['host'])
{
$host = $a_host['host'];
$imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE;
$imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : 143);
}
else {
$host = $args['host'];
$imap_port = 143;
else
{
$host = $args['host'];
$imap_port = 143;
}
// instantiate IMAP class
$IMAP = new rcube_imap(null);
// try to connect to IMAP server
if ($IMAP->connect($host, $args['user'], $args['pass'], $imap_port, $imap_ssl)) {
print "IMAP login successful.\n";
print "Uploading messages...\n";
$count = 0;
$message = $lastline = '';
$fp = fopen($args['file'], 'r');
while (($line = fgets($fp)) !== false) {
if (preg_match('/^From\s+-/', $line) && $lastline == '') {
if (!empty($message)) {
if ($IMAP->save_message($args['mbox'], rtrim($message)))
$count++;
else
rcube::raise_error("Failed to save message to {$args['mbox']}", false, true);
$message = '';
}
continue;
}
$message .= $line;
$lastline = rtrim($line);
}
if (!empty($message) && $IMAP->save_message($args['mbox'], rtrim($message)))
$count++;
// upload message from file
if ($count)
print "$count messages successfully added to {$args['mbox']}.\n";
else
print "Adding messages failed!\n";
if ($IMAP->connect($host, $args['user'], $args['pass'], $imap_port, $imap_ssl))
{
print "IMAP login successful.\n";
print "Uploading messages...\n";
$count = 0;
$message = $lastline = '';
$fp = fopen($args['file'], 'r');
while (($line = fgets($fp)) !== false)
{
if (preg_match('/^From\s+-/', $line) && $lastline == '')
{
if (!empty($message))
{
if ($IMAP->save_message($args['mbox'], rtrim($message)))
$count++;
else
rcube::raise_error("Failed to save message to {$args['mbox']}", false, true);
$message = '';
}
continue;
}
$message .= $line;
$lastline = rtrim($line);
}
if (!empty($message) && $IMAP->save_message($args['mbox'], rtrim($message)))
$count++;
// upload message from file
if ($count)
print "$count messages successfully added to {$args['mbox']}.\n";
else
print "Adding messages failed!\n";
}
else {
rcube::raise_error("IMAP login failed.", false, true);
else
{
rcube::raise_error("IMAP login failed.", false, true);
}
?>

@ -2,9 +2,10 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/package2composer.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2013, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -12,6 +13,7 @@
| |
| PURPOSE: |
| Convert a plugin's package.xml file into a composer.json description |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <thomas@roundcube.net> |
+-----------------------------------------------------------------------+
@ -40,7 +42,7 @@ $data = array(
'version' => strval($package->version->release),
'authors' => array(),
'repositories' => array(
array('type' => 'composer', 'url' => 'https://plugins.roundcube.net'),
array('type' => 'composer', 'url' => 'http://plugins.roundcube.net'),
),
'require' => array(
'php' => '>=5.3.0',
@ -95,7 +97,7 @@ else if (defined('JSON_PRETTY_PRINT')) {
echo json_encode($data, $flags);
}
else {
fwrite(STDERR,
fputs(STDERR,
"FAILED! composer.phar not found in current directory.
Please download it from http://getcomposer.org/download/ or with
@ -104,3 +106,4 @@ Please download it from http://getcomposer.org/download/ or with
}
echo "\n";

@ -6,7 +6,7 @@
# Note: there's a bug in txclib, so if the command below doesn't
# work see https://github.com/transifex/transifex-client/commit/a80320735973dd608b48520bf3b89ad53e2b088b
tx --debug pull -a -f --mode translator
tx --debug pull -a --mode translator
PWD=`dirname "$0"`
@ -18,8 +18,8 @@ do_clean()
echo "Cleaning $1"
# remove untranslated/empty texts
perl -pi -e "s/^\\\$(labels|messages)\[[^]]+\]\s+=\s+'';\n//" $1
perl -pi -e "s/^\\\$(labels|messages)\[[^]]+\]\s+=\s+\"\";\n//" $1
perl -pi -e "s/^\\\$labels\[[^]]+\]\s+=\s+'';\n//" $1
perl -pi -e "s/^\\\$messages\[[^]]+\]\s+=\s+'';\n//" $1
# remove variable initialization
perl -pi -e "s/^\\\$(labels|messages)\s*=\s*array\(\);\n//" $1
# remove (one-line) comments
@ -39,6 +39,6 @@ done
# remove empty localization files
for file in $PWD/../program/localization/*/labels.inc; do grep -q -E '\$labels' $file || rm $file; done
for file in $PWD/../program/localization/*/timezones.inc; do grep -q -E '\$labels' $file || rm $file; done
for file in $PWD/../program/localization/*/messages.inc; do grep -q -E '\$messages' $file || rm $file; done
for file in $PWD/../plugins/*/localization/*.inc; do grep -q -E '\$(labels|messages)' $file || rm $file; done

@ -2,9 +2,10 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/update.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2010-2013, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -18,276 +19,163 @@
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require_once INSTALL_PATH . 'program/include/clisetup.php';
require_once INSTALL_PATH . 'installer/rcube_install.php';
// get arguments
$opts = rcube_utils::get_opt(array('v' => 'version', 'y' => 'accept:bool'));
$opts = rcube_utils::get_opt(array('v' => 'version', 'y' => 'accept'));
// ask user if no version is specified
if (!$opts['version']) {
echo "What version are you upgrading from? Type '?' if you don't know.\n";
if (($input = trim(fgets(STDIN))) && preg_match('/^[0-9.]+[a-z0-9-]*$/', $input)) {
$opts['version'] = $input;
}
else {
$opts['version'] = RCMAIL_VERSION;
}
echo "What version are you upgrading from? Type '?' if you don't know.\n";
if (($input = trim(fgets(STDIN))) && preg_match('/^[0-9.]+[a-z-]*$/', $input))
$opts['version'] = $input;
else
$opts['version'] = RCMAIL_VERSION;
}
$RCI = rcmail_install::get_instance();
$RCI = rcube_install::get_instance();
$RCI->load_config();
if ($RCI->configured) {
$success = true;
if (($messages = $RCI->check_config($opts['version'])) || $RCI->legacy_config) {
$success = false;
$err = 0;
// list old/replaced config options
if (is_array($messages['replaced'])) {
echo "WARNING: Replaced config options:\n";
echo "(These config options have been replaced or renamed)\n";
foreach ($messages['replaced'] as $msg) {
echo "- '" . $msg['prop'] . "' was replaced by '" . $msg['replacement'] . "'\n";
$err++;
}
}
// list obsolete config options (just a notice)
if (is_array($messages['obsolete'])) {
echo "NOTICE: Obsolete config options:\n";
echo "(You still have some obsolete or inexistent properties set."
. " This isn't a problem but should be noticed)\n";
foreach ($messages['obsolete'] as $msg) {
echo "- '" . $msg['prop'] . ($msg['name'] ? "': " . $msg['name'] : "'") . "\n";
$err++;
}
}
if (!$err && $RCI->legacy_config) {
echo "WARNING: Your configuration needs to be migrated!\n";
echo "We changed the configuration files structure and your two config files "
. "main.inc.php and db.inc.php have to be merged into one single file.\n";
$err++;
}
// ask user to update config files
if ($err) {
if (!$opts['accept']) {
echo "Do you want me to fix your local configuration? (y/N)\n";
$input = trim(fgets(STDIN));
}
// positive: merge the local config with the defaults
if ($opts['accept'] || strtolower($input) == 'y') {
$error = $written = false;
echo ". backing up the current config file(s)...\n";
foreach (array('config', 'main', 'db') as $file) {
if (file_exists(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php')) {
if (!copy(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php', RCMAIL_CONFIG_DIR . '/' . $file . '.old.php')) {
$error = true;
}
}
}
if (!$error) {
$RCI->merge_config();
echo ". writing " . RCMAIL_CONFIG_DIR . "/config.inc.php...\n";
$written = $RCI->save_configfile($RCI->create_config());
}
// Success!
if ($written) {
echo "Done.\n";
echo "Your configuration files are now up-to-date!\n";
if ($messages['missing']) {
echo "But you still need to add the following missing options:\n";
foreach ($messages['missing'] as $msg) {
echo "- '" . $msg['prop'] . ($msg['name'] ? "': " . $msg['name'] : "'") . "\n";
}
}
if ($RCI->legacy_config) {
foreach (array('main', 'db') as $file) {
@unlink(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php');
}
}
}
else {
echo "Failed to write config file(s)!\n";
echo "Grant write privileges to the current user or update the files manually "
. "according to the above messages.\n";
}
}
else {
echo "Please update your config files manually according to the above messages.\n";
}
}
// list of config options with changed default (just a notice)
if (!empty($messages['defaults'])) {
echo "WARNING: Changed defaults (These config options have new default values):\n";
foreach ($messages['defaults'] as $opt) {
echo "- '{$opt}'\n";
}
}
// check dependencies based on the current configuration
if (is_array($messages['dependencies'])) {
echo "WARNING: Dependency check failed!\n";
echo "(Some of your configuration settings require other options to be configured "
. "or additional PHP modules to be installed)\n";
foreach ($messages['dependencies'] as $msg) {
echo "- " . $msg['prop'] . ': ' . $msg['explain'] . "\n";
}
echo "Please fix your config files and run this script again!\n";
echo "See ya.\n";
}
$success = true;
if (($messages = $RCI->check_config()) || $RCI->legacy_config) {
$success = false;
$err = 0;
// list old/replaced config options
if (is_array($messages['replaced'])) {
echo "WARNING: Replaced config options:\n";
echo "(These config options have been replaced or renamed)\n";
foreach ($messages['replaced'] as $msg) {
echo "- '" . $msg['prop'] . "' was replaced by '" . $msg['replacement'] . "'\n";
$err++;
}
echo "\n";
}
// check file type detection
if ($RCI->check_mime_detection()) {
echo "WARNING: File type detection doesn't work properly!\n";
echo "Please check the 'mime_magic' config option or the finfo functions of PHP and run this script again.\n";
}
if ($RCI->check_mime_extensions()) {
echo "WARNING: Mimetype to file extension mapping doesn't work properly!\n";
echo "Please check the 'mime_types' config option and run this script again.\n";
// list obsolete config options (just a notice)
if (is_array($messages['obsolete'])) {
echo "NOTICE: Obsolete config options:\n";
echo "(You still have some obsolete or inexistent properties set. This isn't a problem but should be noticed)\n";
foreach ($messages['obsolete'] as $msg) {
echo "- '" . $msg['prop'] . ($msg['name'] ? "': " . $msg['name'] : "'") . "\n";
$err++;
}
echo "\n";
}
// check database schema
if ($RCI->config['db_dsnw']) {
echo "Executing database schema update.\n";
$success = rcmail_utils::db_update(INSTALL_PATH . 'SQL', 'roundcube', $opts['version'],
array('errors' => true));
if (!$err && $RCI->legacy_config) {
echo "WARNING: Your configuration needs to be migrated!\n";
echo "We changed the configuration files structure and your two config files main.inc.php and db.inc.php have to be merged into one single file.\n";
$err++;
}
// update composer dependencies
if (is_file(INSTALL_PATH . 'composer.json') && is_readable(INSTALL_PATH . 'composer.json-dist')) {
$composer_data = json_decode(file_get_contents(INSTALL_PATH . 'composer.json'), true);
$composer_template = json_decode(file_get_contents(INSTALL_PATH . 'composer.json-dist'), true);
$comsposer_json = null;
// ask user to update config files
if ($err) {
if (!$opts['accept']) {
echo "Do you want me to fix your local configuration? (y/N)\n";
$input = trim(fgets(STDIN));
}
// update the require section with the new dependencies
if (is_array($composer_data['require']) && is_array($composer_template['require'])) {
$composer_data['require'] = array_merge($composer_data['require'], $composer_template['require']);
// positive: let's merge the local config with the defaults
if ($opts['accept'] || strtolower($input) == 'y') {
$error = $written = false;
// remove obsolete packages
$old_packages = array(
'pear-pear.php.net/net_socket',
'pear-pear.php.net/auth_sasl',
'pear-pear.php.net/net_idna2',
'pear-pear.php.net/mail_mime',
'pear-pear.php.net/net_smtp',
'pear-pear.php.net/crypt_gpg',
'pear-pear.php.net/net_sieve',
'pear/mail_mime-decode',
'roundcube/net_sieve',
'endroid/qrcode',
);
// backup current config
echo ". backing up the current config file(s)...\n";
foreach ($old_packages as $pkg) {
if (array_key_exists($pkg, $composer_data['require'])) {
unset($composer_data['require'][$pkg]);
}
foreach (array('config', 'main', 'db') as $file) {
if (file_exists(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php')) {
if (!copy(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php', RCMAIL_CONFIG_DIR . '/' . $file . '.old.php')) {
$error = true;
}
}
}
// update the repositories section with the new dependencies
if (is_array($composer_template['repositories'])) {
if (!is_array($composer_data['repositories'])) {
$composer_data['repositories'] = array();
}
foreach ($composer_template['repositories'] as $repo) {
$rkey = $repo['type'] . preg_replace('/^https?:/', '', $repo['url']) . $repo['package']['name'];
$existing = false;
if (!$error) {
$RCI->merge_config();
echo ". writing " . RCMAIL_CONFIG_DIR . "/config.inc.php...\n";
$written = $RCI->save_configfile($RCI->create_config());
}
foreach ($composer_data['repositories'] as $k => $_repo) {
if ($rkey == $_repo['type'] . preg_replace('/^https?:/', '', $_repo['url']) . $_repo['package']['name']) {
// switch to https://
if (isset($_repo['url']) && strpos($_repo['url'], 'http://') === 0) {
$composer_data['repositories'][$k]['url'] = 'https:' . substr($_repo['url'], 5);
}
// Success!
if ($written) {
echo "Done.\n";
echo "Your configuration files are now up-to-date!\n";
$existing = true;
break;
}
// remove old repos
if (strpos($_repo['url'], 'git://git.kolab.org') === 0) {
unset($composer_data['repositories'][$k]);
}
else if ($_repo['type'] == 'package' && $_repo['package']['name'] == 'Net_SMTP') {
unset($composer_data['repositories'][$k]);
}
}
if ($messages['missing']) {
echo "But you still need to add the following missing options:\n";
foreach ($messages['missing'] as $msg)
echo "- '" . $msg['prop'] . ($msg['name'] ? "': " . $msg['name'] : "'") . "\n";
}
if (!$existing) {
$composer_data['repositories'][] = $repo;
}
if ($RCI->legacy_config) {
foreach (array('main', 'db') as $file) {
@unlink(RCMAIL_CONFIG_DIR . '/' . $file . '.inc.php');
}
$composer_data['repositories'] = array_values($composer_data['repositories']);
}
// use the JSON encoder from the Composer package
if (is_file('composer.phar')) {
include 'phar://composer.phar/src/Composer/Json/JsonFile.php';
$comsposer_json = \Composer\Json\JsonFile::encode($composer_data);
}
// PHP 5.4's json_encode() does the job, too
else if (defined('JSON_PRETTY_PRINT')) {
$comsposer_json = json_encode($composer_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
else {
$success = false;
$comsposer_json = null;
}
// write updated composer.json back to disk
if ($comsposer_json && is_writeable(INSTALL_PATH . 'composer.json')) {
$success &= (bool)file_put_contents(INSTALL_PATH . 'composer.json', $comsposer_json);
}
}
else {
echo "WARNING: unable to update composer.json!\n";
echo "Please replace the 'require' section in your composer.json with the following:\n";
$require_json = '';
foreach ($composer_data['require'] as $pkg => $ver) {
$require_json .= sprintf(' "%s": "%s",'."\n", $pkg, $ver);
}
echo ' "require": {'."\n";
echo rtrim($require_json, ",\n");
echo "\n }\n\n";
echo "Failed to write config file(s)!\n";
echo "Grant write privileges to the current user or update the files manually according to the above messages.\n";
}
echo "NOTICE: Update dependencies by running `php composer.phar update --no-dev`\n";
}
else {
echo "Please update your config files manually according to the above messages.\n";
}
}
// index contacts for fulltext searching
if ($opts['version'] && version_compare(version_parse($opts['version']), '0.6.0', '<')) {
rcmail_utils::indexcontacts();
}
// check dependencies based on the current configuration
if (is_array($messages['dependencies'])) {
echo "WARNING: Dependency check failed!\n";
echo "(Some of your configuration settings require other options to be configured or additional PHP modules to be installed)\n";
if ($success) {
echo "This instance of Roundcube is up-to-date.\n";
echo "Have fun!\n";
foreach ($messages['dependencies'] as $msg) {
echo "- " . $msg['prop'] . ': ' . $msg['explain'] . "\n";
}
echo "Please fix your config files and run this script again!\n";
echo "See ya.\n";
}
}
// check file type detection
if ($RCI->check_mime_detection()) {
echo "WARNING: File type detection doesn't work properly!\n";
echo "Please check the 'mime_magic' config option or the finfo functions of PHP and run this script again.\n";
}
if ($RCI->check_mime_extensions()) {
echo "WARNING: Mimetype to file extension mapping doesn't work properly!\n";
echo "Please check the 'mime_types' config option and run this script again.\n";
}
// check database schema
if ($RCI->config['db_dsnw']) {
echo "Executing database schema update.\n";
system("php " . INSTALL_PATH . "bin/updatedb.sh --package=roundcube --version=" . $opts['version']
. " --dir=" . INSTALL_PATH . DIRECTORY_SEPARATOR . "SQL", $res);
$success = !$res;
}
// index contacts for fulltext searching
if ($opts['version'] && version_compare(version_parse($opts['version']), '0.6.0', '<')) {
system("php " . INSTALL_PATH . 'bin/indexcontacts.sh');
}
if ($success) {
echo "This instance of Roundcube is up-to-date.\n";
echo "Have fun!\n";
}
}
else {
echo "This instance of Roundcube is not yet configured!\n";
echo "Open http://url-to-roundcube/installer/ in your browser and follow the instuctions.\n";
echo "This instance of Roundcube is not yet configured!\n";
echo "Open http://url-to-roundcube/installer/ in your browser and follow the instuctions.\n";
}
?>

@ -2,9 +2,10 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/updatecss.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2010-2013, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -17,7 +18,7 @@
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require_once INSTALL_PATH . 'program/include/clisetup.php';
@ -117,3 +118,5 @@ function get_files($dir)
return $files;
}
?>

@ -2,10 +2,11 @@
<?php
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| bin/updatedb.sh |
| |
| Copyright (C) The Roundcube Dev Team |
| Copyright (C) Kolab Systems AG |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2010-2012, The Roundcube Dev Team |
| Copyright (C) 2010-2012, Kolab Systems AG |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -18,7 +19,7 @@
+-----------------------------------------------------------------------+
*/
define('INSTALL_PATH', realpath(__DIR__ . '/..') . '/' );
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/..') . '/' );
require_once INSTALL_PATH . 'program/include/clisetup.php';
@ -36,4 +37,141 @@ if (empty($opts['package'])) {
rcube::raise_error("Database schema package name not specified (--package).", false, true);
}
rcmail_utils::db_update($opts['dir'], $opts['package'], $opts['version'], array('errors' => true));
// Check if directory exists
if (!file_exists($opts['dir'])) {
rcube::raise_error("Specified database schema directory doesn't exist.", false, true);
}
$RC = rcube::get_instance();
$DB = rcube_db::factory($RC->config->get('db_dsnw'));
// Connect to database
$DB->db_connect('w');
if (!$DB->is_connected()) {
rcube::raise_error("Error connecting to database: " . $DB->is_error(), false, true);
}
// Read DB schema version from database (if 'system' table exists)
if (in_array($DB->table_name('system'), (array)$DB->list_tables())) {
$DB->query("SELECT " . $DB->quote_identifier('value')
." FROM " . $DB->quote_identifier($DB->table_name('system'))
." WHERE " . $DB->quote_identifier('name') ." = ?",
$opts['package'] . '-version');
$row = $DB->fetch_array();
$version = preg_replace('/[^0-9]/', '', $row[0]);
}
// DB version not found, but release version is specified
if (!$version && $opts['version']) {
// Map old release version string to DB schema version
// Note: This is for backward compat. only, do not need to be updated
$map = array(
'0.1-stable' => 1,
'0.1.1' => 2008030300,
'0.2-alpha' => 2008040500,
'0.2-beta' => 2008060900,
'0.2-stable' => 2008092100,
'0.2.1' => 2008092100,
'0.2.2' => 2008092100,
'0.3-stable' => 2008092100,
'0.3.1' => 2009090400,
'0.4-beta' => 2009103100,
'0.4' => 2010042300,
'0.4.1' => 2010042300,
'0.4.2' => 2010042300,
'0.5-beta' => 2010100600,
'0.5' => 2010100600,
'0.5.1' => 2010100600,
'0.5.2' => 2010100600,
'0.5.3' => 2010100600,
'0.5.4' => 2010100600,
'0.6-beta' => 2011011200,
'0.6' => 2011011200,
'0.7-beta' => 2011092800,
'0.7' => 2011111600,
'0.7.1' => 2011111600,
'0.7.2' => 2011111600,
'0.7.3' => 2011111600,
'0.7.4' => 2011111600,
'0.8-beta' => 2011121400,
'0.8-rc' => 2011121400,
'0.8.0' => 2011121400,
'0.8.1' => 2011121400,
'0.8.2' => 2011121400,
'0.8.3' => 2011121400,
'0.8.4' => 2011121400,
'0.8.5' => 2011121400,
'0.8.6' => 2011121400,
'0.9-beta' => 2012080700,
);
$version = $map[$opts['version']];
}
// Assume last version before the 'system' table was added
if (empty($version)) {
$version = 2012080700;
}
$dir = $opts['dir'] . DIRECTORY_SEPARATOR . $DB->db_provider;
if (!file_exists($dir)) {
rcube::raise_error("DDL Upgrade files for " . $DB->db_provider . " driver not found.", false, true);
}
$dh = opendir($dir);
$result = array();
while ($file = readdir($dh)) {
if (preg_match('/^([0-9]+)\.sql$/', $file, $m) && $m[1] > $version) {
$result[] = $m[1];
}
}
sort($result, SORT_NUMERIC);
foreach ($result as $v) {
echo "Updating database schema ($v)... ";
$error = update_db_schema($opts['package'], $v, $dir . DIRECTORY_SEPARATOR . "$v.sql");
if ($error) {
echo "[FAILED]\n";
rcube::raise_error("Error in DDL upgrade $v: $error", false, true);
}
echo "[OK]\n";
}
function update_db_schema($package, $version, $file)
{
global $DB;
// read DDL file
if ($sql = file_get_contents($file)) {
if (!$DB->exec_script($sql)) {
return $DB->is_error();
}
}
// escape if 'system' table does not exist
if ($version < 2013011000) {
return;
}
$system_table = $DB->quote_identifier($DB->table_name('system'));
$DB->query("UPDATE " . $system_table
." SET " . $DB->quote_identifier('value') . " = ?"
." WHERE " . $DB->quote_identifier('name') . " = ?",
$version, $package . '-version');
if (!$DB->is_error() && !$DB->affected_rows()) {
$DB->query("INSERT INTO " . $system_table
." (" . $DB->quote_identifier('name') . ", " . $DB->quote_identifier('value') . ")"
." VALUES (?, ?)",
$package . '-version', $version);
}
return $DB->is_error();
}
?>

@ -5,27 +5,12 @@
"repositories": [
{
"type": "composer",
"url": "https://plugins.roundcube.net"
"url": "http://plugins.roundcube.net/"
}
],
"require": {
"php": ">=5.4.0",
"pear/pear-core-minimal": "~1.10.1",
"pear/auth_sasl": "~1.1.0",
"pear/net_idna2": "~0.2.0",
"pear/mail_mime": "~1.10.0",
"pear/net_smtp": "~1.8.1",
"pear/crypt_gpg": "~1.6.3",
"pear/net_sieve": "~1.4.3",
"roundcube/plugin-installer": "~0.1.6",
"masterminds/html5": "~2.5.0",
"endroid/qr-code": "~1.6.5"
"php": ">=5.3.0",
"roundcube/plugin-installer": ">=0.1.3"
},
"require-dev": {
"phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6 || ^7"
},
"suggest": {
"kolab/net_ldap3": "~1.1.1 required for connecting to LDAP",
"mkopinsky/zxcvbn-php": "^4.4.2 required for Zxcvbn password strength driver"
}
"minimum-stability": "dev"
}

@ -1,7 +0,0 @@
# deny webserver access to this directory
<ifModule mod_authz_core.c>
Require all denied
</ifModule>
<ifModule !mod_authz_core.c>
Deny from all
</ifModule>

@ -4,12 +4,12 @@
+-----------------------------------------------------------------------+
| Local configuration for the Roundcube Webmail installation. |
| |
| This is a sample configuration file only containing the minimum |
| This is a sample configuration file only containing the minumum |
| setup required for a functional installation. Copy more options |
| from defaults.inc.php to this file to override the defaults. |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) The Roundcube Dev Team |
| Copyright (C) 2005-2013, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -21,17 +21,15 @@ $config = array();
// Database connection string (DSN) for read+write operations
// Format (compatible with PEAR MDB2): db_provider://user:password@host/database
// Currently supported db_providers: mysql, pgsql, sqlite, mssql, sqlsrv, oracle
// Currently supported db_providers: mysql, pgsql, sqlite, mssql or sqlsrv
// For examples see http://pear.php.net/manual/en/package.database.mdb2.intro-dsn.php
// NOTE: for SQLite use absolute path (Linux): 'sqlite:////full/path/to/sqlite.db?mode=0646'
// or (Windows): 'sqlite:///C:/full/path/to/sqlite.db'
// NOTE: for SQLite use absolute path: 'sqlite:////full/path/to/sqlite.db?mode=0646'
$config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
// The IMAP host chosen to perform the log-in.
// The mail host chosen to perform the log-in.
// Leave blank to show a textbox at login, give a list of hosts
// to display a pulldown menu or set one host as string.
// Enter hostname with prefix ssl:// to use Implicit TLS, or use
// prefix tls:// to use STARTTLS.
// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
// Supported replacement variables:
// %n - hostname ($_SERVER['SERVER_NAME'])
// %t - hostname without the first part
@ -41,8 +39,8 @@ $config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
$config['default_host'] = 'localhost';
// SMTP server host (for sending mails).
// Enter hostname with prefix ssl:// to use Implicit TLS, or use
// prefix tls:// to use STARTTLS.
// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
// If left blank, the PHP mail() function is used
// Supported replacement variables:
// %h - user's IMAP hostname
// %n - hostname ($_SERVER['SERVER_NAME'])
@ -50,20 +48,19 @@ $config['default_host'] = 'localhost';
// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
// %z - IMAP domain (IMAP hostname without the first part)
// For example %n = mail.domain.tld, %t = domain.tld
// To specify differnt SMTP servers for different IMAP hosts provide an array
// of IMAP host (no prefix or port) and SMTP server e.g. array('imap.example.com' => 'smtp.example.net')
$config['smtp_server'] = 'localhost';
$config['smtp_server'] = '';
// SMTP port. Use 25 for cleartext, 465 for Implicit TLS, or 587 for STARTTLS (default)
$config['smtp_port'] = 587;
// SMTP port (default is 25; use 587 for STARTTLS or 465 for the
// deprecated SSL over SMTP (aka SMTPS))
$config['smtp_port'] = 25;
// SMTP username (if required) if you use %u as the username Roundcube
// will use the current username for login
$config['smtp_user'] = '%u';
$config['smtp_user'] = '';
// SMTP password (if required) if you use %p as the password Roundcube
// will use the current user's password for login
$config['smtp_pass'] = '%p';
$config['smtp_pass'] = '';
// provide an URL where a user can get support for this Roundcube installation
// PLEASE DO NOT LINK TO THE ROUNDCUBE.NET WEBSITE HERE!
@ -72,9 +69,9 @@ $config['support_url'] = '';
// Name your service. This is displayed on the login screen and in the window title
$config['product_name'] = 'Roundcube Webmail';
// This key is used to encrypt the users imap password which is stored
// in the session record. For the default cipher method it must be
// exactly 24 characters long.
// this key is used to encrypt the users imap password which is stored
// in the session record (and the client cookie if remember password is enabled).
// please provide a string of exactly 24 chars.
// YOUR KEY MUST BE DIFFERENT THAN THE SAMPLE VALUE FOR SECURITY REASONS
$config['des_key'] = 'rcmail-!24ByteDESkey*Str';
@ -85,4 +82,4 @@ $config['plugins'] = array(
);
// skin name: folder from skins/
$config['skin'] = 'elastic';
$config['skin'] = 'larry';

@ -1,15 +1,11 @@
<?php
// ---------------------------------------------------------------------
// WARNING: Do not edit this file! Copy configuration to config.inc.php.
// ---------------------------------------------------------------------
/*
+-----------------------------------------------------------------------+
| Default settings for all configuration options |
| Main configuration file with default settings |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) The Roundcube Dev Team |
| Copyright (C) 2005-2013, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -25,14 +21,9 @@ $config = array();
// Database connection string (DSN) for read+write operations
// Format (compatible with PEAR MDB2): db_provider://user:password@host/database
// Currently supported db_providers: mysql, pgsql, sqlite, mssql, sqlsrv, oracle
// Currently supported db_providers: mysql, pgsql, sqlite, mssql or sqlsrv
// For examples see http://pear.php.net/manual/en/package.database.mdb2.intro-dsn.php
// Note: for SQLite use absolute path (Linux): 'sqlite:////full/path/to/sqlite.db?mode=0646'
// or (Windows): 'sqlite:///C:/full/path/to/sqlite.db'
// Note: Various drivers support various additional arguments for connection,
// for Mysql: key, cipher, cert, capath, ca, verify_server_cert,
// for Postgres: application_name, sslmode, sslcert, sslkey, sslrootcert, sslcrl, sslcompression, service.
// e.g. 'mysql://roundcube:@localhost/roundcubemail?verify_server_cert=false'
// NOTE: for SQLite use absolute path: 'sqlite:////full/path/to/sqlite.db?mode=0646'
$config['db_dsnw'] = 'mysql://roundcube:@localhost/roundcubemail';
// Database DSN for read-only operations (if empty write database will be used)
@ -60,31 +51,21 @@ $config['db_table_dsn'] = array(
// 'cache_messages' => 'r',
);
// It is possible to specify database variable values e.g. some limits here.
// Use them if your server is not MySQL or for better performance.
// For example Roundcube uses max_allowed_packet value (in bytes)
// which limits query size for database cache operations.
$config['db_max_allowed_packet'] = null;
// ----------------------------------
// LOGGING/DEBUGGING
// ----------------------------------
// log driver: 'syslog', 'stdout' or 'file'.
// system error reporting, sum of: 1 = log; 4 = show, 8 = trace
$config['debug_level'] = 1;
// log driver: 'syslog' or 'file'.
$config['log_driver'] = 'file';
// date format for log entries
// (read http://php.net/manual/en/function.date.php for all format characters)
$config['log_date_format'] = 'd-M-Y H:i:s O';
// length of the session ID to prepend each log line with
// set to 0 to avoid session IDs being logged.
$config['log_session_id'] = 8;
// Default extension used for log file name
$config['log_file_ext'] = '.log';
// Syslog ident string to use, if using the 'syslog' log driver.
$config['syslog_id'] = 'roundcube';
@ -93,49 +74,38 @@ $config['syslog_id'] = 'roundcube';
$config['syslog_facility'] = LOG_USER;
// Activate this option if logs should be written to per-user directories.
// Data will only be logged if a directory <log_dir>/<username>/ exists and is writable.
// Data will only be logged if a directry <log_dir>/<username>/ exists and is writable.
$config['per_user_logging'] = false;
// Log sent messages to <log_dir>/sendmail.log or to syslog
// Log sent messages to <log_dir>/sendmail or to syslog
$config['smtp_log'] = true;
// Log successful/failed logins to <log_dir>/userlogins.log or to syslog
// Log successful/failed logins to <log_dir>/userlogins or to syslog
$config['log_logins'] = false;
// Log session debug information/authentication errors to <log_dir>/session.log or to syslog
$config['session_debug'] = false;
// Log session authentication errors to <log_dir>/session or to syslog
$config['log_session'] = false;
// Log SQL queries to <log_dir>/sql.log or to syslog
// Log SQL queries to <log_dir>/sql or to syslog
$config['sql_debug'] = false;
// Log IMAP conversation to <log_dir>/imap.log or to syslog
// Log IMAP conversation to <log_dir>/imap or to syslog
$config['imap_debug'] = false;
// Log LDAP conversation to <log_dir>/ldap.log or to syslog
// Log LDAP conversation to <log_dir>/ldap or to syslog
$config['ldap_debug'] = false;
// Log SMTP conversation to <log_dir>/smtp.log or to syslog
// Log SMTP conversation to <log_dir>/smtp or to syslog
$config['smtp_debug'] = false;
// Log Memcache conversation to <log_dir>/memcache.log or to syslog
$config['memcache_debug'] = false;
// Log APC conversation to <log_dir>/apc.log or to syslog
$config['apc_debug'] = false;
// Log Redis conversation to <log_dir>/redis.log or to syslog
$config['redis_debug'] = false;
// ----------------------------------
// IMAP
// ----------------------------------
// The IMAP host chosen to perform the log-in.
// The mail host chosen to perform the log-in.
// Leave blank to show a textbox at login, give a list of hosts
// to display a pulldown menu or set one host as string.
// Enter hostname with prefix ssl:// to use Implicit TLS, or use
// prefix tls:// to use STARTTLS.
// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
// Supported replacement variables:
// %n - hostname ($_SERVER['SERVER_NAME'])
// %t - hostname without the first part
@ -149,9 +119,8 @@ $config['default_host'] = 'localhost';
// TCP port used for IMAP connections
$config['default_port'] = 143;
// IMAP authentication method (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or null).
// Use 'IMAP' to authenticate with IMAP LOGIN command.
// By default the most secure method (from supported) will be selected.
// IMAP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or null to use
// best server supported one)
$config['imap_auth_type'] = null;
// IMAP socket context options
@ -164,7 +133,6 @@ $config['imap_auth_type'] = null;
// 'cafile' => '/etc/openssl/certs/ca.crt',
// ),
// );
// Note: These can be also specified as an array of options indexed by hostname
$config['imap_conn_options'] = null;
// IMAP connection timeout, in seconds. Default: 0 (use default_socket_timeout)
@ -180,18 +148,12 @@ $config['imap_auth_pw'] = null;
// Otherwise it will be determined automatically
$config['imap_delimiter'] = null;
// If you know your imap's folder vendor, you can specify it here.
// Otherwise it will be determined automatically. Use lower-case
// identifiers, e.g. 'dovecot', 'cyrus', 'gimap', 'hmail', 'uw-imap'.
$config['imap_vendor'] = null;
// If IMAP server doesn't support NAMESPACE extension, but you're
// using shared folders or personal root folder is non-empty, you'll need to
// set these options. All can be strings or arrays of strings.
// Note: Folders need to be ended with directory separator, e.g. "INBOX."
// (special directory "~" is an exception to this rule)
// Note: These can be used also to overwrite server's namespaces
// Note: Set these to FALSE to disable access to specified namespace
// Folders need to be ended with directory separator, e.g. "INBOX."
// (special directory "~" is an exception to this rule)
// These can be used also to overwrite server's namespaces
$config['imap_ns_personal'] = null;
$config['imap_ns_other'] = null;
$config['imap_ns_shared'] = null;
@ -203,7 +165,7 @@ $config['imap_force_caps'] = false;
// By default list of subscribed folders is determined using LIST-EXTENDED
// extension if available. Some servers (dovecot 1.x) returns wrong results
// for shared namespaces in this case. https://github.com/roundcube/roundcubemail/issues/2474
// for shared namespaces in this case. http://trac.roundcube.net/ticket/1486225
// Enable this option to force LSUB command usage instead.
// Deprecated: Use imap_disabled_caps = array('LIST-EXTENDED')
$config['imap_force_lsub'] = false;
@ -212,16 +174,6 @@ $config['imap_force_lsub'] = false;
// Enable this option to force listing of folders in all namespaces
$config['imap_force_ns'] = false;
// Some servers return hidden folders (name starting witha dot)
// from user home directory. IMAP RFC does not forbid that.
// Enable this option to hide them and disable possibility to create such.
$config['imap_skip_hidden_folders'] = false;
// Some servers do not support folders with both folders and messages inside
// If your server supports that use true, if it does not, use false.
// By default it will be determined automatically (once per user session).
$config['imap_dual_use_folders'] = null;
// List of disabled imap extensions.
// Use if your IMAP server has broken implementation of some feature
// and you can't remove it from CAPABILITY string on server-side.
@ -229,11 +181,7 @@ $config['imap_dual_use_folders'] = null;
// Note: Because the list is cached, re-login is required after change.
$config['imap_disabled_caps'] = array();
// Log IMAP session identifiers after each IMAP login.
// This is used to relate IMAP session with Roundcube user sessions
$config['imap_log_session'] = false;
// Type of IMAP indexes cache. Supported values: 'db', 'apc' and 'memcache' or 'memcached'.
// Type of IMAP indexes cache. Supported values: 'db', 'apc' and 'memcache'.
$config['imap_cache'] = null;
// Enables messages cache. Only 'db' cache is supported.
@ -258,8 +206,8 @@ $config['messages_cache_threshold'] = 50;
// ----------------------------------
// SMTP server host (for sending mails).
// Enter hostname with prefix ssl:// to use Implicit TLS, or use
// prefix tls:// to use STARTTLS.
// To use SSL/TLS connection, enter hostname with prefix ssl:// or tls://
// If left blank, the PHP mail() function is used
// Supported replacement variables:
// %h - user's IMAP hostname
// %n - hostname ($_SERVER['SERVER_NAME'])
@ -267,24 +215,23 @@ $config['messages_cache_threshold'] = 50;
// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
// %z - IMAP domain (IMAP hostname without the first part)
// For example %n = mail.domain.tld, %t = domain.tld
// To specify differnt SMTP servers for different IMAP hosts provide an array
// of IMAP host (no prefix or port) and SMTP server e.g. array('imap.example.com' => 'smtp.example.net')
$config['smtp_server'] = 'localhost';
$config['smtp_server'] = '';
// SMTP port. Use 25 for cleartext, 465 for Implicit TLS, or 587 for STARTTLS (default)
$config['smtp_port'] = 587;
// SMTP port (default is 25; use 587 for STARTTLS or 465 for the
// deprecated SSL over SMTP (aka SMTPS))
$config['smtp_port'] = 25;
// SMTP username (if required) if you use %u as the username Roundcube
// will use the current username for login
$config['smtp_user'] = '%u';
$config['smtp_user'] = '';
// SMTP password (if required) if you use %p as the password Roundcube
// will use the current user's password for login
$config['smtp_pass'] = '%p';
$config['smtp_pass'] = '';
// SMTP AUTH type (DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN or empty to use
// best server supported one)
$config['smtp_auth_type'] = null;
$config['smtp_auth_type'] = '';
// Optional SMTP authentication identifier to be used as authorization proxy
$config['smtp_auth_cid'] = null;
@ -314,7 +261,6 @@ $config['smtp_timeout'] = 0;
// 'cafile' => '/etc/openssl/certs/ca.crt',
// ),
// );
// Note: These can be also specified as an array of options indexed by hostname
$config['smtp_conn_options'] = null;
@ -322,55 +268,12 @@ $config['smtp_conn_options'] = null;
// LDAP
// ----------------------------------
// Type of LDAP cache. Supported values: 'db', 'apc' and 'memcache' or 'memcached'.
// Type of LDAP cache. Supported values: 'db', 'apc' and 'memcache'.
$config['ldap_cache'] = 'db';
// Lifetime of LDAP cache. Possible units: s, m, h, d, w
$config['ldap_cache_ttl'] = '10m';
// ----------------------------------
// CACHE(S)
// ----------------------------------
// Use these hosts for accessing memcached
// Define any number of hosts in the form of hostname:port or unix:///path/to/socket.file
// Example: array('localhost:11211', '192.168.1.12:11211', 'unix:///var/tmp/memcached.sock');
$config['memcache_hosts'] = null;
// Controls the use of a persistent connections to memcache servers
// See http://php.net/manual/en/memcache.addserver.php
$config['memcache_pconnect'] = true;
// Value in seconds which will be used for connecting to the daemon
// See http://php.net/manual/en/memcache.addserver.php
$config['memcache_timeout'] = 1;
// Controls how often a failed server will be retried (value in seconds).
// Setting this parameter to -1 disables automatic retry.
// See http://php.net/manual/en/memcache.addserver.php
$config['memcache_retry_interval'] = 15;
// Use these hosts for accessing Redis.
// Currently only one host is supported. Cluster support may come in a future release.
// You can pass 4 fields, host, port (optional), database (optional) and password (optional).
// Unset fields will be set to the default values host=127.0.0.1, port=6379.
// Examples:
// array('localhost:6379');
// array('192.168.1.1:6379:1:secret');
// array('unix:///var/run/redis/redis-server.sock:1:secret');
$config['redis_hosts'] = null;
// Maximum size of an object in memcache (in bytes). Default: 2MB
$config['memcache_max_allowed_packet'] = '2M';
// Maximum size of an object in APC cache (in bytes). Default: 2MB
$config['apc_max_allowed_packet'] = '2M';
// Maximum size of an object in Redis cache (in bytes). Default: 2MB
$config['redis_max_allowed_packet'] = '2M';
// ----------------------------------
// SYSTEM
// ----------------------------------
@ -379,12 +282,9 @@ $config['redis_max_allowed_packet'] = '2M';
// ONLY ENABLE IT IF YOU'RE REALLY SURE WHAT YOU'RE DOING!
$config['enable_installer'] = false;
// don't allow these settings to be overridden by the user
// don't allow these settings to be overriden by the user
$config['dont_override'] = array();
// List of disabled UI elements/actions
$config['disabled_actions'] = array();
// define which settings should be listed under the 'advanced' block
// which is hidden by default
$config['advanced_prefs'] = array();
@ -393,37 +293,10 @@ $config['advanced_prefs'] = array();
// PLEASE DO NOT LINK TO THE ROUNDCUBE.NET WEBSITE HERE!
$config['support_url'] = '';
// Logo image replacement. Specifies location of the image as:
// - URL relative to the document root of this Roundcube installation
// - full URL with http:// or https:// prefix
// - URL relative to the current skin folder (when starts with a '/')
//
// An array can be used to specify different logos for specific template files
// The array key specifies the place(s) the logo should be applied to and
// is made up of (up to) 3 parts:
// - skin name prefix (always with colon, can be replaced with *)
// - template name (or * for all templates)
// - logo type - it is used for logos used on multiple templates
// the available types include '[favicon]' for favicon, '[print]' for logo on all print
// templates (e.g. messageprint, contactprint) and '[small]' for small screen logo in supported skins
//
// Example config for skin_logo
/*
array(
// show the image /images/logo_login_small.png for the Login screen in the Elastic skin on small screens
"elastic:login[small]" => "/images/logo_login_small.png",
// show the image /images/logo_login.png for the Login screen in the Elastic skin
"elastic:login" => "/images/logo_login.png",
// show the image /images/logo_small.png in the Elastic skin
"elastic:*[small]" => "/images/logo_small.png",
// show the image /images/larry.png in the Larry skin
"larry:*" => "/images/larry.png",
// show the image /images/logo_login.png on the login template in all skins
"login" => "/images/logo_login.png",
// show the image /images/logo_print.png for all print type logos in all skins
"[print]" => "/images/logo_print.png",
);
*/
// replace Roundcube logo with this image
// specify an URL relative to the document root of this Roundcube installation
// an array can be used to specify different logos for specific template files, '*' for default logo
// for example array("*" => "/images/roundcube_logo.png", "messageprint" => "/images/roundcube_logo_print.png")
$config['skin_logo'] = null;
// automatically create a new Roundcube user when log-in the first time.
@ -434,23 +307,20 @@ $config['auto_create_user'] = true;
// Enables possibility to log in using email address from user identities
$config['user_aliases'] = false;
// use this folder to store log files
// must be writeable for the user who runs PHP process (Apache user if mod_php is being used)
// use this folder to store log files (must be writeable for apache user)
// This is used by the 'file' log driver.
$config['log_dir'] = RCUBE_INSTALL_PATH . 'logs/';
// use this folder to store temp files
// must be writeable for the user who runs PHP process (Apache user if mod_php is being used)
// use this folder to store temp files (must be writeable for apache user)
$config['temp_dir'] = RCUBE_INSTALL_PATH . 'temp/';
// expire files in temp_dir after 48 hours
// possible units: s, m, h, d, w
$config['temp_dir_ttl'] = '48h';
// Enforce connections over https
// With this option enabled, all non-secure connections will be redirected.
// It can be also a port number, hostname or hostname:port if they are
// different than default HTTP_HOST:443
// enforce connections over https
// with this option enabled, all non-secure connections will be redirected.
// set the port for the ssl connection as value of this option if it differs from the default 443
$config['force_https'] = false;
// tell PHP that it should work as under secure connection
@ -470,24 +340,11 @@ $config['login_autocomplete'] = 0;
// UPDATE users SET username = LOWER(username);
$config['login_lc'] = 2;
// Maximum length (in bytes) of logon username and password.
$config['login_username_maxlen'] = 1024;
$config['login_password_maxlen'] = 1024;
// Logon username filter. Regular expression for use with preg_match().
// Example: '/^[a-z0-9_@.-]+$/'
$config['login_username_filter'] = null;
// Brute-force attacks prevention.
// The value specifies maximum number of failed logon attempts per minute.
$config['login_rate_limit'] = 3;
// Includes should be interpreted as PHP files
$config['skin_include_php'] = false;
// display product name and software version on login screen
// 0 - hide product name and version number, 1 - show product name only, 2 - show product name and version number
$config['display_product_info'] = 1;
// display software version on login screen
$config['display_version'] = false;
// Session lifetime in minutes
$config['session_lifetime'] = 10;
@ -504,54 +361,35 @@ $config['session_auth_name'] = null;
// Session path. Defaults to PHP session.cookie_path setting.
$config['session_path'] = null;
// Session samesite. Defaults to PHP session.cookie_samesite setting.
// Requires PHP >= 7.3.0, see https://wiki.php.net/rfc/same-site-cookie for more info
// Possible values: null (default), 'Lax', or 'Strict'
$config['session_samesite'] = null;
// Backend to use for session storage. Can either be 'db' (default), 'redis', 'memcache', or 'php'
//
// If set to 'memcache' or 'memcached', a list of servers need to be specified in 'memcache_hosts'
// Make sure the Memcache extension (https://pecl.php.net/package/memcache) version >= 2.0.0
// or the Memcached extension (https://pecl.php.net/package/memcached) version >= 2.0.0 is installed.
//
// If set to 'redis', a server needs to be specified in 'redis_hosts'
// Make sure the Redis extension (https://pecl.php.net/package/redis) version >= 2.0.0 is installed.
//
// Backend to use for session storage. Can either be 'db' (default), 'memcache' or 'php'
// If set to 'memcache', a list of servers need to be specified in 'memcache_hosts'
// Make sure the Memcache extension (http://pecl.php.net/package/memcache) version >= 2.0.0 is installed
// Setting this value to 'php' will use the default session save handler configured in PHP
$config['session_storage'] = 'db';
// Use these hosts for accessing memcached
// Define any number of hosts in the form of hostname:port or unix:///path/to/socket.file
$config['memcache_hosts'] = null; // e.g. array( 'localhost:11211', '192.168.1.12:11211', 'unix:///var/tmp/memcached.sock' );
// check client IP in session authorization
$config['ip_check'] = false;
// List of trusted proxies
// X_FORWARDED_* and X_REAL_IP headers are only accepted from these IPs
$config['proxy_whitelist'] = array();
// List of trusted host names
// Attackers can modify Host header of the HTTP request causing $_SERVER['SERVER_NAME']
// or $_SERVER['HTTP_HOST'] variables pointing to a different host, that could be used
// to collect user names and passwords. Some server configurations prevent that, but not all.
// An empty list accepts any host name. The list can contain host names
// or PCRE patterns (without // delimiters, that will be added automatically).
$config['trusted_host_patterns'] = array();
// check client IP in session authorization
$config['ip_check'] = false;
// check referer of incoming requests
$config['referer_check'] = false;
// X-Frame-Options HTTP header value sent to prevent from Clickjacking.
// Possible values: sameorigin|deny|allow-from <uri>.
// Set to false in order to disable sending the header.
// Possible values: sameorigin|deny. Set to false in order to disable sending them
$config['x_frame_options'] = 'sameorigin';
// This key is used for encrypting purposes, like storing of imap password
// in the session. For historical reasons it's called DES_key, but it's used
// with any configured cipher_method (see below).
// For the default cipher_method a required key length is 24 characters.
// this key is used to encrypt the users imap password which is stored
// in the session record (and the client cookie if remember password is enabled).
// please provide a string of exactly 24 chars.
$config['des_key'] = 'rcmail-!24ByteDESkey*Str';
// Encryption algorithm. You can use any method supported by OpenSSL.
// Default is set for backward compatibility to DES-EDE3-CBC,
// but you can choose e.g. AES-256-CBC which we consider a better choice.
$config['cipher_method'] = 'DES-EDE3-CBC';
// Automatically add this domain to user names for login
// Only for IMAP servers that require full e-mail addresses for login
// Specify an array with 'host' => 'domain' values to support multiple hosts
@ -578,40 +416,29 @@ $config['username_domain_forced'] = false;
// For example %n = mail.domain.tld, %t = domain.tld
$config['mail_domain'] = '';
// Password character set, to change the password for user
// authentication or for password change operations
$config['password_charset'] = 'UTF-8';
// Password charset.
// Use it if your authentication backend doesn't support UTF-8.
// Defaults to ISO-8859-1 for backward compatibility
$config['password_charset'] = 'ISO-8859-1';
// How many seconds must pass between emails sent by a user
$config['sendmail_delay'] = 0;
// Message size limit. Note that SMTP server(s) may use a different value.
// This limit is verified when user attaches files to a composed message.
// Size in bytes (possible unit suffix: K, M, G)
$config['max_message_size'] = '100M';
// Maximum number of recipients per message (including To, Cc, Bcc).
// Default: 0 (no limit)
$config['max_recipients'] = 0;
// Maximum number of recipients per message. Default: 0 (no limit)
$config['max_recipients'] = 0;
// Maximum number of recipients per message exluding Bcc header.
// This is a soft limit, which means we only display a warning to the user.
// Default: 5
$config['max_disclosed_recipients'] = 5;
// Maximum allowed number of members of an address group. Default: 0 (no limit)
// Maximum allowednumber of members of an address group. Default: 0 (no limit)
// If 'max_recipients' is set this value should be less or equal
$config['max_group_members'] = 0;
$config['max_group_members'] = 0;
// Name your service. This is displayed on the login screen and in the window title
$config['product_name'] = 'Roundcube Webmail';
// Add this user-agent to message headers when sending
$config['useragent'] = 'Roundcube Webmail/'.RCUBE_VERSION;
$config['useragent'] = 'Roundcube Webmail/'.RCMAIL_VERSION;
// try to load host-specific configuration
// see https://github.com/roundcube/roundcubemail/wiki/Configuration:-Multi-Domain-Setup
// for more details
// see http://trac.roundcube.net/wiki/Howto_Config for more details
$config['include_host_config'] = false;
// path to a text file which will be added to each sent message
@ -631,6 +458,10 @@ $config['http_received_header'] = false;
// when tracking down issues.
$config['http_received_header_encrypt'] = false;
// This string is used as a delimiter for message headers when sending
// a message via mail() function. Leave empty for auto-detection
$config['mail_header_delimiter'] = NULL;
// number of chars allowed for line when wrapping text.
// text wrapping is done when composing/sending messages
$config['line_length'] = 72;
@ -650,17 +481,10 @@ $config['mdn_use_from'] = false;
// 4 - one identity with possibility to edit only signature
$config['identities_level'] = 0;
// Maximum size of uploaded image in kilobytes
// Images (in html signatures) are stored in database as data URIs
$config['identity_image_size'] = 64;
// Mimetypes supported by the browser.
// Attachments of these types will open in a preview window.
// Either a comma-separated list or an array. Default list includes:
// text/plain,text/html,
// image/jpeg,image/gif,image/png,image/bmp,image/tiff,image/webp,
// application/x-javascript,application/pdf,application/x-shockwave-flash
$config['client_mimetypes'] = null;
// attachments of these types will open in a preview window
// either a comma-separated list or an array: 'text/plain,text/html,text/xml,image/jpeg,image/gif,image/png,application/pdf'
$config['client_mimetypes'] = null; # null == default
// Path to a local mime magic database file for PHPs finfo extension.
// Set to null if the default path should be used.
@ -672,10 +496,10 @@ $config['mime_magic'] = null;
// download it from http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
$config['mime_types'] = null;
// path to imagemagick identify binary (if not set we'll use Imagick or GD extensions)
// path to imagemagick identify binary
$config['im_identify_path'] = null;
// path to imagemagick convert binary (if not set we'll use Imagick or GD extensions)
// path to imagemagick convert binary
$config['im_convert_path'] = null;
// Size of thumbnails from image attachments displayed below the message content.
@ -693,28 +517,6 @@ $config['email_dns_check'] = false;
// Note: useful when SMTP server stores sent mail in user mailbox
$config['no_save_sent_messages'] = false;
// Improve system security by using special URL with security token.
// This can be set to a number defining token length. Default: 16.
// Warning: This requires http server configuration. Sample:
// RewriteRule ^/roundcubemail/[a-zA-Z0-9]{16}/(.*) /roundcubemail/$1 [PT]
// Alias /roundcubemail /var/www/roundcubemail/
// Note: Use assets_path to not prevent the browser from caching assets
$config['use_secure_urls'] = false;
// Allows to define separate server/path for image/js/css files
// Warning: If the domain is different cross-domain access to some
// resources need to be allowed
// Sample:
// <FilesMatch ".(eot|ttf|woff)">
// Header set Access-Control-Allow-Origin "*"
// </FilesMatch>
$config['assets_path'] = '';
// While assets_path is for the browser, assets_dir informs
// PHP code about the location of asset files in filesystem
$config['assets_dir'] = '';
// ----------------------------------
// PLUGINS
// ----------------------------------
@ -734,7 +536,7 @@ $config['message_sort_col'] = '';
$config['message_sort_order'] = 'DESC';
// These cols are shown in the message list. Available cols are:
// subject, from, to, fromto, cc, replyto, date, size, status, flag, attachment, priority
// subject, from, to, fromto, cc, replyto, date, size, status, flag, attachment, 'priority'
$config['list_cols'] = array('subject', 'status', 'fromto', 'date', 'size', 'flag', 'attachment');
// the default locale setting (leave empty for auto-detection)
@ -779,19 +581,26 @@ $config['sent_mbox'] = 'Sent';
// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
$config['trash_mbox'] = 'Trash';
// automatically create the above listed default folders on user login
// display these folders separately in the mailbox list.
// these folders will also be displayed with localized names
// NOTE: Use folder names with namespace prefix (INBOX. on Courier-IMAP)
$config['default_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash');
// Disable localization of the default folder names listed above
$config['show_real_foldernames'] = false;
// automatically create the above listed default folders on first login
$config['create_default_folders'] = false;
// protect the default folders from renames, deletes, and subscription changes
$config['protect_default_folders'] = true;
// Disable localization of the default folder names listed above
$config['show_real_foldernames'] = false;
// if in your system 0 quota means no limit set this option to true
$config['quota_zero_as_unlimited'] = false;
// Make use of the built-in spell checker. It is based on GoogieSpell.
// Since Google only accepts connections over https your PHP installatation
// requires to be compiled with Open SSL support
$config['enable_spellcheck'] = true;
// Enables spellchecker exceptions dictionary.
@ -799,13 +608,12 @@ $config['enable_spellcheck'] = true;
$config['spellcheck_dictionary'] = false;
// Set the spell checking engine. Possible values:
// - 'googie' - the default (also used for connecting to Nox Spell Server, see 'spellcheck_uri' setting)
// - 'googie' - the default
// - 'pspell' - requires the PHP Pspell module and aspell installed
// - 'enchant' - requires the PHP Enchant module
// - 'atd' - install your own After the Deadline server or check with the people at http://www.afterthedeadline.com before using their API
// Since Google shut down their public spell checking service, the default settings
// connect to http://spell.roundcube.net which is a hosted service provided by Roundcube.
// You can connect to any other googie-compliant service by setting 'spellcheck_uri' accordingly.
// Since Google shut down their public spell checking service, you need to
// connect to a Nox Spell Server when using 'googie' here. Therefore specify the 'spellcheck_uri'
$config['spellcheck_engine'] = 'googie';
// For locally installed Nox Spell Server or After the Deadline services,
@ -829,6 +637,9 @@ $config['spellcheck_ignore_nums'] = false;
// Makes that words with symbols will be ignored (e.g. g@@gle)
$config['spellcheck_ignore_syms'] = false;
// Use this char/string to separate recipients when composing a new message
$config['recipients_separator'] = ',';
// Number of lines at the end of a message considered to contain the signature.
// Increase this value if signatures are not properly detected and colored
$config['sig_max_lines'] = 15;
@ -839,6 +650,11 @@ $config['max_pagesize'] = 200;
// Minimal value of user's 'refresh_interval' setting (in seconds)
$config['min_refresh_interval'] = 60;
// Enables files upload indicator. Requires APC installed and enabled apc.rfc1867 option.
// By default refresh time is set to 1 second. You can set this value to true
// or any integer value indicating number of seconds.
$config['upload_progress'] = false;
// Specifies for how many seconds the Undo button will be available
// after object delete action. Currently used with supporting address book sources.
// Setting it to 0, disables the feature.
@ -850,19 +666,17 @@ $config['compose_responses_static'] = array(
// array('name' => 'Canned Response 2', 'text' => 'Static Response Two'),
);
// List of HKP key servers for PGP public key lookups in Enigma/Mailvelope
// Note: Lookup is client-side, so the server must support Cross-Origin Resource Sharing
$config['keyservers'] = array('keys.openpgp.org');
// ----------------------------------
// ADDRESSBOOK SETTINGS
// ----------------------------------
// This indicates which type of address book to use. Possible choises:
// 'sql' - built-in sql addressbook enabled (default),
// '' - built-in sql addressbook disabled.
// Still LDAP or plugin-added addressbooks will be available.
// BC Note: The value can actually be anything except 'sql', it does not matter.
// 'sql' (default), 'ldap' and ''.
// If set to 'ldap' then it will look at using the first writable LDAP
// address book as the primary address book and it will not display the
// SQL address book in the 'Address Book' view.
// If set to '' then no address book will be displayed or only the
// addressbook which is created by a plugin (like CardDAV).
$config['address_book_type'] = 'sql';
// In order to enable public ldap search, configure an array like the Verisign
@ -895,7 +709,6 @@ $config['ldap_public']['Verisign'] = array(
// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
// %z - IMAP domain (IMAP hostname without the first part)
// For example %n = mail.domain.tld, %t = domain.tld
// Note: Host can also be a full URI e.g. ldaps://hostname.local:636 (for SSL)
'hosts' => array('directory.verisign.com'),
'port' => 389,
'use_tls' => false,
@ -919,10 +732,6 @@ $config['ldap_public']['Verisign'] = array(
// DN and password to bind as before searching for bind DN, if anonymous search is not allowed
'search_bind_dn' => '',
'search_bind_pw' => '',
// Base DN and filter used for resolving the user's domain root DN which feeds the %dc variables
// Leave empty to skip this lookup and derive the root DN from the username domain
'domain_base_dn' => '',
'domain_filter' => '',
// Optional map of replacement strings => attributes used when binding for an individual address book
'search_bind_attrib' => array(), // e.g. array('%udc' => 'ou')
// Default for %dn variable if search doesn't return DN value
@ -953,11 +762,8 @@ $config['ldap_public']['Verisign'] = array(
'required_fields' => array('cn', 'sn', 'mail'),
'search_fields' => array('mail', 'cn'), // fields to search in
// mapping of contact fields to directory attributes
// 1. for every attribute one can specify the number of values (limit) allowed.
// default is 1, a wildcard * means unlimited
// 2. another possible parameter is separator character for composite fields
// 3. it's possible to define field format for write operations, e.g. for date fields
// example: 'birthday:date[YmdHis\\Z]'
// for every attribute one can specify the number of values (limit) allowed.
// default is 1, a wildcard * means unlimited
'fieldmap' => array(
// Roundcube => LDAP:limit
'name' => 'cn',
@ -1007,9 +813,9 @@ $config['ldap_public']['Verisign'] = array(
// Used where addressbook contains aliases to objects elsewhere in the LDAP tree.
// definition for contact groups (uncomment if no groups are supported)
// for the groups base_dn, the user replacements %fu, %u, %d and %dc work as for base_dn (see above)
// for the groups base_dn, the user replacements %fu, %u, $d and %dc work as for base_dn (see above)
// if the groups base_dn is empty, the contact base_dn is used for the groups as well
// -> in this case, assure that groups and contacts are separated due to the concernig filters!
// -> in this case, assure that groups and contacts are separated due to the concernig filters!
'groups' => array(
'base_dn' => '',
'scope' => 'sub', // Search mode: sub|base|list
@ -1076,15 +882,6 @@ $config['address_template'] = '{street}<br/>{locality} {zipcode}<br/>{country} {
// Note: For LDAP sources fuzzy_search must be enabled to use 'partial' or 'prefix' mode
$config['addressbook_search_mode'] = 0;
// List of fields used on contacts list and for autocompletion searches
// Warning: These are field names not LDAP attributes (see 'fieldmap' setting)!
$config['contactlist_fields'] = array('name', 'firstname', 'surname', 'email');
// Template of contact entry on the autocompletion list.
// You can use contact fields as: name, email, organization, department, etc.
// See program/steps/addressbook/func.inc for a list
$config['contact_search_name'] = '{name} <{email}>';
// ----------------------------------
// USER PREFERENCES
// ----------------------------------
@ -1092,12 +889,8 @@ $config['contact_search_name'] = '{name} <{email}>';
// Use this charset as fallback for message decoding
$config['default_charset'] = 'ISO-8859-1';
// Skin name: folder from skins/
$config['skin'] = 'elastic';
// Limit skins available for the user.
// Note: When not empty, it should include the default skin set in 'skin' option.
$config['skins_allowed'] = array();
// skin name: folder from skins/
$config['skin'] = 'larry';
// Enables using standard browser windows (that can be handled as tabs)
// instead of popup windows
@ -1112,25 +905,25 @@ $config['addressbook_pagesize'] = 50;
// sort contacts by this col (preferably either one of name, firstname, surname)
$config['addressbook_sort_col'] = 'surname';
// The way how contact names are displayed in the list.
// 0: prefix firstname middlename surname suffix (only if display name is not set)
// 1: firstname middlename surname
// 2: surname firstname middlename
// 3: surname, firstname middlename
// the way how contact names are displayed in the list
// 0: display name
// 1: (prefix) firstname middlename surname (suffix)
// 2: (prefix) surname firstname middlename (suffix)
// 3: (prefix) surname, firstname middlename (suffix)
$config['addressbook_name_listing'] = 0;
// use this timezone to display date/time
// valid timezone identifiers are listed here: php.net/manual/en/timezones.php
// valid timezone identifers are listed here: php.net/manual/en/timezones.php
// 'auto' will use the browser's timezone settings
$config['timezone'] = 'auto';
// prefer displaying HTML messages
$config['prefer_html'] = true;
// display remote resources (inline images, styles)
// display remote inline images
// 0 - Never, always ask
// 1 - Ask if sender is not in address book
// 2 - Always allow
// 2 - Always show inline images
$config['show_images'] = 0;
// open messages in new window
@ -1140,32 +933,21 @@ $config['message_extwin'] = false;
$config['compose_extwin'] = false;
// compose html formatted messages by default
// 0 - never,
// 1 - always,
// 2 - on reply to HTML message,
// 3 - on forward or reply to HTML message
// 4 - always, except when replying to plain text message
// 0 - never, 1 - always, 2 - on reply to HTML message, 3 - on forward or reply to HTML message
$config['htmleditor'] = 0;
// save copies of compose messages in the browser's local storage
// for recovery in case of browser crashes and session timeout.
$config['compose_save_localstorage'] = true;
// show pretty dates as standard
$config['prettydate'] = true;
// save compose message every 300 seconds (5min)
$config['draft_autosave'] = 300;
// Interface layout. Default: 'widescreen'.
// 'widescreen' - three columns
// 'desktop' - two columns, preview on bottom
// 'list' - two columns, no preview
$config['layout'] = 'widescreen';
// default setting if preview pane is enabled
$config['preview_pane'] = false;
// Mark as read when viewing a message (delay in seconds)
// Set to -1 if messages should not be marked as read
$config['mail_read_time'] = 0;
// Mark as read when viewed in preview pane (delay in seconds)
// Set to -1 if messages in preview pane should not be marked as read
$config['preview_pane_mark_read'] = 0;
// Clear Trash on logout
$config['logout_purge'] = false;
@ -1202,7 +984,7 @@ $config['refresh_interval'] = 60;
// If true all folders will be checked for recent messages
$config['check_all_folders'] = false;
// If true, after message/contact delete/move, the next message/contact will be displayed
// If true, after message delete/move, the next message will be displayed
$config['display_next'] = true;
// Default messages listing mode. One of 'threads' or 'list'.
@ -1217,7 +999,6 @@ $config['autoexpand_threads'] = 0;
// -1 - don't cite the original message
// 0 - place cursor below the original message
// 1 - place cursor above original message (top posting)
// 2 - place cursor above original message (top posting), but do not indent the quote
$config['reply_mode'] = 0;
// When replying strip original signature from message
@ -1230,26 +1011,24 @@ $config['strip_existing_sig'] = true;
// 3 - Forwards and Replies only
$config['show_sig'] = 1;
// By default the signature is placed depending on cursor position (reply_mode).
// Sometimes it might be convenient to start the reply on top but keep
// the signature below the quoted text (sig_below = true).
$config['sig_below'] = false;
// Enables adding of standard separator to the signature
$config['sig_separator'] = true;
// Use MIME encoding (quoted-printable) for 8bit characters in message body
$config['force_7bit'] = false;
// Defaults of the search field configuration.
// The array can contain a per-folder list of header fields which should be considered when searching
// The entry with key '*' stands for all folders which do not have a specific list set.
// Please note that folder names should to be in sync with $config['*_mbox'] options
// Please note that folder names should to be in sync with $config['default_folders']
$config['search_mods'] = null; // Example: array('*' => array('subject'=>1, 'from'=>1), 'Sent' => array('subject'=>1, 'to'=>1));
// Defaults of the addressbook search field configuration.
$config['addressbook_search_mods'] = null; // Example: array('name'=>1, 'firstname'=>1, 'surname'=>1, 'email'=>1, '*'=>1);
// 'Delete always'
// This setting reflects if mail should be always deleted
// when moving to Trash fails. This is necessary in some setups
// when user is over quota and Trash is included in the quota.
$config['delete_always'] = false;
// Directly delete messages in Junk instead of moving to Trash
$config['delete_junk'] = false;

@ -1,10 +1,10 @@
<?php
/**
/*
+-------------------------------------------------------------------------+
| Roundcube Webmail IMAP Client |
| Version 1.5-git |
| Version 1.0.12 |
| |
| Copyright (C) The Roundcube Dev Team |
| Copyright (C) 2005-2014, 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 (with exceptions |
@ -40,11 +40,10 @@
require_once 'program/include/iniset.php';
// init application, start session, init output class, etc.
$RCMAIL = rcmail::get_instance(0, $GLOBALS['env']);
$RCMAIL = rcmail::get_instance($GLOBALS['env']);
// Make the whole PHP output non-cacheable (#1487797)
$RCMAIL->output->nocacheing_headers();
$RCMAIL->output->common_headers(!empty($_SESSION['user_id']));
// turn on output buffering
ob_start();
@ -62,33 +61,21 @@ if ($err_str = $RCMAIL->db->is_error()) {
rcmail::raise_error(array(
'code' => 603,
'type' => 'db',
'message' => $err_str), false, true);
'message' => $err_str), FALSE, TRUE);
}
// error steps
if ($RCMAIL->action == 'error' && !empty($_GET['_code'])) {
rcmail::raise_error(array('code' => hexdec($_GET['_code'])), false, true);
rcmail::raise_error(array('code' => hexdec($_GET['_code'])), FALSE, TRUE);
}
// check if https is required (for login) and redirect if necessary
if (empty($_SESSION['user_id']) && ($force_https = $RCMAIL->config->get('force_https', false))) {
// force_https can be true, <hostname>, <hostname>:<port>, <port>
if (!is_bool($force_https)) {
list($host, $port) = explode(':', $force_https);
if (is_numeric($host) && empty($port)) {
$port = $host;
$host = '';
}
}
$https_port = is_bool($force_https) ? 443 : $force_https;
if (!rcube_utils::https_check($port ?: 443)) {
if (empty($host)) {
$host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']);
}
if ($port && $port != 443) {
$host .= ':' . $port;
}
if (!rcube_utils::https_check($https_port)) {
$host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']);
$host .= ($https_port != 443 ? ':' . $https_port : '');
header('Location: https://' . $host . $_SERVER['REQUEST_URI']);
exit;
@ -102,20 +89,18 @@ $RCMAIL->action = $startup['action'];
// try to log in
if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
$request_valid = $_SESSION['temp'] && $RCMAIL->check_request();
$pass_charset = $RCMAIL->config->get('password_charset', 'UTF-8');
$request_valid = $_SESSION['temp'] && $RCMAIL->check_request(rcube_utils::INPUT_POST, 'login');
// purge the session in case of new login when a session already exists
if ($request_valid) {
$RCMAIL->kill_session();
}
// purge the session in case of new login when a session already exists
$RCMAIL->kill_session();
$auth = $RCMAIL->plugins->exec_hook('authenticate', array(
'host' => $RCMAIL->autoselect_host(),
'user' => trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST)),
'pass' => rcube_utils::get_input_value('_pass', rcube_utils::INPUT_POST, true, $pass_charset),
'valid' => $request_valid,
'cookiecheck' => true,
'host' => $RCMAIL->autoselect_host(),
'user' => trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST)),
'pass' => rcube_utils::get_input_value('_pass', rcube_utils::INPUT_POST, true,
$RCMAIL->config->get('password_charset', 'ISO-8859-1')),
'cookiecheck' => true,
'valid' => $request_valid,
));
// Login
@ -145,7 +130,7 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
// prevent redirect to compose with specified ID (#1488226)
if ($query['_action'] == 'compose' && !empty($query['_id'])) {
$query = array('_action' => 'compose');
$query = array();
}
}
@ -154,25 +139,24 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
unset($redir['abort'], $redir['_err']);
// send redirect
$OUTPUT->redirect($redir, 0, true);
$OUTPUT->redirect($redir);
}
else {
if (!$auth['valid']) {
$error_code = rcmail::ERROR_INVALID_REQUEST;
$error_code = RCMAIL::ERROR_INVALID_REQUEST;
}
else {
$error_code = is_numeric($auth['error']) ? $auth['error'] : $RCMAIL->login_error();
$error_code = $auth['error'] ? $auth['error'] : $RCMAIL->login_error();
}
$error_labels = array(
rcmail::ERROR_STORAGE => 'storageerror',
rcmail::ERROR_COOKIES_DISABLED => 'cookiesdisabled',
rcmail::ERROR_INVALID_REQUEST => 'invalidrequest',
rcmail::ERROR_INVALID_HOST => 'invalidhost',
rcmail::ERROR_RATE_LIMIT => 'accountlocked',
RCMAIL::ERROR_STORAGE => 'storageerror',
RCMAIL::ERROR_COOKIES_DISABLED => 'cookiesdisabled',
RCMAIL::ERROR_INVALID_REQUEST => 'invalidrequest',
RCMAIL::ERROR_INVALID_HOST => 'invalidhost',
);
$error_message = !empty($auth['error']) && !is_numeric($auth['error']) ? $auth['error'] : ($error_labels[$error_code] ?: 'loginfailed');
$error_message = $error_labels[$error_code] ? $error_labels[$error_code] : 'loginfailed';
$OUTPUT->show_message($error_message, 'warning');
@ -182,16 +166,15 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
$RCMAIL->plugins->exec_hook('login_failed', array(
'code' => $error_code, 'host' => $auth['host'], 'user' => $auth['user']));
if (!isset($_SESSION['user_id'])) {
$RCMAIL->kill_session();
}
$RCMAIL->kill_session();
}
}
// end session
else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id'])) {
$RCMAIL->request_security_check(rcube_utils::INPUT_GET | rcube_utils::INPUT_POST);
// end session (after optional referer check)
else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id'])
&& $RCMAIL->check_request(rcube_utils::INPUT_GET)
&& (!$RCMAIL->config->get('referer_check') || rcube_utils::check_referer())
) {
$userdata = array(
'user' => $_SESSION['username'],
'host' => $_SESSION['storage_host'],
@ -206,17 +189,27 @@ else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id'])) {
}
// check session and auth cookie
else if ($RCMAIL->task != 'login' && $_SESSION['user_id']) {
else if ($RCMAIL->task != 'login' && $_SESSION['user_id'] && $RCMAIL->action != 'send') {
if (!$RCMAIL->session->check_auth()) {
$RCMAIL->kill_session();
$session_error = 'sessionerror';
$session_error = true;
}
}
// not logged in -> show login page
if (empty($RCMAIL->user->ID)) {
if ($session_error || $_REQUEST['_err'] === 'session' || ($session_error = $RCMAIL->session_error())) {
$OUTPUT->show_message($session_error ?: 'sessionerror', 'error', null, true, -1);
// log session failures
$task = rcube_utils::get_input_value('_task', rcube_utils::INPUT_GPC);
if ($task && !in_array($task, array('login','logout'))
&& !$session_error && ($sess_id = $_COOKIE[ini_get('session.name')])
) {
$RCMAIL->session->log("Aborted session $sess_id; no valid session data found");
$session_error = true;
}
if ($session_error || $_REQUEST['_err'] == 'session') {
$OUTPUT->show_message('sessionerror', 'error', null, true, -1);
}
if ($OUTPUT->ajax_call || $OUTPUT->get_env('framed')) {
@ -226,40 +219,46 @@ if (empty($RCMAIL->user->ID)) {
// check if installer is still active
if ($RCMAIL->config->get('enable_installer') && is_readable('./installer/index.php')) {
$OUTPUT->add_footer(html::div(array('id' => 'login-addon', 'style' => "background:#ef9398; border:2px solid #dc5757; padding:0.5em; margin:2em auto; width:50em"),
$OUTPUT->add_footer(html::div(array('style' => "background:#ef9398; border:2px solid #dc5757; padding:0.5em; margin:2em auto; width:50em"),
html::tag('h2', array('style' => "margin-top:0.2em"), "Installer script is still accessible") .
html::p(null, "The install script of your Roundcube installation is still stored in its default location!") .
html::p(null, "Please <b>remove</b> the whole <tt>installer</tt> folder from the Roundcube directory because
html::p(null, "Please <b>remove</b> the whole <tt>installer</tt> folder from the Roundcube directory because .
these files may expose sensitive configuration data like server passwords and encryption keys
to the public. Make sure you cannot access the <a href=\"./installer/\">installer script</a> from your browser.")
));
}
$plugin = $RCMAIL->plugins->exec_hook('unauthenticated', array(
'task' => 'login',
'error' => $session_error,
// Return 401 only on failed logins (#7010)
'http_code' => empty($session_error) && !empty($error_message) ? 401 : 200
));
$plugin = $RCMAIL->plugins->exec_hook('unauthenticated', array('task' => 'login', 'error' => $session_error));
$RCMAIL->set_task($plugin['task']);
if ($plugin['http_code'] == 401) {
header('HTTP/1.0 401 Unauthorized');
}
$OUTPUT->send($plugin['task']);
}
// CSRF prevention
else {
// CSRF prevention
$RCMAIL->request_security_check();
// check access to disabled actions
$disabled_actions = (array) $RCMAIL->config->get('disabled_actions');
if (in_array($RCMAIL->task . '.' . ($RCMAIL->action ?: 'index'), $disabled_actions)) {
rcube::raise_error(array(
'code' => 404, 'type' => 'php',
'message' => "Action disabled"), true, true);
// don't check for valid request tokens in these actions
$request_check_whitelist = array('login'=>1, 'spell'=>1, 'spell_html'=>1);
if (!$request_check_whitelist[$RCMAIL->action]) {
// check client X-header to verify request origin
if ($OUTPUT->ajax_call) {
if (rcube_utils::request_header('X-Roundcube-Request') != $RCMAIL->get_request_token()) {
header('HTTP/1.1 403 Forbidden');
die("Invalid Request");
}
}
// check request token in POST form submissions
else if (!empty($_POST) && !$RCMAIL->check_request()) {
$OUTPUT->show_message('invalidrequest', 'error');
$OUTPUT->send($RCMAIL->task);
}
// check referer if configured
if ($RCMAIL->config->get('referer_check') && !rcube_utils::check_referer()) {
raise_error(array(
'code' => 403, 'type' => 'php',
'message' => "Referer check failed"), true, true);
}
}
}
@ -285,19 +284,18 @@ if (is_file($incfile = INSTALL_PATH . 'program/steps/'.$RCMAIL->task.'/func.inc'
}
// allow 5 "redirects" to another action
$redirects = 0;
$redirects = 0; $incstep = null;
while ($redirects < 5) {
// execute a plugin action
if (preg_match('/^plugin\./', $RCMAIL->action)) {
$RCMAIL->plugins->exec_action($RCMAIL->action);
break;
}
// execute action registered to a plugin task
else if ($RCMAIL->plugins->is_plugin_task($RCMAIL->task)) {
if ($RCMAIL->plugins->is_plugin_task($RCMAIL->task)) {
if (!$RCMAIL->action) $RCMAIL->action = 'index';
$RCMAIL->plugins->exec_action($RCMAIL->task.'.'.$RCMAIL->action);
break;
}
else if (preg_match('/^plugin\./', $RCMAIL->action)) {
$RCMAIL->plugins->exec_action($RCMAIL->action);
break;
}
// try to include the step file
else if (($stepfile = $RCMAIL->get_action_file())
&& is_file($incfile = INSTALL_PATH . 'program/steps/'.$RCMAIL->task.'/'.$stepfile)

@ -1,20 +1,6 @@
<?php
/**
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| 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. |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
*/
if (!class_exists('rcmail_install', false) || !is_object($RCI)) {
if (!class_exists('rcube_install') || !is_object($RCI)) {
die("Not allowed! Please open installer/index.php instead.");
}
@ -29,45 +15,40 @@ $required_php_exts = array(
'XML' => 'xml',
'JSON' => 'json',
'PDO' => 'PDO',
'Multibyte' => 'mbstring',
'OpenSSL' => 'openssl',
'Filter' => 'filter',
'Ctype' => 'ctype',
);
$optional_php_exts = array(
'FileInfo' => 'fileinfo',
'Libiconv' => 'iconv',
'Multibyte' => 'mbstring',
'OpenSSL' => 'openssl',
'Mcrypt' => 'mcrypt',
'Intl' => 'intl',
'Exif' => 'exif',
'LDAP' => 'ldap',
'GD' => 'gd',
'Imagick' => 'imagick',
'Zip' => 'zip',
);
$required_libs = array(
'PEAR' => 'pear.php.net',
'Auth_SASL' => 'pear.php.net',
'Net_SMTP' => 'pear.php.net',
'Net_IDNA2' => 'pear.php.net',
'Mail_mime' => 'pear.php.net',
);
$optional_libs = array(
'Net_LDAP3' => 'git.kolab.org',
);
$ini_checks = array(
'file_uploads' => 1,
'session.auto_start' => 0,
'zend.ze1_compatibility_mode' => 0,
'mbstring.func_overload' => 0,
'suhosin.session.encrypt' => 0,
'magic_quotes_runtime' => 0,
'magic_quotes_sybase' => 0,
);
$optional_checks = array(
// required for utils/modcss.inc, should we require this?
'allow_url_fopen' => 1,
'date.timezone' => '-VALID-',
'register_globals' => 0, // #1489157
);
$source_urls = array(
@ -75,20 +56,15 @@ $source_urls = array(
'Session' => 'http://www.php.net/manual/en/book.session.php',
'PCRE' => 'http://www.php.net/manual/en/book.pcre.php',
'FileInfo' => 'http://www.php.net/manual/en/book.fileinfo.php',
'Libiconv' => 'http://www.php.net/manual/en/book.iconv.php',
'Multibyte' => 'http://www.php.net/manual/en/book.mbstring.php',
'Mcrypt' => 'http://www.php.net/manual/en/book.mcrypt.php',
'OpenSSL' => 'http://www.php.net/manual/en/book.openssl.php',
'JSON' => 'http://www.php.net/manual/en/book.json.php',
'DOM' => 'http://www.php.net/manual/en/book.dom.php',
'Intl' => 'http://www.php.net/manual/en/book.intl.php',
'Exif' => 'http://www.php.net/manual/en/book.exif.php',
'oci8' => 'http://www.php.net/manual/en/book.oci8.php',
'PDO' => 'http://www.php.net/manual/en/book.pdo.php',
'LDAP' => 'http://www.php.net/manual/en/book.ldap.php',
'GD' => 'http://www.php.net/manual/en/book.image.php',
'Imagick' => 'http://www.php.net/manual/en/book.imagick.php',
'Zip' => 'http://www.php.net/manual/en/book.zip.php',
'Filter' => 'http://www.php.net/manual/en/book.filter.php',
'Ctype' => 'http://www.php.net/manual/en/book.ctype.php',
'pdo_mysql' => 'http://www.php.net/manual/en/ref.pdo-mysql.php',
'pdo_pgsql' => 'http://www.php.net/manual/en/ref.pdo-pgsql.php',
'pdo_sqlite' => 'http://www.php.net/manual/en/ref.pdo-sqlite.php',
@ -99,7 +75,6 @@ $source_urls = array(
'Net_SMTP' => 'http://pear.php.net/package/Net_SMTP',
'Mail_mime' => 'http://pear.php.net/package/Mail_mime',
'Net_IDNA2' => 'http://pear.php.net/package/Net_IDNA2',
'Net_LDAP3' => 'https://git.kolab.org/diffusion/PNL',
);
echo '<input type="hidden" name="_step" value="' . ($RCI->configured ? 3 : 2) . '" />';
@ -108,7 +83,7 @@ echo '<input type="hidden" name="_step" value="' . ($RCI->configured ? 3 : 2) .
<h3>Checking PHP version</h3>
<?php
define('MIN_PHP_VERSION', '5.4.0');
define('MIN_PHP_VERSION', '5.2.1');
if (version_compare(PHP_VERSION, MIN_PHP_VERSION, '>=')) {
$RCI->pass('Version', 'PHP ' . PHP_VERSION . ' detected');
} else {
@ -163,8 +138,14 @@ foreach ($optional_php_exts as $name => $ext) {
$prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
foreach ($RCI->supported_dbs as $database => $ext) {
if (extension_loaded($ext)) {
$RCI->pass($database);
$found_db_driver = true;
// MySQL driver requires PHP >= 5.3 (#1488875)
if ($ext == 'pdo_mysql' && version_compare(PHP_VERSION, '5.3.0', '<')) {
$RCI->fail($database, 'PHP >= 5.3 required', null, true);
}
else {
$RCI->pass($database);
$found_db_driver = true;
}
}
else {
$_ext = $ext_dir . '/' . $prefix . $ext . '.' . PHP_SHLIB_SUFFIX;
@ -185,25 +166,17 @@ if (empty($found_db_driver)) {
<?php
foreach ($required_libs as $classname => $vendor) {
foreach ($required_libs as $classname => $file) {
@include_once $file;
if (class_exists($classname)) {
$RCI->pass($classname);
}
else {
$RCI->fail($classname, "Failed to load class $classname from $vendor", $source_urls[$classname]);
$RCI->fail($classname, "Failed to load $file", $source_urls[$classname]);
}
echo "<br />";
}
foreach ($optional_libs as $classname => $vendor) {
if (class_exists($classname)) {
$RCI->pass($classname);
}
else {
$RCI->na($classname, "Recommended to install $classname from $vendor", $source_urls[$classname]);
}
echo "<br />";
}
?>

@ -1,13 +1,14 @@
/*
+-----------------------------------------------------------------------+
| Roundcube installer client function |
| Roundcube installer cleint function |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) The Roundcube Dev Team |
| This file is part of the Roundcube web development suite |
| Copyright (C) 2009-2012, 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. |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
@ -16,7 +17,7 @@
function toggleblock(id, link)
{
var block = document.getElementById(id);
return false;
}
@ -27,14 +28,14 @@ function addhostfield()
var row = document.createElement('div');
var input = document.createElement('input');
var link = document.createElement('a');
input.name = '_default_host[]';
input.size = '30';
link.href = '#';
link.onclick = function() { removehostfield(this.parentNode); return false };
link.className = 'removelink';
link.innerHTML = 'remove';
row.appendChild(input);
row.appendChild(link);
container.appendChild(row);

@ -1,23 +1,14 @@
<?php
/**
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
| |
| 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. |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
*/
if (!class_exists('rcmail_install', false) || !is_object($RCI)) {
if (!class_exists('rcube_install') || !is_object($RCI)) {
die("Not allowed! Please open installer/index.php instead.");
}
?>
<form action="index.php" method="post">
<input type="hidden" name="_step" value="2" />
<?php
// register these boolean fields
$RCI->bool_config_props = array(
'ip_check' => 1,
@ -25,6 +16,8 @@ $RCI->bool_config_props = array(
'auto_create_user' => 1,
'smtp_log' => 1,
'prefer_html' => 1,
'preview_pane' => 1,
'debug_level' => 1,
);
// allow the current user to get to the next step
@ -43,20 +36,10 @@ if (!empty($_POST['submit'])) {
echo '</p>';
}
else {
if (($dir = sys_get_temp_dir()) && @is_writable($dir)) {
echo '<iframe name="getconfig" style="display:none"></iframe>';
echo '<form id="getconfig_form" action="index.php" method="get" target="getconfig" style="display:none">';
echo '<input name="_getconfig" value="2" /></form>';
$button_txt = html::quote('Save in ' . $dir);
$save_button = '&nbsp;<input type="button" onclick="document.getElementById(\'getconfig_form\').submit()" value="' . $button_txt . '" />';
}
echo '<p class="notice">Copy or download the following configuration and save it';
echo ' as <tt><b>config.inc.php</b></tt> within the <tt>'.RCUBE_CONFIG_DIR.'</tt> directory of your Roundcube installation.<br/>';
echo ' Make sure that there are no characters outside the <tt>&lt;?php ?&gt;</tt> brackets when saving the file.';
echo '&nbsp;<input type="button" onclick="location.href=\'index.php?_getconfig=1\'" value="Download" />';
echo $save_button;
if ($RCI->legacy_config) {
echo '<br/><br/>Afterwards, please <b>remove</b> the old configuration files <tt>main.inc.php</tt> and <tt>db.inc.php</tt> from the config directory.';
@ -69,7 +52,7 @@ if (!empty($_POST['submit'])) {
}
echo '<p class="hint">Of course there are more options to configure.
Have a look at the defaults.inc.php file or visit <a href="https://github.com/roundcube/roundcubemail/wiki/Configuration" target="_blank">Howto_Config</a> to find out.</p>';
Have a look at the defaults.inc.php file or visit <a href="http://trac.roundcube.net/wiki/Howto_Config" target="_blank">Howto_Config</a> to find out.</p>';
echo '<p><input type="button" onclick="location.href=\'./index.php?_step=3\'" value="CONTINUE" /></p>';
@ -78,9 +61,6 @@ if (!empty($_POST['submit'])) {
}
?>
<form action="index.php" method="post">
<input type="hidden" name="_step" value="2" />
<fieldset>
<legend>General configuration</legend>
<dl class="configblock">
@ -104,8 +84,8 @@ $input_support = new html_inputfield(array('name' => '_support_url', 'size' => 5
echo $input_support->show($RCI->getprop('support_url'));
?>
<div>Provide a URL where a user can get support for this Roundcube installation.<br/>PLEASE DO NOT LINK TO THE ROUNDCUBE.NET WEBSITE HERE!</div>
<p class="hint">Enter an absolute URL (including http://) to a support page/form or a mailto: link.</p>
<div>Provide an URL where a user can get support for this Roundcube installation.<br/>PLEASE DO NOT LINK TO THE ROUNDCUBE.NET WEBSITE HERE!</div>
<p class="hint">Enter an absolute URL (inculding http://) to a support page/form or a mailto: link.</p>
</dd>
<dt class="propname">skin_logo</dt>
@ -140,7 +120,8 @@ echo $input_deskey->show($RCI->getprop('des_key'));
?>
<div>This key is used to encrypt the users imap password before storing in the session record</div>
<p class="hint">It's a random generated string to ensure that every installation has its own key.</p>
<p class="hint">It's a random generated string to ensure that every installation has its own key.
If you enter it manually please provide a string of exactly 24 chars.</p>
</dd>
<dt class="propname">ip_check</dt>
@ -209,16 +190,34 @@ echo $input_ilevel->show($RCI->getprop('identities_level'), 0);
<legend>Logging & Debugging</legend>
<dl class="loggingblock">
<dt class="propname">debug_level</dt>
<dd>
<?php
$value = $RCI->getprop('debug_level');
$check_debug = new html_checkbox(array('name' => '_debug_level[]'));
echo $check_debug->show(($value & 1) ? 1 : 0 , array('value' => 1, 'id' => 'cfgdebug1'));
echo '<label for="cfgdebug1">Log errors</label><br />';
echo $check_debug->show(($value & 4) ? 4 : 0, array('value' => 4, 'id' => 'cfgdebug4'));
echo '<label for="cfgdebug4">Print errors (to the browser)</label><br />';
echo $check_debug->show(($value & 8) ? 8 : 0, array('value' => 8, 'id' => 'cfgdebug8'));
echo '<label for="cfgdebug8">Verbose display (enables debug console)</label><br />';
?>
</dd>
<dt class="propname">log_driver</dt>
<dd>
<?php
$select_log_driver = new html_select(array('name' => '_log_driver', 'id' => "cfglogdriver"));
$select_log_driver->add(array('file', 'syslog', 'stdout'), array('file', 'syslog', 'stdout'));
$select_log_driver->add(array('file', 'syslog'), array('file', 'syslog'));
echo $select_log_driver->show($RCI->getprop('log_driver', 'file'));
?>
<div>How to do logging? 'file' - write to files in the log directory, 'syslog' - use the syslog facility, 'stdout' writes to the process' STDOUT file descriptor.</div>
<div>How to do logging? 'file' - write to files in the log directory, 'syslog' - use the syslog facility.</div>
</dd>
<dt class="propname">log_dir</dt>
@ -289,7 +288,7 @@ foreach ($RCI->supported_dbs as $database => $ext) {
$input_dbhost = new html_inputfield(array('name' => '_dbhost', 'size' => 20, 'id' => "cfgdbhost"));
$input_dbname = new html_inputfield(array('name' => '_dbname', 'size' => 20, 'id' => "cfgdbname"));
$input_dbuser = new html_inputfield(array('name' => '_dbuser', 'size' => 20, 'id' => "cfgdbuser"));
$input_dbpass = new html_inputfield(array('name' => '_dbpass', 'size' => 20, 'id' => "cfgdbpass"));
$input_dbpass = new html_passwordfield(array('name' => '_dbpass', 'size' => 20, 'id' => "cfgdbpass"));
$dsnw = rcube_db::parse_dsn($RCI->getprop('db_dsnw'));
@ -458,12 +457,12 @@ echo $text_junkmbox->show($RCI->getprop('junk_mbox'));
<?php
$text_smtphost = new html_inputfield(array('name' => '_smtp_server', 'size' => 30, 'id' => "cfgsmtphost"));
echo $text_smtphost->show($RCI->getprop('smtp_server', 'localhost'));
echo $text_smtphost->show($RCI->getprop('smtp_server'));
?>
<div>Use this host for sending mails</div>
<p class="hint">To use SSL connection, set ssl://smtp.host.com.</p>
<p class="hint">To use SSL connection, set ssl://smtp.host.com. If left blank, the PHP mail() function is used</p>
</dd>
<dt class="propname">smtp_port</dt>
@ -474,7 +473,7 @@ $text_smtpport = new html_inputfield(array('name' => '_smtp_port', 'size' => 6,
echo $text_smtpport->show($RCI->getprop('smtp_port'));
?>
<div>SMTP port (default is 587)</div>
<div>SMTP port (default is 25; 465 for SSL; 587 for submission)</div>
</dd>
<dt class="propname">smtp_user/smtp_pass</dt>
@ -482,7 +481,7 @@ echo $text_smtpport->show($RCI->getprop('smtp_port'));
<?php
$text_smtpuser = new html_inputfield(array('name' => '_smtp_user', 'size' => 20, 'id' => "cfgsmtpuser"));
$text_smtppass = new html_inputfield(array('name' => '_smtp_pass', 'size' => 20, 'id' => "cfgsmtppass"));
$text_smtppass = new html_passwordfield(array('name' => '_smtp_pass', 'size' => 20, 'id' => "cfgsmtppass"));
echo $text_smtpuser->show($RCI->getprop('smtp_user'));
echo $text_smtppass->show($RCI->getprop('smtp_pass'));
@ -595,6 +594,17 @@ echo $check_htmlview->show(intval($RCI->getprop('prefer_html')));
<label for="cfghtmlview">Prefer displaying HTML messages</label><br />
</dd>
<dt class="propname">preview_pane <span class="userconf">*</span></dt>
<dd>
<?php
$check_prevpane = new html_checkbox(array('name' => '_preview_pane', 'id' => "cfgprevpane", 'value' => 1));
echo $check_prevpane->show(intval($RCI->getprop('preview_pane')));
?>
<label for="cfgprevpane">If preview pane is enabled</label><br />
</dd>
<dt class="propname">htmleditor <span class="userconf">*</span></dt>
<dd>
<label for="cfghtmlcompose">Compose HTML formatted messages</label>
@ -664,27 +674,6 @@ echo $select_param_folding->show(strval($RCI->getprop('mime_param_folding')));
<p class="hint"><span class="userconf">*</span>&nbsp; These settings are defaults for the user preferences</p>
</fieldset>
<fieldset>
<legend>Plugins</legend>
<dl class="configblock" id="cgfblockdisplay">
<?php
$plugins = $RCI->list_plugins();
foreach ($plugins as $p) {
$p_check = new html_checkbox(array('name' => '_plugins_'.$p['name'], 'id' => 'cfgplugin_'.$p['name'], 'value' => $p['name']));
echo '<dt class="propname"><label>';
echo $p_check->show($p['enabled'] ? $p['name'] : 0);
echo '&nbsp;' . $p['name'] . '</label></dt><dd>';
echo '<label for="cfgplugin_'.$p['name'].'" class="hint">' . $p['desc'] . '</label><br/></dd>';
}
?>
</dl>
<p class="hint">Please consider checking dependencies of enabled plugins</p>
</fieldset>
<?php
echo '<p><input type="submit" name="submit" value="' . ($RCI->configured ? 'UPDATE' : 'CREATE') . ' CONFIG" ' . ($RCI->failures ? 'disabled' : '') . ' /></p>';

Binary file not shown.

Before

Width:  |  Height:  |  Size: 653 B

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 637 B

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 565 B

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

@ -1,11 +1,11 @@
<?php
/**
/*
+-------------------------------------------------------------------------+
| Roundcube Webmail setup tool |
| Version 1.5-git |
| Version 0.9-git |
| |
| Copyright (C) The Roundcube Dev Team |
| Copyright (C) 2009-2013, 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 (with exceptions |
@ -36,27 +36,33 @@
+-------------------------------------------------------------------------+
*/
ini_set('error_reporting', E_ALL &~ (E_NOTICE | E_STRICT));
ini_set('display_errors', 1);
define('INSTALL_PATH', realpath(__DIR__ . '/../').'/');
define('INSTALL_PATH', realpath(dirname(__FILE__) . '/../').'/');
define('RCUBE_INSTALL_PATH', INSTALL_PATH);
define('RCUBE_CONFIG_DIR', INSTALL_PATH . 'config/');
require INSTALL_PATH . 'program/include/iniset.php';
$include_path = INSTALL_PATH . 'program/lib' . PATH_SEPARATOR;
$include_path .= INSTALL_PATH . 'program/include' . PATH_SEPARATOR;
$include_path .= ini_get('include_path');
set_include_path($include_path);
require_once 'Roundcube/bootstrap.php';
require_once 'rcube_install.php';
// deprecated aliases (to be removed)
require_once 'bc.php';
if (function_exists('session_start'))
session_start();
$RCI = rcmail_install::get_instance();
$RCI = rcube_install::get_instance();
$RCI->load_config();
if (isset($_GET['_getconfig'])) {
$filename = 'config.inc.php';
if (!empty($_SESSION['config']) && $_GET['_getconfig'] == 2) {
$path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $filename;
@unlink($path);
file_put_contents($path, $_SESSION['config']);
exit;
}
else if (!empty($_SESSION['config'])) {
if (!empty($_SESSION['config'])) {
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="'.$filename.'"');
echo $_SESSION['config'];
@ -106,7 +112,7 @@ if ($RCI->configured && empty($_REQUEST['_step'])) {
</div>
<div id="topnav">
<a href="https://github.com/roundcube/roundcubemail/wiki/Installation">How-to Wiki</a>
<a href="http://trac.roundcube.net/wiki/Howto_Install">How-to Wiki</a>
</div>
<div id="content">
@ -148,7 +154,7 @@ if ($RCI->configured && empty($_REQUEST['_step'])) {
foreach (array('Check environment', 'Create config', 'Test config') as $i => $item) {
$j = $i + 1;
$link = ($RCI->step >= $j || $RCI->configured) ? '<a href="./index.php?_step='.$j.'">' . rcube::Q($item) . '</a>' : rcube::Q($item);
$link = ($RCI->step >= $j || $RCI->configured) ? '<a href="./index.php?_step='.$j.'">' . Q($item) . '</a>' : Q($item);
printf('<li class="step%d%s">%s</li>', $j+1, $RCI->step > $j ? ' passed' : ($RCI->step == $j ? ' current' : ''), $link);
}
?>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save