├── modules
├── tags
│ ├── site.js
│ ├── site.css
│ ├── README.md
│ └── modules.php
├── highlights
│ ├── site.css
│ └── site.js
├── profiles
│ ├── site.css
│ ├── js_modules
│ │ └── route_handlers.js
│ ├── README.md
│ ├── functions.php
│ └── site.js
├── dynamic_login
│ ├── site.css
│ ├── site.js
│ ├── README.md
│ └── setup.php
├── calendar
│ ├── site.js
│ ├── README.md
│ ├── js_modules
│ │ └── route_handlers.js
│ ├── site.css
│ └── setup.php
├── developer
│ ├── site.js
│ ├── site.css
│ ├── README.md
│ └── setup.php
├── history
│ ├── site.js
│ ├── site.css
│ ├── js_modules
│ │ └── route_handlers.js
│ ├── README.md
│ └── setup.php
├── ldap_contacts
│ ├── site.css
│ ├── site.js
│ └── README.md
├── carddav_contacts
│ ├── site.css
│ ├── README.md
│ └── site.js
├── feeds
│ ├── site.css
│ ├── js_modules
│ │ └── route_handlers.js
│ └── README.md
├── core
│ ├── assets
│ │ ├── images
│ │ │ └── cloud.jpg
│ │ └── fonts
│ │ │ └── Behdad
│ │ │ ├── Behdad-Regular.woff
│ │ │ ├── Behdad-Regular.woff2
│ │ │ └── README.md
│ ├── js_modules
│ │ ├── utils
│ │ │ ├── messageList.js
│ │ │ ├── popovers.js
│ │ │ └── loaders.js
│ │ ├── actions
│ │ │ ├── search.js
│ │ │ ├── privacy_controls.js
│ │ │ └── sortCombinedLists.js
│ │ ├── markup
│ │ │ └── pagination.js
│ │ └── [cash]
│ │ │ └── extend.js
│ ├── modules.php
│ ├── README.md
│ └── navigation
│ │ ├── utils.js
│ │ └── navbar.js
├── advanced_search
│ ├── README.md
│ ├── site.css
│ └── js_modules
│ │ └── route_handlers.js
├── recaptcha
│ ├── site.css
│ ├── README.md
│ └── setup.php
├── local_contacts
│ ├── assets
│ │ └── data
│ │ │ └── contact_sample.csv
│ ├── README.md
│ └── setup.php
├── smtp
│ ├── assets
│ │ └── markdown
│ │ │ └── fonts
│ │ │ └── icomoon.woff
│ ├── README.md
│ └── js_modules
│ │ └── [kindeditor]
│ │ └── kindEditor.js
├── account
│ ├── site.js
│ ├── README.md
│ └── site.css
├── saved_searches
│ ├── README.md
│ └── site.css
├── site
│ ├── README.md
│ ├── modules.php
│ ├── site.js
│ └── setup.php
├── themes
│ ├── assets
│ │ ├── default
│ │ │ ├── fonts
│ │ │ │ ├── roboto-condensed-v14-latin-regular.woff
│ │ │ │ └── roboto-condensed-v14-latin-regular.woff2
│ │ │ └── css
│ │ │ │ └── default.css
│ │ ├── lux
│ │ │ └── css
│ │ │ │ └── lux.css
│ │ ├── yeti
│ │ │ └── css
│ │ │ │ └── yeti.css
│ │ ├── cosmo
│ │ │ └── css
│ │ │ │ └── cosmo.css
│ │ ├── lumen
│ │ │ └── css
│ │ │ │ └── lumen.css
│ │ ├── pulse
│ │ │ └── css
│ │ │ │ └── pulse.css
│ │ ├── flatly
│ │ │ └── css
│ │ │ │ └── flatly.css
│ │ ├── journal
│ │ │ └── css
│ │ │ │ └── journal.css
│ │ ├── litera
│ │ │ └── css
│ │ │ │ └── litera.css
│ │ ├── simplex
│ │ │ └── css
│ │ │ │ └── simplex.css
│ │ ├── united
│ │ │ └── css
│ │ │ │ └── united.css
│ │ ├── cerulean
│ │ │ └── css
│ │ │ │ └── cerulean.css
│ │ ├── spacelab
│ │ │ └── css
│ │ │ │ └── spacelab.css
│ │ ├── sandstone
│ │ │ └── css
│ │ │ │ └── sandstone.css
│ │ ├── zephyr
│ │ │ └── css
│ │ │ │ └── zephyr.css
│ │ ├── minty
│ │ │ └── css
│ │ │ │ └── minty.css
│ │ ├── quartz
│ │ │ └── css
│ │ │ │ └── quartz.css
│ │ ├── cyborg
│ │ │ └── css
│ │ │ │ └── cyborg.css
│ │ ├── morph
│ │ │ └── css
│ │ │ │ └── morph.css
│ │ ├── sketchy
│ │ │ └── css
│ │ │ │ └── sketchy.css
│ │ ├── vapor
│ │ │ └── css
│ │ │ │ └── vapor.css
│ │ ├── solar
│ │ │ └── css
│ │ │ │ └── solar.css
│ │ ├── materia
│ │ │ └── css
│ │ │ │ └── materia.css
│ │ ├── superhero
│ │ │ └── css
│ │ │ │ └── superhero.css
│ │ ├── slate
│ │ │ └── css
│ │ │ │ └── slate.css
│ │ └── darkly
│ │ │ └── css
│ │ │ └── darkly.css
│ ├── README.md
│ └── setup.php
├── keyboard_shortcuts
│ ├── README.md
│ ├── js_modules
│ │ └── route_handlers.js
│ └── site.css
├── hello_world
│ ├── README.md
│ ├── js_modules
│ │ └── route_handlers.js
│ ├── site.css
│ └── site.js
├── imap
│ ├── README.md
│ ├── modules.php
│ └── js_modules
│ │ ├── utils
│ │ ├── messageParts.js
│ │ └── attachements.js
│ │ └── route_handlers.js
├── wordpress
│ ├── site.css
│ └── README.md
├── recover_settings
│ ├── site.css
│ ├── README.md
│ └── setup.php
├── inline_message
│ ├── README.md
│ ├── site.css
│ └── setup.php
├── idle_timer
│ ├── README.md
│ ├── site.js
│ └── setup.php
├── github
│ ├── README.md
│ └── site.css
├── imap_folders
│ ├── README.md
│ ├── js_modules
│ │ └── route_handlers.js
│ └── site.css
├── nasa
│ ├── README.md
│ ├── site.css
│ ├── site.js
│ └── setup.php
├── api_login
│ ├── README.md
│ └── setup.php
├── sievefilters
│ ├── js_modules
│ │ └── route_handlers.js
│ ├── hm-sieve.php
│ └── README.md
├── nux
│ └── README.md
├── desktop_notifications
│ ├── README.md
│ ├── modules.php
│ ├── setup.php
│ └── site.js
├── 2fa
│ ├── README.md
│ └── setup.php
├── gmail_contacts
│ ├── README.md
│ └── setup.php
├── pgp
│ ├── site.css
│ ├── js_modules
│ │ └── route_handlers.js
│ ├── README.md
│ └── setup.php
└── contacts
│ └── README.md
├── .dockerignore
├── tests
├── phpunit
│ ├── data
│ │ ├── foo.ini
│ │ ├── app.php
│ │ ├── schema.sql
│ │ ├── schema_postgres.sql
│ │ ├── schema_sqlite.sql
│ │ ├── seed.sql
│ │ ├── seed_mysql.sql
│ │ └── seed_postgres.sql
│ ├── elog.php
│ ├── page_redirect.php
│ ├── debug.php
│ ├── handler_module_debug.php
│ ├── redis_session.php
│ ├── output.php
│ ├── module_exec_debug.php
│ ├── bootstrap.php
│ ├── run.sh
│ ├── oauth2.php
│ ├── transform.php
│ ├── request_key.php
│ ├── environment.php
│ ├── api.php
│ ├── site_file_config.php
│ ├── user_config_functions.php
│ ├── output_module.php
│ ├── tags.php
│ └── crypt.php
└── selenium
│ ├── requirements.txt
│ ├── runall.sh
│ ├── get_config.php
│ ├── local_creds.example.py
│ ├── remote_creds.example.py
│ ├── runner.py
│ └── search.py
├── .travis
├── .my.cnf
├── run.sh
├── travis-ci-apache
├── dovecot.sh
├── creds.py-ie
├── creds.py-edge
├── creds.py-ff
├── creds.py-chrome
└── creds.py-safari
├── .github
├── tests
│ ├── my.cnf
│ ├── scripts
│ │ ├── postfix.sh
│ │ └── dovecot.sh
│ ├── selenium
│ │ ├── webdriver
│ │ │ └── webdriver.sh
│ │ ├── nginx
│ │ │ ├── php_fastcgi.conf
│ │ │ └── nginx-site.conf
│ │ └── creds.py
│ └── test.sh
├── ISSUE_TEMPLATE
│ ├── feature.md
│ ├── devops.md
│ ├── refactor.md
│ ├── epic.md
│ ├── release.md
│ ├── question.md
│ └── bug.md
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── Daily-Image.yml
│ ├── Release-Image.yml
│ └── release.yml
├── database
├── migrations
│ ├── sqlite
│ │ ├── 20241209010201_add_lock_columns.sql
│ │ └── 20241209010200_add_hm_version_columns.sql
│ ├── mysql
│ │ └── 20241209010200_add_hm_version_columns.sql
│ └── pgsql
│ │ └── 20241209010200_add_hm_version_columns.sql
├── mysql_schema.sql
├── sqlite_schema.sql
└── pgsql_schema.sql
├── third_party
├── kindeditor
│ ├── themes
│ │ ├── common
│ │ │ ├── rm.gif
│ │ │ ├── blank.gif
│ │ │ ├── flash.gif
│ │ │ ├── media.gif
│ │ │ ├── anchor.gif
│ │ │ └── loading.gif
│ │ └── default
│ │ │ ├── default.png
│ │ │ └── background.png
│ └── plugins
│ │ ├── pagebreak
│ │ └── pagebreak.js
│ │ ├── preview
│ │ └── preview.js
│ │ ├── lineheight
│ │ └── lineheight.js
│ │ ├── autoheight
│ │ └── autoheight.js
│ │ ├── plainpaste
│ │ └── plainpaste.js
│ │ └── wordpaste
│ │ └── wordpaste.js
└── ays-beforeunload-shim.js
├── .coveralls.yml
├── RELEASE_NOTES
├── CONTRIBUTING.md
├── config
├── carddav.php
├── recaptcha.php
├── themes.php
├── wordpress.php
├── github.php
└── 2fa.php
├── scripts
├── build_changelog.sh
├── release_changes.sh
├── setup_system.sh
├── load.php
├── create_account.php
├── delete_account.php
└── update_password.php
├── lib
├── session_redis.php
└── js_libs.php
├── assets
└── data
│ ├── server_accounts_sample.csv
│ └── server_accounts_sample.yaml
├── docker
├── supervisord.conf
├── docker-compose.yaml
├── docker-entrypoint.sh
└── nginx.conf
├── .gitignore
├── Makefile
└── docker-compose.dev.yaml
/modules/tags/site.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/modules/highlights/site.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/modules/profiles/site.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | /data/
2 | .git
3 |
--------------------------------------------------------------------------------
/modules/dynamic_login/site.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/modules/dynamic_login/site.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/phpunit/data/foo.ini:
--------------------------------------------------------------------------------
1 | foo=bar
2 |
--------------------------------------------------------------------------------
/modules/calendar/site.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/modules/developer/site.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/modules/history/site.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/.travis/.my.cnf:
--------------------------------------------------------------------------------
1 | [mysql]
2 | socket = /var/run/mysqld/mysqld.sock
3 |
--------------------------------------------------------------------------------
/modules/ldap_contacts/site.css:
--------------------------------------------------------------------------------
1 | .ldap_settings { display: none; }
2 |
--------------------------------------------------------------------------------
/modules/carddav_contacts/site.css:
--------------------------------------------------------------------------------
1 | .carddav_settings { display: none; }
2 |
--------------------------------------------------------------------------------
/modules/feeds/site.css:
--------------------------------------------------------------------------------
1 | .feeds_setting, .feeds_section { display: none; }
2 |
--------------------------------------------------------------------------------
/.github/tests/my.cnf:
--------------------------------------------------------------------------------
1 | [client]
2 | user = "cypht_test"
3 | password = "cypht_test"
4 | host = "127.0.0.1"
--------------------------------------------------------------------------------
/tests/phpunit/data/app.php:
--------------------------------------------------------------------------------
1 | 'bar','default_setting_foo' => 'bar',);
4 |
--------------------------------------------------------------------------------
/modules/core/assets/images/cloud.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/modules/core/assets/images/cloud.jpg
--------------------------------------------------------------------------------
/modules/advanced_search/README.md:
--------------------------------------------------------------------------------
1 | ## Advanced Search
2 |
3 | Searches throughout various IMAP accounts in one interface.
4 |
--------------------------------------------------------------------------------
/modules/recaptcha/site.css:
--------------------------------------------------------------------------------
1 | .g-recaptcha { margin-left: -12px; }
2 | .mobile .g-recaptcha { clear: left; margin-left: 20px; }
3 |
--------------------------------------------------------------------------------
/database/migrations/sqlite/20241209010201_add_lock_columns.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE hm_user_session
2 | ADD COLUMN lock INT DEFAULT 0;
3 |
--------------------------------------------------------------------------------
/database/migrations/mysql/20241209010200_add_hm_version_columns.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE hm_user_session ADD COLUMN hm_version INT DEFAULT 1;
2 |
--------------------------------------------------------------------------------
/modules/local_contacts/assets/data/contact_sample.csv:
--------------------------------------------------------------------------------
1 | display_name,email_address,phone_number
2 | Thomas Tester,test@example.org,1234567890
--------------------------------------------------------------------------------
/third_party/kindeditor/themes/common/rm.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/third_party/kindeditor/themes/common/rm.gif
--------------------------------------------------------------------------------
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | service_name: travis-ci
2 | coverage_clover: tests/phpunit/clover.xml
3 | json_path: tests/phpunit/coveralls-upload.json
4 |
--------------------------------------------------------------------------------
/database/migrations/pgsql/20241209010200_add_hm_version_columns.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE hm_user_session
2 | ADD COLUMN hm_version INT DEFAULT 1;
3 |
--------------------------------------------------------------------------------
/database/migrations/sqlite/20241209010200_add_hm_version_columns.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE hm_user_session
2 | ADD COLUMN hm_version INT DEFAULT 1;
3 |
--------------------------------------------------------------------------------
/third_party/kindeditor/themes/common/blank.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/third_party/kindeditor/themes/common/blank.gif
--------------------------------------------------------------------------------
/third_party/kindeditor/themes/common/flash.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/third_party/kindeditor/themes/common/flash.gif
--------------------------------------------------------------------------------
/third_party/kindeditor/themes/common/media.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/third_party/kindeditor/themes/common/media.gif
--------------------------------------------------------------------------------
/modules/smtp/assets/markdown/fonts/icomoon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/modules/smtp/assets/markdown/fonts/icomoon.woff
--------------------------------------------------------------------------------
/third_party/kindeditor/themes/common/anchor.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/third_party/kindeditor/themes/common/anchor.gif
--------------------------------------------------------------------------------
/third_party/kindeditor/themes/common/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/third_party/kindeditor/themes/common/loading.gif
--------------------------------------------------------------------------------
/third_party/kindeditor/themes/default/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/third_party/kindeditor/themes/default/default.png
--------------------------------------------------------------------------------
/modules/account/site.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 | $('.delete_user_form').on('submit', function() {
3 | return hm_delete_prompt();
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/modules/core/assets/fonts/Behdad/Behdad-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/modules/core/assets/fonts/Behdad/Behdad-Regular.woff
--------------------------------------------------------------------------------
/modules/core/assets/fonts/Behdad/Behdad-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/modules/core/assets/fonts/Behdad/Behdad-Regular.woff2
--------------------------------------------------------------------------------
/modules/history/site.css:
--------------------------------------------------------------------------------
1 | .history_links { width: 70%; white-space: nowrap; padding: 20px; padding-left: 30px; }
2 | .history_links td { padding: 5px; }
3 |
--------------------------------------------------------------------------------
/third_party/kindeditor/themes/default/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/third_party/kindeditor/themes/default/background.png
--------------------------------------------------------------------------------
/modules/feeds/js_modules/route_handlers.js:
--------------------------------------------------------------------------------
1 | function applyFeedMessageContentPageHandlers(routeParams) {
2 | feed_item_view(routeParams.uid, routeParams.list_path);
3 | }
--------------------------------------------------------------------------------
/modules/profiles/js_modules/route_handlers.js:
--------------------------------------------------------------------------------
1 | function applyProfilesPageHandler() {
2 | $('.add_profile').on("click", function() { $('.edit_profile').show(); });
3 | }
--------------------------------------------------------------------------------
/modules/saved_searches/README.md:
--------------------------------------------------------------------------------
1 | ## Saved searches
2 |
3 | This module set allows users to save the parameters of a search, and quickly
4 | access it again from the menu.
5 |
--------------------------------------------------------------------------------
/modules/site/README.md:
--------------------------------------------------------------------------------
1 | ## Site
2 |
3 | This module set provides sites a way to add features to Cypht, or to override
4 | existing behavior without modifying any Cypht code.
5 |
--------------------------------------------------------------------------------
/RELEASE_NOTES:
--------------------------------------------------------------------------------
1 | This is a placeholder for the release notes that will be updated each time we
2 | create a release. New development goes on in this branch, so be aware things
3 | may break!
4 |
--------------------------------------------------------------------------------
/modules/recaptcha/README.md:
--------------------------------------------------------------------------------
1 | ## Recaptcha
2 |
3 | This module set enables Google Recaptcha support for the login page requiring
4 | users to "prove" they are not a bot when attempting to login.
5 |
--------------------------------------------------------------------------------
/modules/themes/assets/default/fonts/roboto-condensed-v14-latin-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/modules/themes/assets/default/fonts/roboto-condensed-v14-latin-regular.woff
--------------------------------------------------------------------------------
/modules/themes/assets/default/fonts/roboto-condensed-v14-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Revisto/cypht/master/modules/themes/assets/default/fonts/roboto-condensed-v14-latin-regular.woff2
--------------------------------------------------------------------------------
/modules/carddav_contacts/README.md:
--------------------------------------------------------------------------------
1 | ## CardDav module set
2 |
3 | Initial support for contacts from a CardDav server. Servers must be defined in the carddav.php file. As of right now support is read-only.
4 |
--------------------------------------------------------------------------------
/modules/themes/README.md:
--------------------------------------------------------------------------------
1 | ## Themes
2 |
3 | This module set provides users the ability to select from different UI themes.
4 | A theme in Cypht is just a simple CSS file that overrides the default layout.
5 |
--------------------------------------------------------------------------------
/modules/keyboard_shortcuts/README.md:
--------------------------------------------------------------------------------
1 | ## Keyboard shortcuts
2 |
3 | This module set adds the ability to use keyboard shortcuts to navigate Cypht,
4 | and adds a menu entry to the Settings menu so they can be customized.
5 |
--------------------------------------------------------------------------------
/modules/keyboard_shortcuts/js_modules/route_handlers.js:
--------------------------------------------------------------------------------
1 | function applyShortcutsPageHandlers() {
2 | $('.reset_shortcut').on("click", function() {
3 | Hm_Utils.redirect('?page=shortcuts');
4 | });
5 | }
6 |
--------------------------------------------------------------------------------
/modules/hello_world/README.md:
--------------------------------------------------------------------------------
1 | ## Hello world
2 |
3 | This module set is an example set to explain to developers how module
4 | sets work in Cypht. It has a lot of comments in the code to explain
5 | how module sets work.
6 |
--------------------------------------------------------------------------------
/modules/history/js_modules/route_handlers.js:
--------------------------------------------------------------------------------
1 | function applyHistoryPageHandlers() {
2 | // When Message list style setting is set to news
3 | $('.news_cell').removeClass('checkbox_cell');
4 | $('.news_cell').attr('colspan', 5);
5 | }
--------------------------------------------------------------------------------
/modules/imap/README.md:
--------------------------------------------------------------------------------
1 | ## IMAP
2 |
3 | This module set allows you to read and manage messages in E-mail accounts using
4 | the IMAP protocol. If you are using Cypht as a webmail program, you definitely
5 | want this module set enabled.
6 |
--------------------------------------------------------------------------------
/modules/wordpress/site.css:
--------------------------------------------------------------------------------
1 | .wordpress_connect_section { padding: 20px; padding-bottom: 40px; display: none; padding-left: 40px; }
2 | .wp_disconnect { margin-left: 20px; margin-top: 20px; }
3 | .wp_notifications_setting { display: none; }
4 |
--------------------------------------------------------------------------------
/modules/recover_settings/site.css:
--------------------------------------------------------------------------------
1 | .menu_recover_settings .unread_link { font-weight: bold; }
2 | .recover_form { max-width: 600px; margin-left: 30px; margin-top: 20px; max-width: 60%; color: #666; }
3 | .recover_form input { margin-top: 20px; }
4 |
--------------------------------------------------------------------------------
/modules/ldap_contacts/site.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function() {
4 | $('.ldap_password_change').on("click", function() {
5 | $(this).prev().prop('disabled', false);
6 | $(this).prev().attr('placeholder', '');
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/.github/tests/scripts/postfix.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | sudo systemctl stop postfix.service
4 | sudo sed -i 's/#myorigin/myorigin/g' /etc/postfix/main.cf
5 | sudo -H postconf virtual_transport=lmtp:unix:private/dovecot-lmtp
6 | sudo systemctl start postfix.service
--------------------------------------------------------------------------------
/modules/calendar/README.md:
--------------------------------------------------------------------------------
1 | ## Calendar
2 |
3 | This module set provides a basic calendar, with limited event support. Some
4 | work has gone into providing integration with CalDav/Ical formats, however
5 | there is a lot of work left to go for that.
6 |
7 |
--------------------------------------------------------------------------------
/modules/carddav_contacts/site.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function() {
4 | $('.carddav_password_change').on("click", function() {
5 | $(this).prev().prop('disabled', false);
6 | $(this).prev().attr('placeholder', '');
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/modules/inline_message/README.md:
--------------------------------------------------------------------------------
1 | ## Inline message
2 |
3 | This module set provides options to users to view message content inline in the
4 | message list instead of opening a new window. This behavior can be controlled
5 | from the Settings->Site page.
6 |
--------------------------------------------------------------------------------
/modules/local_contacts/README.md:
--------------------------------------------------------------------------------
1 | ## Local contacts
2 |
3 | This module set provides built in (and very basic) contact support in Cypht.
4 | Like all other contact sources (gmail, ldap), the generic contacts module set
5 | must also be enabled for this to work.
6 |
--------------------------------------------------------------------------------
/modules/idle_timer/README.md:
--------------------------------------------------------------------------------
1 | ## Idle timer
2 |
3 | This module set allows user to designate an idle timeout that will cause them
4 | to be logged out of Cypht once it expires. It is not compatible with the api
5 | login module set, so make sure to disable it if using that.
6 |
--------------------------------------------------------------------------------
/modules/tags/site.css:
--------------------------------------------------------------------------------
1 | .tag_icon { position: absolute; right: 50px; top: 18px; }
2 | .mobile .tag_icon { display: none; }
3 | .tags_action_btn { width: 30px !important; height: 30px !important; }
4 | .mr-4 { margin-right: 4px !important; }
5 | .tag_setting { display: none; }
6 |
--------------------------------------------------------------------------------
/modules/core/assets/fonts/Behdad/README.md:
--------------------------------------------------------------------------------
1 | Thanks to [font-store](https://github.com/font-store) and the designer [Mohammad Saleh Souzanchi](http://github.com/zoghal) who made this awesome Persian/Arabic Open Source font which is [Behdad](https://github.com/font-store/BehdadFont).
--------------------------------------------------------------------------------
/modules/github/README.md:
--------------------------------------------------------------------------------
1 | ## Github
2 |
3 | This module set adds Github notification support to Cypht. It provides the
4 | ability to add repositories to monitor in the Settings->Servers page, adds
5 | a section to the menu to view them, and integrates with the combined views.
6 |
--------------------------------------------------------------------------------
/modules/imap_folders/README.md:
--------------------------------------------------------------------------------
1 | ## IMAP Folders
2 |
3 | This module set provides users with the ability to add/rename/delete folders
4 | in there IMAP accounts. It requires the imap module set to work. It also supports
5 | assigning special folders to an account (Sent/Trash).
6 |
--------------------------------------------------------------------------------
/modules/smtp/README.md:
--------------------------------------------------------------------------------
1 | ## SMTP
2 |
3 | This module set provides support for sending E-mail using Cypht. It supports
4 | plain text, HTML, and markdown formatted messages. It adds a section to the
5 | Settings->Servers page for users to add as many SMTP servers as they want.
6 |
--------------------------------------------------------------------------------
/modules/hello_world/js_modules/route_handlers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * If we are on the "hello_world" page, activate the click handler
3 | */
4 | function applyHelloWorldPageHandlers() {
5 | $('.hw_ajax_link').on("click", function() {
6 | hello_world_ajax_update();
7 | });
8 | }
--------------------------------------------------------------------------------
/modules/ldap_contacts/README.md:
--------------------------------------------------------------------------------
1 | ## LDAP Contacts
2 |
3 | This module set adds support for using one or more LDAP servers to store
4 | contacts. Contact sources can be read/write or read only. Sites must
5 | enable the contacts module set and setup the ldap.php file for it to work.
6 |
--------------------------------------------------------------------------------
/modules/nasa/README.md:
--------------------------------------------------------------------------------
1 | ## NASA
2 |
3 | This module set uses the NASA API to provide the APOD (Astronomy Picture Of the
4 | Day) inside Cypht. It adds a menu entry and a page that display the image and
5 | description, and a dialog in the Settings->Server page to configure that API.
6 |
--------------------------------------------------------------------------------
/modules/api_login/README.md:
--------------------------------------------------------------------------------
1 | ## API Login
2 |
3 | This module set helps make it easier to integrate Cypht with other web
4 | applications making "single sign on" possible. More information about
5 | how this works can be found here:
6 |
7 | https://github.com/cypht-org/cypht/wiki/API-Login
8 |
--------------------------------------------------------------------------------
/modules/wordpress/README.md:
--------------------------------------------------------------------------------
1 | ## Wordpress
2 |
3 | This module set uses the WordPress.com API to integrate WordPress notices into
4 | Cypht. It adds a WordPress section to the menu that displays notifications, and
5 | a dialog to the Settings->Site page to setup the connection to WordPress.
6 |
--------------------------------------------------------------------------------
/tests/selenium/requirements.txt:
--------------------------------------------------------------------------------
1 | attrs==23.1.0
2 | certifi==2024.7.4
3 | h11==0.16.0
4 | idna==3.7
5 | outcome==1.2.0
6 | PySocks==1.7.1
7 | selenium==4.14.0
8 | sniffio==1.3.0
9 | sortedcontainers==2.4.0
10 | trio==0.22.2
11 | trio-websocket==0.11.1
12 | urllib3==2.5.0
13 | wsproto==1.2.0
14 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | We appreciate all feedback and support of the project.
2 | Please use the issue tracker at GitHub to submit bug reports or feature requests:
3 |
4 | https://github.com/cypht-org/cypht/issues
5 |
6 | If you have questions, please join our chat at: https://gitter.im/cypht-org/community
7 |
--------------------------------------------------------------------------------
/modules/sievefilters/js_modules/route_handlers.js:
--------------------------------------------------------------------------------
1 | function applyBlockListPageHandlers() {
2 | blockListPageHandlers();
3 | }
4 |
5 | function applySieveFiltersPageHandler() {
6 | sieveFiltersPageHandler();
7 |
8 | return () => {
9 | cleanUpSieveFiltersPage();
10 | };
11 | }
--------------------------------------------------------------------------------
/modules/core/js_modules/utils/messageList.js:
--------------------------------------------------------------------------------
1 | function triggerNewMessageEvent(uid, row) {
2 | const newRowEvent = new CustomEvent('new-message', {
3 | detail: {
4 | uid: uid,
5 | row: row,
6 | }
7 | });
8 | window.dispatchEvent(newRowEvent);
9 | }
10 |
--------------------------------------------------------------------------------
/modules/history/README.md:
--------------------------------------------------------------------------------
1 | ## History
2 |
3 | This module set provides a history of all the content a user has access since
4 | they last logged in to Cypht. The history itself is entirely saved in Javascript,
5 | and only records content views like reading an E-mail message, github notice, feed
6 | item, etc.
7 |
--------------------------------------------------------------------------------
/modules/nux/README.md:
--------------------------------------------------------------------------------
1 | ## NUX
2 |
3 | NUX is short for "New User Experience" and is a module set intented to make
4 | using Cypht easier for new users. It adds a help dialog to the home page (which
5 | needs content), and a wizard to walk users through adding new E-mail accounts
6 | to the Settings->Server page.
7 |
--------------------------------------------------------------------------------
/modules/dynamic_login/README.md:
--------------------------------------------------------------------------------
1 | ## Dynamic login
2 |
3 | This module set enables a special login flow allowing you to select
4 | at login the E-mail service you want to authenticate with. It supports
5 | many existing E-mail service providers, and has a custom domain option
6 | that attempts to auto-discover how to login.
7 |
--------------------------------------------------------------------------------
/modules/core/js_modules/utils/popovers.js:
--------------------------------------------------------------------------------
1 | function sessionAvailableOnlyActionInfo(element) {
2 | return new bootstrap.Popover(element, {
3 | title: 'Session-limited action',
4 | content: 'Note that the action will persist only during the current session, unless the settings are saved.',
5 | trigger: 'hover',
6 | });
7 | }
--------------------------------------------------------------------------------
/config/carddav.php:
--------------------------------------------------------------------------------
1 | [
12 | 'server' => env('CARD_DAV_SERVER', 'http://localhost:5232'),
13 | ]
14 | ];
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🚀 Feature
3 | about: Suggest an idea for this project
4 | labels: feature
5 | title: 🚀 [Feature]
6 | ---
7 |
8 |
9 | ## 🚀 Feature
10 |
11 |
--------------------------------------------------------------------------------
/.github/tests/scripts/dovecot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | systemctl stop dovecot.service
4 | sudo echo "disable_plaintext_auth = no" >> /etc/dovecot/conf.d/10-auth.conf
5 | sudo sed -i "s/auth_mechanisms = plain/auth_mechanisms = plain login/g" /etc/dovecot/conf.d/10-auth.conf
6 | sudo sed -i "s/ssl = yes/ssl = no/g" /etc/dovecot/conf.d/10-ssl.conf
7 | systemctl start dovecot.service
--------------------------------------------------------------------------------
/modules/account/README.md:
--------------------------------------------------------------------------------
1 | ## Account
2 |
3 | This module set provides some basic user management and password changing
4 | capabilities inside of Cypht. It only works for sites using the DB
5 | authentication type. When enabled, it allows users to change there password
6 | from the Settings menu, and allows sites to designate admins that can create or
7 | delete user accounts.
8 |
--------------------------------------------------------------------------------
/modules/feeds/README.md:
--------------------------------------------------------------------------------
1 | ## Feeds
2 |
3 | This module set adds RSS/ATOM feed reading support to Cypht. It adds a new
4 | section to the menu for configured feeds, allows them to be integrated into the
5 | combined views, and provides add/remove feed options to the Settings->Servers
6 | page. Like E-mail content, feeds are filtered for security removing any remote
7 | resources.
8 |
--------------------------------------------------------------------------------
/modules/desktop_notifications/README.md:
--------------------------------------------------------------------------------
1 | ## Desktop Notifications
2 |
3 | This module set enables desktop notifications for newly arrived content
4 | to the Unread page. It uses the notifications API in JavaScript.
5 |
6 | https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API
7 |
8 | Users must opt-in in there browser to receive notifications.
9 |
--------------------------------------------------------------------------------
/tests/selenium/runall.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PYTHON=$(command -v python3)
4 | rm -rf __pycache__/
5 |
6 | for suite in login.py folder_list.py pages.py profiles.py settings.py servers.py send.py search.py inline_msg.py keyboard_shortcuts.py
7 | do
8 | export TEST_SUITE="$suite"
9 | "$PYTHON" -u ./$suite
10 | if [ $? -ne 0 ]; then
11 | exit 1
12 | fi
13 | done
14 |
--------------------------------------------------------------------------------
/modules/tags/README.md:
--------------------------------------------------------------------------------
1 | ## Tags
2 |
3 | This module allows users to organize content effectively by utilizing tags/labels. It is designed to enhance content management by enabling users to assign relevant tags, facilitating easy categorization, filtering, and retrieval of content. The tagging feature is fully implemented, allowing for seamless interaction where users can add, edit, or remove tags as needed.
4 |
--------------------------------------------------------------------------------
/scripts/build_changelog.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Should we continue to use this?
4 |
5 |
6 | CYPHT_DIR="/home/jason/cypht"
7 |
8 | cd "$CYPHT_DIR"
9 | git log --pretty=format:'%h% - %s [%aD]' \
10 | --abbrev-commit \
11 | --since 2017-05-11 \
12 | --graph release-1.1.0 \
13 | | sed -r "s/[|\*\/\\]//g" \
14 | | tr -s ' ' \
15 | | grep -v '^ $' \
16 | | sed -r "s/^ //" > CHANGES
17 |
--------------------------------------------------------------------------------
/modules/recover_settings/README.md:
--------------------------------------------------------------------------------
1 | ## Recover settings
2 |
3 | This module set provides users the ability to recover settings after a password
4 | change. Cypht encrypts user settings with the user password as the basis for
5 | the encryption key, so if that is changed externally, the user settings cannot
6 | be decrypted. Using this module set, users can enter there old and new
7 | passwords, and the settings can be converted.
8 |
--------------------------------------------------------------------------------
/modules/2fa/README.md:
--------------------------------------------------------------------------------
1 | ## 2FA
2 |
3 | This module set provides the ability for users to enable "two factor
4 | authentication" (2fa), requiring a user to enter a one time code from an
5 | authentication app (like Google Authenticator). It uses the TOTP protocol and
6 | provides a QR code image in the settings page to make it easy to setup in
7 | authentication apps. It also provides backup code support in case of account
8 | lock out.
9 |
--------------------------------------------------------------------------------
/scripts/release_changes.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Should we continue to use this?
4 |
5 | CYPHT_DIR="/home/jason/cypht"
6 | VERSION="v1.1.0-rc4"
7 | SINCE="2017-05-11"
8 |
9 | cd "$CYPHT_DIR"
10 | git log --pretty=format:'%h% - %s [%aD]' \
11 | --abbrev-commit \
12 | --since "$SINCE" \
13 | "$VERSION"..HEAD \
14 | | sed -r "s/[|\*\/\\]//g" \
15 | | tr -s ' ' \
16 | | grep -v '^ $' \
17 | | sed -r "s/^ //"
18 |
--------------------------------------------------------------------------------
/.github/tests/selenium/webdriver/webdriver.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | VERSION=$(
4 | dpkg -s google-chrome-stable | grep Version | awk '{print $2}' | sed 's/-.*//'
5 | )
6 |
7 | wget -O /tmp/chromedriver-linux64.zip https://storage.googleapis.com/chrome-for-testing-public/"${VERSION}"/linux64/chromedriver-linux64.zip
8 |
9 | unzip /tmp/chromedriver-linux64.zip -d /tmp
10 |
11 | mv /tmp/chromedriver-linux64/chromedriver /usr/bin/chromedriver
12 |
--------------------------------------------------------------------------------
/modules/gmail_contacts/README.md:
--------------------------------------------------------------------------------
1 | ## Gmail contacts
2 |
3 | This module set provides read-only access to Gmail contacts associated
4 | with any Gmail account setup in Cypht. Gmail accounts must be enabled
5 | using the "add new account" feature of the nux module set and must use
6 | the Oauth2 authentication methods, since that is the only way we can
7 | access the contacts API.
8 |
9 | Related: https://www.cypht.org/cypht-enable-gmail-oauth/
10 |
--------------------------------------------------------------------------------
/.travis/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | phpunit_tests() {
4 | cd tests/phpunit/ && /usr/local/bin/phpunit && cd ../../
5 | }
6 |
7 | selenium_tests() {
8 | cd tests/selenium/ && sh ./runall.sh && cd ../../
9 | }
10 |
11 | BUILD="$DB$TRAVIS_PHP_VERSION"
12 | case "$BUILD" in
13 | postgresql8.1)
14 | #phpunit_tests && selenium_tests
15 | phpunit_tests
16 | ;;
17 | *)
18 | phpunit_tests
19 | ;;
20 | esac
21 |
--------------------------------------------------------------------------------
/modules/github/site.css:
--------------------------------------------------------------------------------
1 | .github_connect_section { padding: 20px; padding-bottom: 40px; display: none; padding-left: 40px; }
2 | .github_connect_section .add_server { width: 180px; }
3 | .github_connect_section .server_title { margin-bottom: 10px; }
4 | .github_link { margin-left: 10px; display: inline; }
5 | .github_all_setting { display: none; }
6 | .github_para { white-space: pre; border-bottom: solid 1px #ccc; padding-bottom: 20px; margin-bottom: 20px; }
7 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/devops.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 💥 DevOp
3 | about: Help us manage our deployed Software.
4 | labels: devops
5 | title: 💥 [DevOps]
6 | ---
7 |
8 |
9 | ## 💥 DevOps
10 |
11 |
--------------------------------------------------------------------------------
/modules/account/site.css:
--------------------------------------------------------------------------------
1 | .create_user { margin-top: 20px; margin-left: 10px; }
2 | .create_user input { clear: both; float: left; padding: 4px; margin-left: 20px; margin-top: 10px; margin-bottom: 10px; }
3 | .create_account_link { margin-left: 120px; float: left; clear: left; font-size: 115%; padding: 5px; }
4 | .user_list { padding-left: 40px; padding-top: 20px; }
5 | .user_list td {padding-bottom: 10px; }
6 | .user_list .user_delete { cursor: pointer; margin-right: 10px; }
7 |
--------------------------------------------------------------------------------
/modules/core/js_modules/actions/search.js:
--------------------------------------------------------------------------------
1 | function performSearch(routeParams) {
2 | if (routeParams.search_terms) {
3 | const messages = new Hm_MessagesStore('search', Hm_Utils.get_url_page_number(), `${routeParams.search_terms}_${routeParams.search_fld}_${routeParams.search_since}`, routeParams.sort);
4 | messages.load(true, false, false, function() {
5 | display_imap_mailbox(messages.rows, messages.list, messages);
6 | });
7 | }
8 | }
--------------------------------------------------------------------------------
/modules/imap/modules.php:
--------------------------------------------------------------------------------
1 |
8 |
9 | ## 🔧 Refactor
10 |
11 |
--------------------------------------------------------------------------------
/modules/desktop_notifications/modules.php:
--------------------------------------------------------------------------------
1 | ';
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/modules/highlights/site.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | $(function() {
4 | $('.rule_del').on('click', function() {
5 | return hm_delete_prompt();
6 | });
7 | $('.hl_source_type').on('change', function() {
8 | $('.imap_row').addClass('d-none');
9 | $('.github_row').addClass('d-none');
10 | $('.feeds_row').addClass('d-none');
11 | var selected = $(this).val();
12 | $('.'+selected+'_row').removeClass('d-none');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/epic.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🌟 Epic
3 | about: Define a big development Step
4 | labels: epic
5 | title: 🌟 [EPIC]
6 | ---
7 |
8 |
9 |
10 |
11 |
12 | ## 🌟 EPIC
13 |
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/release.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🎂 Release
3 | about: Define a Release
4 | labels: release
5 | title: 🎂 [RELEASE]
6 | ---
7 |
8 |
9 |
10 |
11 |
12 | ## 🎂 RELEASE
13 |
14 |
--------------------------------------------------------------------------------
/modules/hello_world/site.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Style defined here will be combined and optionally minified with css from other
3 | * modules duing the build process. Only one css file is used in normal mode. All
4 | * individual css files from all activated modules are used in DEBUG_MODE
5 | */
6 | .hw { float: right; margin-right: 200px; margin-top: 5px; }
7 | .hwpage { width: 100%; font-size: 80pt; text-align: center; margin-top: 100px; color: #aaa; }
8 | .hw_ajax_link { font-size: 12pt; cursor: pointer; }
9 |
--------------------------------------------------------------------------------
/tests/phpunit/elog.php:
--------------------------------------------------------------------------------
1 | assertEquals('string: test', elog('test'));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/database/mysql_schema.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS hm_user (
2 | username VARCHAR(255),
3 | hash VARCHAR(255),
4 | PRIMARY KEY (username)
5 | );
6 |
7 | CREATE TABLE IF NOT EXISTS hm_user_session (
8 | hm_id VARCHAR(255),
9 | data LONGBLOB,
10 | date TIMESTAMP,
11 | hm_version INT DEFAULT 1,
12 | PRIMARY KEY (hm_id)
13 | );
14 |
15 | CREATE TABLE IF NOT EXISTS hm_user_settings (
16 | username VARCHAR(255),
17 | settings LONGBLOB,
18 | PRIMARY KEY (username)
19 | );
--------------------------------------------------------------------------------
/modules/desktop_notifications/setup.php:
--------------------------------------------------------------------------------
1 | array(
12 | ),
13 | 'allowed_output' => array(
14 | ),
15 | 'allowed_get' => array(
16 | ),
17 | 'allowed_post' => array(
18 | )
19 | );
20 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 | ## 💬 Issue
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/modules/profiles/README.md:
--------------------------------------------------------------------------------
1 | ## Profiles
2 |
3 | This module set adds a Profile page to the Settings menu that allows users to
4 | configure profiles. A profile ties together an IMAP server, an SMTP server, and
5 | values for the users E-mail address, reply to address, display name, and
6 | signature. A profile is required for Cypht to be able to save an outbound
7 | message into an IMAP server Sent folder. When composing a message users can
8 | select which profile to use, and when replying the profile is automatically
9 | selected.
10 |
--------------------------------------------------------------------------------
/tests/selenium/get_config.php:
--------------------------------------------------------------------------------
1 | load();
9 |
10 | /* get config object */
11 | $config = new Hm_Site_Config_File();
12 | /* set the default since and per_source values */
13 | $environment->define_default_constants($config);
14 | $config = merge_config_files('../../config');
15 |
16 | echo json_encode($config);
17 |
--------------------------------------------------------------------------------
/modules/calendar/js_modules/route_handlers.js:
--------------------------------------------------------------------------------
1 | function applyCalendarPageHandlers() {
2 | $('.event_delete').on("click", function() {
3 | if (hm_delete_prompt()) {
4 | $(this).parent().submit();
5 | }
6 | });
7 | $('.cal_title').on("click", function(e) {
8 | e.preventDefault();
9 | $('.event_details').hide();
10 | $('.event_details', $(this).parent()).show();
11 | $('.event_details').on("click", function() {
12 | $(this).hide();
13 | });
14 | });
15 | }
--------------------------------------------------------------------------------
/modules/developer/site.css:
--------------------------------------------------------------------------------
1 | .hmod_val, .omod_val, .hmod, .omod { color: #666; display: none; padding: 4px; padding-left: 60px; }
2 | .config_map_page { color: #666; font-size: 110%; cursor: pointer; padding-top: 20px; padding-left: 40px; }
3 | .config_map { margin-left: 40px; min-width: 400px; }
4 | .config_map th {border-bottom: solid 1px #eee; padding-left: 20px; display: none; padding-top: 10px; color: #666; font-size: 90%; text-align: left; }
5 | .config_map th { padding-left: 60px; }
6 | .config_map img { width: 16px; height: 16px; opacity: .6 }
7 |
--------------------------------------------------------------------------------
/modules/saved_searches/site.css:
--------------------------------------------------------------------------------
1 | .saved_searches_form { margin-left: 30px; }
2 | .saved_searches_form input { margin-left: 3px; margin-right: 3px; }
3 | .update_search_label img { opacity: .5; position: absolute; right: 105px; top: 21px; }
4 | .update_saved_search_title { color: #666; font-size: 110%; padding: 5px; margin-bottom: 10px; }
5 | .update_search img { opacity: .5; position: absolute; right: 135px; top: 22px; }
6 |
7 | .mobile .save_search, .mobile .update_search_label, .mobile .delete_search, .mobile .add_search { display: none !important; }
8 |
--------------------------------------------------------------------------------
/modules/tags/modules.php:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 | ## 💬 Question
13 |
14 |
--------------------------------------------------------------------------------
/modules/dynamic_login/setup.php:
--------------------------------------------------------------------------------
1 | array(),
13 | 'allowed_cookie' => array(),
14 | 'allowed_server' => array(),
15 | 'allowed_get' => array(),
16 | 'allowed_post' => array('email_provider' => FILTER_UNSAFE_RAW)
17 | );
18 |
--------------------------------------------------------------------------------
/tests/phpunit/data/schema_sqlite.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS hm_user;
2 |
3 | DROP TABLE IF EXISTS hm_user_session;
4 |
5 | DROP TABLE IF EXISTS hm_user_settings;
6 |
7 | CREATE TABLE IF NOT EXISTS hm_user (username varchar(255), hash varchar(255), primary key (username));
8 |
9 | CREATE TABLE IF NOT EXISTS hm_user_session (hm_id varchar(255), data longblob, date timestamp, lock int default 0, hm_version int default 1, primary key (hm_id));
10 |
11 | CREATE TABLE IF NOT EXISTS hm_user_settings(username varchar(255), settings longblob, primary key (username));
12 |
--------------------------------------------------------------------------------
/.github/tests/selenium/nginx/php_fastcgi.conf:
--------------------------------------------------------------------------------
1 | # 404
2 | try_files $fastcgi_script_name =404;
3 |
4 | # default fastcgi_params
5 | include fastcgi_params;
6 |
7 | # fastcgi settings
8 | fastcgi_index index.php;
9 | fastcgi_buffers 8 16k;
10 | fastcgi_buffer_size 32k;
11 |
12 | # fastcgi params
13 | fastcgi_param DOCUMENT_ROOT $realpath_root;
14 | fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
15 | fastcgi_param PHP_ADMIN_VALUE "open_basedir=$base/:/usr/lib/php/:/tmp/";
--------------------------------------------------------------------------------
/modules/pgp/site.css:
--------------------------------------------------------------------------------
1 | .pgp_block { margin-bottom: 30px; margin-left: 40px; padding-top: 20px; }
2 | .priv_keys, .public_keys { display: none; }
3 | .private_key_count, .key_count { float: right; margin-right: 120px; font-size: 90%; }
4 | .pgp_msg_controls { display: none; position: absolute; right: 20px; top: 70px; }
5 | .pgp_sign { display: none; }
6 | .passphrase_prompt { display: none; text-align: center; top: 0px; padding: 20px; background-color: #fff; position: absolute; z-index: 101; left: 0; right: 0; margin: auto; width: 300px; border: solid 1px #ccc; border-top: none; }
7 |
--------------------------------------------------------------------------------
/database/sqlite_schema.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS hm_user (
2 | username TEXT NOT NULL,
3 | hash TEXT NOT NULL,
4 | PRIMARY KEY (username)
5 | );
6 |
7 | CREATE TABLE IF NOT EXISTS hm_user_session (
8 | hm_id TEXT NOT NULL,
9 | data BLOB,
10 | date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
11 | hm_version INT DEFAULT 1,
12 | lock INT DEFAULT 0,
13 | PRIMARY KEY (hm_id)
14 | );
15 |
16 | CREATE TABLE IF NOT EXISTS hm_user_settings (
17 | username TEXT NOT NULL,
18 | settings BLOB,
19 | PRIMARY KEY (username)
20 | );
21 |
--------------------------------------------------------------------------------
/config/recaptcha.php:
--------------------------------------------------------------------------------
1 | [
13 | /* Client secret for the recaptcha admin */
14 | 'secret' => env('RECAPTCHA_SECRET', ''),
15 |
16 | /* Site key from the recaptcha admin */
17 | 'site_key' => env('RECAPTCHA_SITE_KEY', '')
18 | ],
19 | ];
20 |
--------------------------------------------------------------------------------
/modules/recaptcha/setup.php:
--------------------------------------------------------------------------------
1 | array(
13 | 'g-recaptcha-response' => FILTER_UNSAFE_RAW
14 | )
15 | );
16 |
--------------------------------------------------------------------------------
/.github/tests/selenium/nginx/nginx-site.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | listen [::]:80;
4 | server_name cypht-test.org;
5 | set $base /var/www/cypht;
6 | root $base/site;
7 |
8 | # index.php
9 | index index.php;
10 |
11 | # index.php fallback
12 | location / {
13 | try_files $uri $uri/ /index.php?$query_string;
14 | }
15 |
16 | # handle .php
17 | location ~ \.php$ {
18 | fastcgi_pass unix:/run/php/php%VERSION%-fpm.sock;
19 | include nginxconfig/php_fastcgi.conf;
20 | }
21 | }
--------------------------------------------------------------------------------
/lib/session_redis.php:
--------------------------------------------------------------------------------
1 | conn = new Hm_Redis($this->site_config);
20 | return $this->conn->is_active();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/assets/data/server_accounts_sample.csv:
--------------------------------------------------------------------------------
1 | server_name;username;password;jmap_server;jmap_hide_from_combined_view;imap_server;imap_port;imap_tls;imap_hide_from_combined_view;smtp_server;smtp_port;smtp_tls;sieve_host;sieve_port;sieve_tls;profile_reply_to;profile_signature;profile_is_default
2 | Mailbox 1;email@example.org;secret;;FALSE;imap.example.org;993;TRUE;FALSE;smtp.example.org;465;TRUE;tls://imap.exemple.org;4190;true;email@example.org;;FALSE
3 | Mailbox 2;test@example2.org;secret2;jmap.example2.org;FALSE;;;;;smtp.example2.org;465;TRUE;tls://jmap.example2.org;4190;false;test@example2.org;my-signature;TRUE
--------------------------------------------------------------------------------
/tests/phpunit/page_redirect.php:
--------------------------------------------------------------------------------
1 | assertEquals(null, Hm_Dispatch::page_redirect('test', 200));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/docker/supervisord.conf:
--------------------------------------------------------------------------------
1 | [supervisord]
2 | nodaemon=true
3 | logfile=/var/log/supervisord.log
4 | pidfile=/var/run/supervisord.pid
5 |
6 | [program:nginx]
7 | command=/usr/sbin/nginx -g "daemon off;"
8 | autostart=true
9 | autorestart=true
10 | stdout_logfile=/dev/stdout
11 | stdout_logfile_maxbytes=0
12 | stderr_logfile=/dev/stderr
13 | stderr_logfile_maxbytes=0
14 |
15 | [program:php-fpm]
16 | command=php-fpm
17 | autostart=true
18 | autorestart=true
19 | stdout_logfile=/dev/stdout
20 | stdout_logfile_maxbytes=0
21 | stderr_logfile=/dev/stderr
22 | stderr_logfile_maxbytes=0
23 |
--------------------------------------------------------------------------------
/modules/themes/assets/lux/css/lux.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 | /*Bootswatch theme adapted by the Cypht Community for Cypht */
3 | /* Original Bootswatch information:
4 | * Bootswatch v5.3.1 (https://bootswatch.com)
5 | * Theme: lux
6 | * Copyright 2012-2023 Thomas Park
7 | * Licensed under MIT
8 | * Based on Bootstrap
9 | */
10 | /*!
11 | * Bootstrap v5.3.1 (https://getbootstrap.com/)
12 | * Copyright 2011-2023 The Bootstrap Authors
13 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
14 | */
15 | @import url('../../../../../vendor/thomaspark/bootswatch/dist/lux/bootstrap.min.css');
16 |
--------------------------------------------------------------------------------
/modules/themes/assets/yeti/css/yeti.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 | /*Bootswatch theme adapted by the Cypht Community for Cypht */
3 | /* Original Bootswatch information:
4 | * Bootswatch v5.3.1 (https://bootswatch.com)
5 | * Theme: yeti
6 | * Copyright 2012-2023 Thomas Park
7 | * Licensed under MIT
8 | * Based on Bootstrap
9 | */
10 | /*!
11 | * Bootstrap v5.3.1 (https://getbootstrap.com/)
12 | * Copyright 2011-2023 The Bootstrap Authors
13 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
14 | */
15 | @import url('../../../../../vendor/thomaspark/bootswatch/dist/yeti/bootstrap.min.css');
16 |
--------------------------------------------------------------------------------
/tests/phpunit/debug.php:
--------------------------------------------------------------------------------
1 | assertTrue(count(Hm_Debug::get()) > 4);
20 | }
21 | /**
22 | * @preserveGlobalState disabled
23 | * @runInSeparateProcess
24 | */
25 | }
26 |
--------------------------------------------------------------------------------
/modules/themes/assets/cosmo/css/cosmo.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 | /*Bootswatch theme adapted by the Cypht Community for Cypht */
3 | /* Original Bootswatch information:
4 | * Bootswatch v5.3.1 (https://bootswatch.com)
5 | * Theme: cosmo
6 | * Copyright 2012-2023 Thomas Park
7 | * Licensed under MIT
8 | * Based on Bootstrap
9 | */
10 | /*!
11 | * Bootstrap v5.3.1 (https://getbootstrap.com/)
12 | * Copyright 2011-2023 The Bootstrap Authors
13 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
14 | */
15 | @import url('../../../../../vendor/thomaspark/bootswatch/dist/cosmo/bootstrap.min.css');
16 |
--------------------------------------------------------------------------------
/modules/themes/assets/lumen/css/lumen.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 | /*Bootswatch theme adapted by the Cypht Community for Cypht */
3 | /* Original Bootswatch information:
4 | * Bootswatch v5.3.1 (https://bootswatch.com)
5 | * Theme: lumen
6 | * Copyright 2012-2023 Thomas Park
7 | * Licensed under MIT
8 | * Based on Bootstrap
9 | */
10 | /*!
11 | * Bootstrap v5.3.1 (https://getbootstrap.com/)
12 | * Copyright 2011-2023 The Bootstrap Authors
13 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
14 | */
15 | @import url('../../../../../vendor/thomaspark/bootswatch/dist/lumen/bootstrap.min.css');
16 |
--------------------------------------------------------------------------------
/modules/themes/assets/pulse/css/pulse.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 | /*Bootswatch theme adapted by the Cypht Community for Cypht */
3 | /* Original Bootswatch information:
4 | * Bootswatch v5.3.1 (https://bootswatch.com)
5 | * Theme: pulse
6 | * Copyright 2012-2023 Thomas Park
7 | * Licensed under MIT
8 | * Based on Bootstrap
9 | */
10 | /*!
11 | * Bootstrap v5.3.1 (https://getbootstrap.com/)
12 | * Copyright 2011-2023 The Bootstrap Authors
13 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
14 | */
15 | @import url('../../../../../vendor/thomaspark/bootswatch/dist/pulse/bootstrap.min.css');
16 |
--------------------------------------------------------------------------------
/modules/contacts/README.md:
--------------------------------------------------------------------------------
1 | ## Contacts
2 |
3 | This module set does not do anything by itself. It provides the framework
4 | for contact sources to be used in Cypht. Currently there are 3 contact
5 | sources supported:
6 |
7 | - local contacts: Basic contact support locally within Cypht
8 | - LDAP contacts: Uses an LDAP server to access/manage contacts
9 | - Gmail contacts: Read-only access to contacts from Gmail accounts
10 |
11 | One or all of those module sets can be enabled with this one to add contact
12 | support for that source. Some work has been done to add CardDav contact
13 | support, however there is much left to do.
14 |
--------------------------------------------------------------------------------
/modules/site/modules.php:
--------------------------------------------------------------------------------
1 |
8 |
9 | ## 🐛 Bug
10 |
11 |
12 | ### Version & Environment
13 |
14 | Rev: []
15 |
16 | OS: []
17 |
--------------------------------------------------------------------------------
/config/themes.php:
--------------------------------------------------------------------------------
1 | [
17 | "yourthemefile|Your Theme Name"
18 | ],
19 | ];
20 |
--------------------------------------------------------------------------------
/.github/tests/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | phpunit_tests() {
4 | phpunit --bootstrap vendor/autoload.php --configuration tests/phpunit/phpunit.xml --testdox
5 | }
6 |
7 | selenium_tests() {
8 | cp .github/tests/selenium/creds.py tests/selenium/
9 | cd tests/selenium/ && sh ./runall.sh && cd ../../
10 | }
11 |
12 | # Main
13 | echo "database: ${DB}"
14 | echo "php-version: ${PHP_V}"
15 | echo "test-arg: ${TEST_ARG}"
16 |
17 | ARG="${TEST_ARG}"
18 | case "$ARG" in
19 | phpunit)
20 | phpunit_tests
21 | ;;
22 | selenium)
23 | selenium_tests
24 | ;;
25 | *)
26 | phpunit_tests
27 | ;;
28 | esac
29 |
--------------------------------------------------------------------------------
/modules/pgp/js_modules/route_handlers.js:
--------------------------------------------------------------------------------
1 | function applyPgpPageHandlers() {
2 | $('.priv_title').on("click", function() { $('.priv_keys').toggle(); });
3 | $('.public_title').on("click", function() { $('.public_keys').toggle(); });
4 | $('.delete_pgp_key').on("click", function() { return hm_delete_prompt(); });
5 | $('#priv_key').on("change", function(evt) { Hm_Pgp.read_private_key(evt); });
6 | Hm_Pgp.list_private_keys();
7 | if (window.location.hash == '#public_keys') {
8 | $('.public_keys').toggle();
9 | }
10 | if (window.location.hash == '#private_keys') {
11 | $('.private_keys').toggle();
12 | }
13 | }
--------------------------------------------------------------------------------
/config/wordpress.php:
--------------------------------------------------------------------------------
1 | [
15 | 'client_id' => env('WORDPRESS_CLIENT_ID', ''),
16 | 'client_secret' => env('WORDPRESS_CLIENT_SECRET', ''),
17 | 'client_uri' => env('WORDPRESS_CLIENT_URI', '')
18 | ],
19 | ];
20 |
--------------------------------------------------------------------------------
/modules/api_login/setup.php:
--------------------------------------------------------------------------------
1 | array('process_api_login'),
15 | 'allowed_post' => array(
16 | 'hm_session' => FILTER_UNSAFE_RAW,
17 | 'hm_id' => FILTER_UNSAFE_RAW,
18 | 'api_login_key' => FILTER_UNSAFE_RAW
19 | )
20 | );
21 |
--------------------------------------------------------------------------------
/modules/core/js_modules/actions/privacy_controls.js:
--------------------------------------------------------------------------------
1 | async function addSenderToImagesWhitelist(email) {
2 | return new Promise((resolve, reject) => {
3 | Hm_Ajax.request([
4 | { name: "hm_ajax_hook", value: "ajax_privacy_settings" },
5 | { name: "images_whitelist", value: email },
6 | { name: "save_settings", value: true },
7 | { name: "update", value: true }
8 | ], (response) => {
9 | resolve(response);
10 | }, [], false, undefined, () => {
11 | Hm_Notices.show('An error occured while adding the sender to the whitelist', 'danger');
12 | reject();
13 | });
14 | });
15 | }
--------------------------------------------------------------------------------
/modules/developer/README.md:
--------------------------------------------------------------------------------
1 | ## Developer
2 |
3 | This module set provides tools that are useful for developers adding
4 | features to Cypht. It adds 2 pages to the Settings menu:
5 |
6 | - info: This page shows infromation about the Cypht installation,
7 | the status of existing server connections, and a configuration "map"
8 | that breaks down what modules are associated with what page, with
9 | links to the code online.
10 |
11 | - dev: This page just has some summary information about developing
12 | module sets for Cypht, and has some links to online resources.
13 |
14 | Cypht must be run in debug mode for these pages to be visible, in
15 | production mode they are disabled.
16 |
--------------------------------------------------------------------------------
/modules/core/modules.php:
--------------------------------------------------------------------------------
1 |
4 |
5 | DocumentRoot %TRAVIS_BUILD_DIR%/site
6 |
7 |
').replace(/$/, '
').replace(/\n/g, '');
31 | } else {
32 | html = html.replace(/\n/g, '
$&');
33 | }
34 | self.insertHtml(html).hideDialog().focus();
35 | }
36 | }
37 | }),
38 | textarea = K('textarea', dialog.div);
39 | textarea[0].focus();
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/tests/phpunit/environment.php:
--------------------------------------------------------------------------------
1 | load();
21 | $cypht_dotenv = $environment->get('CYPHT_DOTENV');
22 | $this->assertStringEndsWith(".env", $cypht_dotenv);
23 | }
24 |
25 | /**
26 | * @preserveGlobalState disabled
27 | * @runInSeparateProcess
28 | */
29 | public function test_get_default_value() {
30 | $environment = Hm_Environment::getInstance();
31 | $environment->load();
32 | $undifined_env_data = $environment::get('APP_VERSION', "DEFAUL_VALUE");
33 | $this->assertEquals('DEFAUL_VALUE', $undifined_env_data);
34 | }
35 |
36 | /**
37 | * @preserveGlobalState disabled
38 | * @runInSeparateProcess
39 | */
40 | public function test_get_environment_variables() {
41 | $environment = Hm_Environment::getInstance();
42 | $reflection = new ReflectionClass($environment);
43 | $method = $reflection->getMethod('get_environment_variables');
44 | $method->setAccessible(true);
45 | $env_vars = $method->invoke($environment);
46 | $expected = array_merge($_ENV, $_SERVER);
47 | $this->assertEquals($expected, $env_vars);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tests/selenium/runner.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | from sys import exc_info
4 | from traceback import print_exception
5 | from creds import DESIRED_CAP, success
6 |
7 | GREEN = '\033[32m'
8 | RED = '\033[31m'
9 | END = '\033[0m'
10 |
11 | def run_tests(obj, tests):
12 | passed = 0
13 | for name in tests:
14 | func = getattr(obj, name)
15 | try:
16 | func()
17 | print('%s %sPASSED%s' % (name, GREEN, END))
18 | passed += 1
19 | except Exception:
20 | print('%s %sFAILED%s' % (name, RED, END))
21 | exc_type, exc_value, exc_traceback = exc_info()
22 | print_exception(exc_type, exc_value, exc_traceback)
23 | print('')
24 | print('%s%s of %s PASSED%s' % (GREEN, passed, len(tests), END))
25 | print('')
26 | if (len(tests) > passed):
27 | print('%s%s of %s FAILED%s' % (RED, (len(tests) - passed), len(tests), END))
28 | if obj.browser == 'safari':
29 | print("Safari unresolved failures, continuing...")
30 | else:
31 | obj.end()
32 | exit(1);
33 | else:
34 | success(obj.driver)
35 | obj.end()
36 | return True
37 |
38 | def get_tests(class_name):
39 | res = []
40 | for method in class_name.__dict__:
41 | if not method.startswith('__'):
42 | res.append(method)
43 | return res
44 |
45 | def test_runner(class_name, tests=None):
46 | if not tests:
47 | tests = get_tests(class_name)
48 | if isinstance(DESIRED_CAP, list):
49 | for cap in DESIRED_CAP:
50 | run_tests(class_name(cap), tests)
51 | else:
52 | run_tests(class_name(), tests)
53 |
--------------------------------------------------------------------------------
/tests/phpunit/api.php:
--------------------------------------------------------------------------------
1 | assertEquals(array('unit' => 'test'), $api->command('asdf'));
17 | }
18 | /**
19 | * @preserveGlobalState disabled
20 | * @runInSeparateProcess
21 | */
22 | public function test_curl_setopt_post() {
23 | $api = new Hm_API_Curl();
24 | $this->assertEquals(array('unit' => 'test'), $api->command('asdf', array(), array('foo' => 'bar')));
25 | }
26 | /**
27 | * @preserveGlobalState disabled
28 | * @runInSeparateProcess
29 | */
30 | public function test_curl_result() {
31 | $api = new Hm_API_Curl();
32 | $this->assertEquals(array('unit' => 'test'), $api->command('asdf', array(), array('foo' => 'bar')));
33 | Hm_Functions::$exec_res = NULL;
34 | $this->assertEquals(array(), $api->command('asdf', array(), array('foo' => 'bar')));
35 | $api->format = 'binary';
36 | Hm_Functions::$exec_res = 'foo';
37 | $this->assertEquals('foo', $api->command('asdf', array(), 'bar'));
38 | }
39 | /**
40 | * @preserveGlobalState disabled
41 | * @runInSeparateProcess
42 | */
43 | public function test_curl_custom() {
44 | $api = new Hm_API_Curl('xml');
45 | $this->assertEquals('{"unit":"test"}', $api->command('asdf', array(), array(), 'foo', 'FOO'));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/modules/calendar/setup.php:
--------------------------------------------------------------------------------
1 | array(
22 | 'calendar',
23 | ),
24 | 'allowed_post' => array(
25 | 'event_title' => FILTER_UNSAFE_RAW,
26 | 'event_detail' => FILTER_UNSAFE_RAW,
27 | 'event_date' => FILTER_UNSAFE_RAW,
28 | 'event_time' => FILTER_UNSAFE_RAW,
29 | 'event_repeat' => FILTER_UNSAFE_RAW,
30 | 'delete_id' => FILTER_UNSAFE_RAW
31 | ),
32 | 'allowed_get' => array(
33 | 'date' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
34 | 'view' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
35 | 'action' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
36 | ),
37 | );
38 |
--------------------------------------------------------------------------------
/modules/core/js_modules/[cash]/extend.js:
--------------------------------------------------------------------------------
1 | /* extend cash.js with some useful bits */
2 | $.inArray = function(item, list) {
3 | for (var i in list) {
4 | if (list[i] === item) {
5 | return i;
6 | }
7 | }
8 | return -1;
9 | };
10 | $.isEmptyObject = function(obj) {
11 | for (var key in obj) {
12 | if (obj.hasOwnProperty(key)) {
13 | return false;
14 | }
15 | }
16 | return true;
17 | };
18 | $.fn.submit = function() { this[0].submit(); }
19 | $.fn.focus = function() { this[0].focus(); };
20 | $.fn.serializeArray = function() {
21 | var parts;
22 | var res = [];
23 | var args = this.serialize().split('&');
24 | for (var i in args) {
25 | parts = args[i].split('=');
26 | if (parts[0] && parts[1]) {
27 | res.push({'name': parts[0], 'value': parts[1]});
28 | }
29 | }
30 | return res.map(function(x) {return {name: x.name, value: decodeURIComponent(x.value.replace(/\+/g, " "))}});
31 | };
32 | $.fn.sort = function(sort_function) {
33 | var list = [];
34 | for (var i=0, len=this.length; i < len; i++) {
35 | list.push(this[i]);
36 | }
37 | return $(list.sort(sort_function));
38 | };
39 | $.fn.fadeOut = function(timeout = 600) {
40 | return this.css("opacity", 0)
41 | .css("transition", `opacity ${timeout}ms`)
42 | };
43 |
44 | $.fn.modal = function(action) {
45 | const modalElement = this[0];
46 | if (modalElement) {
47 | const modal = new bootstrap.Modal(modalElement);
48 | if (action === 'show') {
49 | modal.show();
50 | } else if (action === 'hide') {
51 | modal.hide();
52 | }
53 | }
54 | };
--------------------------------------------------------------------------------
/tests/phpunit/site_file_config.php:
--------------------------------------------------------------------------------
1 | config = new Hm_User_Config_File($mock_config);
15 | }
16 | /**
17 | * @preserveGlobalState disabled
18 | * @runInSeparateProcess
19 | */
20 | public function test_get_modules() {
21 | $config = new Hm_Site_Config_File(merge_config_files(APP_PATH.'tests/phpunit/data'));
22 | $this->assertFalse($config->get_modules());
23 | $config->set('modules', 'asdf');
24 | $this->assertEquals(array('asdf'), $config->get_modules());
25 | }
26 | /**
27 | * @preserveGlobalState disabled
28 | * @runInSeparateProcess
29 | */
30 | public function test_site_load() {
31 | $config = new Hm_Site_Config_File(merge_config_files(APP_PATH.'tests/phpunit/data'));
32 | $this->assertEquals(array('version' => VERSION, 'foo' => 'bar', 'default_setting_foo' => 'bar'), $config->dump());
33 | }
34 | /**
35 | * @preserveGlobalState disabled
36 | * @runInSeparateProcess
37 | */
38 | public function test_get_user_defaults() {
39 | $config = new Hm_Site_Config_File(merge_config_files(APP_PATH.'tests/phpunit/data'));
40 | $this->assertEquals(array('version' => VERSION, 'foo' => 'bar', 'default_setting_foo' => 'bar'), $config->dump());
41 | }
42 | public function tearDown(): void {
43 | unset($this->config);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/phpunit/user_config_functions.php:
--------------------------------------------------------------------------------
1 | config = new Hm_User_Config_File($mock_config);
15 | }
16 | /**
17 | * @preserveGlobalState disabled
18 | * @runInSeparateProcess
19 | */
20 | public function test_load_user_config_object() {
21 | /* TODO assertions */
22 | $mock_config = new Hm_Mock_Config();
23 | load_user_config_object($mock_config);
24 | $this->assertEquals('Hm_User_Config_File', get_class(load_user_config_object($mock_config)));
25 | $mock_config->set('user_config_type', 'DB');
26 | $this->assertEquals('Hm_User_Config_DB', get_class(load_user_config_object($mock_config)));
27 | $mock_config->set('user_config_type', 'custom:Hm_Mock_Config');
28 | $this->assertEquals('Hm_Mock_Config', get_class(load_user_config_object($mock_config)));
29 | }
30 | /**
31 | * @preserveGlobalState disabled
32 | * @runInSeparateProcess
33 | */
34 | public function test_crypt_state() {
35 | $site_config = new Hm_Mock_Config();
36 | $this->assertTrue(crypt_state($site_config));
37 | $site_config->set('auth_type', 'IMAP');
38 | $site_config->set('single_server_mode', true);
39 | $this->assertFalse(crypt_state($site_config));
40 | }
41 |
42 | public function tearDown(): void {
43 | unset($this->config);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/phpunit/output_module.php:
--------------------------------------------------------------------------------
1 | output_mod = new Hm_Output_Test(array('foo' => 'bar', 'bar' => 'foo'), array('bar'));
14 | }
15 | /**
16 | * @preserveGlobalState disabled
17 | * @runInSeparateProcess
18 | */
19 | public function test_output_content() {
20 | $this->output_mod->output_content('HTML5', array('Main' => false, 'Test' => 'Translated', 'interface_lang' => 'en', 'interface_direction' => 'ltr'), array());
21 | $this->assertEquals('Main', $this->output_mod->trans('Main'));
22 | $this->assertEquals('Translated', $this->output_mod->trans('Test'));
23 | }
24 | /**
25 | * @preserveGlobalState disabled
26 | * @runInSeparateProcess
27 | */
28 | public function test_trans() {
29 | $this->assertEquals('inbox', $this->output_mod->trans('inbox'));
30 | $this->assertEquals('Main', $this->output_mod->trans('Main'));
31 | }
32 | /**
33 | * @preserveGlobalState disabled
34 | * @runInSeparateProcess
35 | */
36 | public function test_html_safe() {
37 | $this->assertEquals('<script>', $this->output_mod->html_safe('