├── .coveralls.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── Vagrantfile ├── Vagrantfile.backup ├── Vagrantfile.digitalocean ├── composer.json ├── composer.lock ├── composer.phar ├── config ├── i18n │ ├── ar.ini │ ├── en.ini │ └── ja.ini └── init.php ├── etc ├── app.php ├── constants.php └── utils.php ├── files ├── apns-dev.pem └── apns-prod.pem ├── install ├── INSTALL ├── alterTable.sql ├── databaseschema.sql ├── designdocuments.dump └── resouces │ ├── categoryimages │ ├── cat_1.png │ ├── cat_2.png │ ├── cat_3.png │ ├── cat_4.png │ └── cat_5.png │ └── emoticons │ ├── adore.png │ ├── after_boom.png │ ├── ah.png │ ├── amazed.png │ ├── angry.png │ ├── bad_smelly.png │ ├── baffle.png │ ├── beat_brick.png │ ├── beat_plaster.png │ ├── beat_shot.png │ ├── beated.png │ ├── beauty.png │ ├── big_smile.png │ ├── boss.png │ ├── burn_joss_stick.png │ ├── byebye.png │ ├── canny.png │ ├── choler.png │ ├── cold.png │ ├── confident.png │ ├── confuse.png │ ├── cool.png │ ├── cry.png │ ├── doubt.png │ ├── dribble.png │ ├── embarrassed.png │ ├── extreme_sexy_girl.png │ ├── feel_good.png │ ├── go.png │ ├── haha.png │ ├── hell_boy.png │ ├── hungry.png │ ├── look_down.png │ ├── matrix.png │ ├── misdoubt.png │ ├── nosebleed.png │ ├── oh.png │ ├── ops.png │ ├── pudency.png │ ├── rap.png │ ├── sad.png │ ├── sexy_girl.png │ ├── shame.png │ ├── smile.png │ ├── spiderman.png │ ├── still_dreaming.png │ ├── sure.png │ ├── surrender.png │ ├── sweat.png │ ├── sweet_kiss.png │ ├── tire.png │ ├── too_sad.png │ ├── waaaht.png │ └── what.png ├── phpclient ├── activitySummaryTest.php ├── alltest.php └── hu_client.php ├── phpunit.xml.dist ├── src └── Spika │ ├── Controller │ ├── AsyncTaskController.php │ ├── CheckUniqueController.php │ ├── FileController.php │ ├── GeneralAPIHandlerController.php │ ├── GroupController.php │ ├── MessageController.php │ ├── PasswordResetController.php │ ├── ReportController.php │ ├── SearchUserController.php │ ├── SendPasswordController.php │ ├── ServerListController.php │ ├── SignoutController.php │ ├── SpikaBaseController.php │ ├── UserController.php │ ├── Web │ │ ├── Admin │ │ │ ├── EmoticonController.php │ │ │ ├── GroupCategoryController.php │ │ │ ├── GroupController.php │ │ │ ├── LoginController.php │ │ │ ├── NewsController.php │ │ │ ├── ServerController.php │ │ │ └── UserController.php │ │ ├── Client │ │ │ ├── LoginController.php │ │ │ └── MainController.php │ │ ├── Installer │ │ │ └── InstallerController.php │ │ ├── SpikaWebBaseController.php │ │ └── StaticPageController.php │ └── WebViewController.php │ ├── Db │ ├── CouchDb.php │ ├── DbInterface.php │ └── MySql.php │ ├── Middleware │ ├── APIGeneralBeforeHandler.php │ ├── AdminChecker.php │ └── TokenChecker.php │ ├── Provider │ ├── PushNotificationProvider.php │ ├── SpikaDbServiceProvider.php │ └── TokenCheckerServiceProvider.php │ └── Views │ ├── admin │ ├── adminBase.twig │ ├── alerts.twig │ ├── categoryDelete.twig │ ├── categoryForm.twig │ ├── categoryList.twig │ ├── dashboard.twig │ ├── emoticonDelete.twig │ ├── emoticonForm.twig │ ├── emoticonList.twig │ ├── groupAdd.twig │ ├── groupDelete.twig │ ├── groupEdit.twig │ ├── groupList.twig │ ├── groupProfile.twig │ ├── groupUserList.twig │ ├── login.twig │ ├── newsDelete.twig │ ├── newsForm.twig │ ├── newsList.twig │ ├── pager.twig │ ├── serversDelete.twig │ ├── serversForm.twig │ ├── serversList.twig │ ├── userAdd.twig │ ├── userConversationHistory.twig │ ├── userDelete.twig │ ├── userEdit.twig │ ├── userList.twig │ └── userProfile.twig │ ├── client │ ├── login.twig │ ├── main.twig │ ├── regist.twig │ └── resetpassword.twig │ ├── installer │ ├── installerError.twig │ ├── installerStep1.twig │ ├── installerStep2.twig │ ├── installerStep3.twig │ └── installerTop.twig │ ├── passwordReset │ ├── passwordReset.twig │ ├── passwordResetError.twig │ └── passwordResetSucceed.twig │ ├── static │ ├── eula_english.twig │ ├── eula_japanese.twig │ ├── information.twig │ └── tokenExpired.twig │ └── webview │ ├── alerts.twig │ ├── nav_bar.twig │ ├── newsListDevice.twig │ ├── newsViewDevice.twig │ ├── pager.twig │ └── webViewBaseForDevice.twig ├── tests ├── Spika │ ├── Controller │ │ ├── GroupControllerTest.php │ │ ├── MessageControllerTest.php │ │ ├── ReportControllerTest.php │ │ ├── SearchUserControllerTest.php │ │ └── UserControllerTest.php │ ├── Middleware │ │ └── TokenCheckerTest.php │ └── PsrTest.php ├── bootstrap.php └── define.php └── wwwroot ├── .htaccess ├── api.php ├── assets ├── css │ ├── bootstrap-theme.css │ ├── bootstrap-theme.min.css │ ├── bootstrap.css │ ├── bootstrap.min.css │ ├── datepicker.css │ ├── plugins │ │ ├── dataTables │ │ │ └── dataTables.bootstrap.css │ │ ├── morris │ │ │ └── morris-0.4.3.min.css │ │ ├── social-buttons │ │ │ └── social-buttons.css │ │ └── timeline │ │ │ └── timeline.css │ ├── sb-admin.css │ ├── sb-device.css │ └── spika-client.css ├── font-awesome │ ├── css │ │ ├── font-awesome.css │ │ └── font-awesome.min.css │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ └── fontawesome-webfont.woff │ ├── less │ │ ├── bordered-pulled.less │ │ ├── core.less │ │ ├── fixed-width.less │ │ ├── font-awesome.less │ │ ├── icons.less │ │ ├── larger.less │ │ ├── list.less │ │ ├── mixins.less │ │ ├── path.less │ │ ├── rotated-flipped.less │ │ ├── spinning.less │ │ ├── stacked.less │ │ └── variables.less │ └── scss │ │ ├── _bordered-pulled.scss │ │ ├── _core.scss │ │ ├── _fixed-width.scss │ │ ├── _icons.scss │ │ ├── _larger.scss │ │ ├── _list.scss │ │ ├── _mixins.scss │ │ ├── _path.scss │ │ ├── _rotated-flipped.scss │ │ ├── _spinning.scss │ │ ├── _stacked.scss │ │ ├── _variables.scss │ │ └── font-awesome.scss ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff └── js │ ├── bootstrap-datepicker.js │ ├── bootstrap.js │ ├── bootstrap.min.js │ ├── cookies.min.js │ ├── jquery-1.10.2.js │ ├── jquery.js │ ├── md5.js │ ├── plugins │ ├── dataTables │ │ ├── dataTables.bootstrap.js │ │ └── jquery.dataTables.js │ ├── flot │ │ ├── excanvas.min.js │ │ ├── jquery.flot.js │ │ ├── jquery.flot.pie.js │ │ ├── jquery.flot.resize.js │ │ └── jquery.flot.tooltip.min.js │ ├── metisMenu │ │ └── jquery.metisMenu.js │ └── morris │ │ ├── morris.js │ │ └── raphael-2.1.0.min.js │ ├── sb-admin.js │ ├── spika-chat-window.js │ ├── underscore.js │ └── webclient │ ├── alert-manager.js │ ├── chat-view.js │ ├── file-uploader.js │ ├── media-view.js │ ├── navigationbar.js │ ├── spika-api-client.js │ ├── spika-client-app.js │ ├── spika-client-utils.js │ ├── stickes-view.js │ └── window-manager.js └── index.php /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci 2 | 3 | coverage_clover: build/logs/clover.xml 4 | json_path: build/logs/coveralls-upload.json 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .vagrant/ 3 | idea/ 4 | vagrant/ 5 | logs/ 6 | uploads/ 7 | vendor/ 8 | build/ 9 | logs/ 10 | nottrackingfiles/ 11 | !logs/.gitkeep 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3 5 | - 5.4 6 | - 5.5 7 | 8 | services: 9 | - couchdb 10 | 11 | env: 12 | - SPIKA_COUCH_DB_URL=http://localhost:5984/spikatest SPIKA_ADMIN_EMAIL=admin@example.com 13 | 14 | before_script: 15 | - composer install --dev 16 | - curl -X PUT $SPIKA_COUCH_DB_URL 17 | - curl -X PUT $SPIKA_COUCH_DB_URL/_design/app --data-binary @install/designdocuments.dump 18 | 19 | script: vendor/bin/phpunit 20 | 21 | after_script: 22 | - vendor/bin/coveralls -v 23 | 24 | notifications: 25 | irc: "irc.freenode.org#spika_hackathon" 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 clover studio official account 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Spika-Server 2 | ============ 3 | 4 | # We've stopped matain this version of Spika. 5 | 6 | But we are developing new version of Spika right now. 7 | Please visit http://www.spikaapp.com and add your email address to our mailing list. 8 | We will launch new version in August 2015. 9 | 10 | ## About new version of Spika 11 | 12 | - Easy to setup backend. 13 | - Easy to integrate to your existing app/web. 14 | - Focused on only chat feature 15 | - Easy to customise 16 | 17 | If you are looking for messenger for companies or for any size of organisation, please visit https://www.spikaent.com -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | config.vm.box = "precise64" 9 | config.vm.box_url = "http://files.vagrantup.com/precise64.box" 10 | 11 | config.vm.network :forwarded_port, guest: 80, host: 8080 12 | config.vm.synced_folder "./", "/vagrant_data", :owner=> 'vagrant', :group=>'www-data', :mount_options => ['dmode=775','fmode=775'] 13 | 14 | config.vm.provision :shell, :inline => <<-EOS 15 | 16 | sudo apt-get update 17 | sudo DEBIAN_FRONTEND=noninteractive apt-get install -y php5 php5-curl phpunit curl git-core php5-xdebug postfix mysql-server php5-mysql php5-gd 18 | 19 | #http://www.giocc.com/installing-phpunit-on-ubuntu-11-04-natty-narwhal.html 20 | sudo pear upgrade pear 21 | sudo pear channel-discover pear.phpunit.de 22 | sudo pear channel-discover components.ez.no 23 | sudo pear channel-discover pear.symfony.com 24 | sudo pear install --alldeps phpunit/PHPUnit 25 | 26 | a2enmod rewrite 27 | sed -i '/AllowOverride None/c AllowOverride All' /etc/apache2/sites-available/default 28 | 29 | sudo rm -rf /var/www 30 | sudo ln -s /vagrant_data /var/www 31 | 32 | sudo /etc/init.d/apache2 restart 33 | sudo mkdir -p /vagrant_data/logs 34 | sudo mkdir -p /vagrant_data/uploads 35 | sudo chmod 777 /vagrant_data/logs 36 | sudo chmod 777 /vagrant_data/uploads 37 | sudo php /vagrant_data/composer.phar install -d /vagrant_data/ 38 | 39 | echo 'please open http://localhost:8080/wwwroot/installer to finish setup' 40 | 41 | EOS 42 | end 43 | -------------------------------------------------------------------------------- /Vagrantfile.backup: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | config.vm.box = "precise64" 9 | config.vm.box_url = "http://files.vagrantup.com/precise64.box" 10 | 11 | #comment this to disable Futon for couchdb on http://localhost:5984/_utils/ 12 | config.vm.network :forwarded_port, guest: 5984, host: 5984 13 | config.vm.network :forwarded_port, guest: 80, host: 8080 14 | 15 | config.vm.synced_folder "./", "/vagrant_data", :owner=> 'vagrant', :group=>'www-data', :mount_options => ['dmode=775','fmode=775'] 16 | 17 | config.vm.provision :shell, :inline => <<-EOS 18 | sudo apt-get update 19 | sudo DEBIAN_FRONTEND=noninteractive apt-get install -y php5 php5-curl phpunit curl git-core php5-xdebug postfix mysql-server php5-mysql php5-gd 20 | 21 | #http://www.giocc.com/installing-phpunit-on-ubuntu-11-04-natty-narwhal.html 22 | sudo pear upgrade pear 23 | sudo pear channel-discover pear.phpunit.de 24 | sudo pear channel-discover components.ez.no 25 | sudo pear channel-discover pear.symfony.com 26 | sudo pear install --alldeps phpunit/PHPUnit 27 | 28 | a2enmod rewrite 29 | sed -i '/AllowOverride None/c AllowOverride All' /etc/apache2/sites-available/default 30 | 31 | sudo rm -rf /var/www 32 | sudo ln -s /vagrant_data /var/www 33 | 34 | sudo /etc/init.d/apache2 restart 35 | sudo mkdir -p /vagrant_data/logs 36 | sudo mkdir -p /vagrant_data/uploads 37 | sudo chmod 777 /vagrant_data/logs 38 | sudo chmod 777 /vagrant_data/uploads 39 | sudo php /vagrant_data/composer.phar install -d /vagrant_data/ 40 | 41 | echo 'please open http://localhost:8080/wwwroot/installer to finish setup' 42 | 43 | EOS 44 | end 45 | -------------------------------------------------------------------------------- /Vagrantfile.digitalocean: -------------------------------------------------------------------------------- 1 | Vagrant.configure('2') do |config| 2 | config.vm.hostname = 'test002.foobar.com' # 好きなhostnameに変更 3 | 4 | config.vm.provider :digital_ocean do |provider, override| 5 | 6 | provider.client_id = '' 7 | provider.api_key = '' 8 | provider.ssh_key_name = '' 9 | 10 | override.ssh.private_key_path = '~/.ssh/id_rsa' 11 | override.vm.box = 'digital_ocean' 12 | override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box" 13 | 14 | provider.image = 'Ubuntu 12.04.3 x64' 15 | provider.region = 'San Francisco 1' 16 | provider.size = '512MB' 17 | provider.ca_path = '/usr/local/opt/curl-ca-bundle/share/ca-bundle.crt' 18 | end 19 | 20 | config.vm.provision :shell, :inline => <<-EOT 21 | sudo apt-get update 22 | sudo DEBIAN_FRONTEND=noninteractive apt-get install -y php5 php5-curl phpunit curl git-core php5-xdebug postfix mysql-server php5-mysql php5-gd 23 | 24 | #http://www.giocc.com/installing-phpunit-on-ubuntu-11-04-natty-narwhal.html 25 | sudo pear upgrade pear 26 | sudo pear channel-discover pear.phpunit.de 27 | sudo pear channel-discover components.ez.no 28 | sudo pear channel-discover pear.symfony.com 29 | sudo pear install --alldeps phpunit/PHPUnit 30 | 31 | a2enmod rewrite 32 | sed -i '/AllowOverride None/c AllowOverride All' /etc/apache2/sites-available/default 33 | 34 | sudo rm -rf /var/www 35 | sudo ln -s /vagrant /var/www 36 | 37 | sudo /etc/init.d/apache2 restart 38 | sudo mkdir -p /vagrant/logs 39 | sudo mkdir -p /vagrant/uploads 40 | sudo chmod -R 777 /vagrant/logs 41 | sudo chmod -R 777 /vagrant/uploads 42 | sudo php /vagrant/composer.phar install -d /vagrant/ 43 | 44 | echo 'please open http://[your_ip_address]/wwwroot/installer to finish setup' 45 | 46 | EOT 47 | 48 | end 49 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "silex/silex": "~1.1", 4 | "monolog/monolog": ">=1.0.0", 5 | "swiftmailer/swiftmailer": ">=4.1.2", 6 | "twig/twig": ">=1.8,<2.0-dev", 7 | "guzzle/guzzle": "~3.7", 8 | "doctrine/dbal": "2.2.*", 9 | "imagine/imagine": "~0.5.0" 10 | }, 11 | "require-dev": { 12 | "phpunit/phpunit": ">=3.7", 13 | "symfony/browser-kit": ">=2.3", 14 | "satooshi/php-coveralls": "dev-master", 15 | "squizlabs/php_codesniffer": ">=1.4" 16 | }, 17 | "autoload": { 18 | "psr-0": {"Spika\\": "src/"} 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /composer.phar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/composer.phar -------------------------------------------------------------------------------- /config/i18n/ja.ini: -------------------------------------------------------------------------------- 1 | [admin] 2 | adminSiteTitle = Spika管理画面 3 | labelLogin = ログイン 4 | formUsernamePlaceHolder = ユーザー名 5 | formPasswordPlaceHolder = パスワード 6 | labelRememberMe = 保存する 7 | btnLogin = ログインする -------------------------------------------------------------------------------- /config/init.php: -------------------------------------------------------------------------------- 1 | register(new MonologServiceProvider(), array( 36 | 'monolog.logfile' => __DIR__.'/../logs/debug.log', 37 | )); 38 | 39 | if(!ENABLE_LOGGING){ 40 | $app['monolog.handler'] = function () use ($app) { 41 | return new NullHandler(); 42 | }; 43 | } 44 | 45 | $app->register(new Silex\Provider\DoctrineServiceProvider(), array( 46 | 'db.options' => array ( 47 | 'driver' => 'pdo_mysql', 48 | 'host' => MySQL_HOST, 49 | 'dbname' => MySQL_DBNAME, 50 | 'user' => MySQL_USERNAME, 51 | 'password' => MySQL_PASSWORD, 52 | 'charset' => 'utf8' 53 | ) 54 | )); 55 | 56 | 57 | $app->register(new Spika\Provider\SpikaDbServiceProvider(), array( 58 | )); 59 | 60 | $app->register(new SwiftmailerServiceProvider()); 61 | $app->register(new Spika\Provider\TokenCheckerServiceProvider()); 62 | $app->register(new Silex\Provider\TwigServiceProvider(), array( 63 | 'twig.path' => __DIR__.'/../src/Spika/Views', 64 | )); 65 | 66 | $app->register(new Silex\Provider\SessionServiceProvider(), array( 67 | )); 68 | 69 | $app->register(new Spika\Provider\PushNotificationProvider(), array( 70 | 'pushnotification.options' => array ( 71 | 'GCMAPIKey' => GCM_API_KEY, 72 | 'APNProdPem' => __DIR__.'/../'.APN_PROD_CERT_PATH, 73 | 'APNDevPem' => __DIR__.'/../'.APN_DEV_CERT_PATH 74 | ) 75 | )); 76 | 77 | 78 | $app['beforeApiGeneral'] = $app->share(function () use ($app) { 79 | return new Spika\Middleware\APIGeneralBeforeHandler( 80 | $app['spikadb'], 81 | $app['logger'], 82 | $app 83 | ); 84 | }); 85 | 86 | $app['adminBeforeTokenChecker'] = $app->share(function () use ($app) { 87 | return new Spika\Middleware\AdminChecker( 88 | $app 89 | ); 90 | }); 91 | 92 | 93 | $app->mount('/api/', new Spika\Controller\ServerListController()); 94 | $app->mount('/api/', new Spika\Controller\SendPasswordController()); 95 | $app->mount('/api/', new Spika\Controller\ReportController()); 96 | $app->mount('/api/', new Spika\Controller\FileController()); 97 | $app->mount('/api/', new Spika\Controller\SearchUserController()); 98 | $app->mount('/api/', new Spika\Controller\SignoutController()); 99 | $app->mount('/api/', new Spika\Controller\CheckUniqueController()); 100 | $app->mount('/api/', new Spika\Controller\UserController()); 101 | $app->mount('/api/', new Spika\Controller\MessageController()); 102 | $app->mount('/api/', new Spika\Controller\GroupController()); 103 | $app->mount('/api/', new Spika\Controller\CheckUniqueController()); 104 | $app->mount('/api/', new Spika\Controller\AsyncTaskController()); 105 | $app->mount('/api/', new Spika\Controller\WebViewController()); 106 | $app->mount('/page/', new Spika\Controller\PasswordResetController()); 107 | $app->mount('/page/', new Spika\Controller\Web\StaticPageController()); 108 | 109 | $app->mount('/', new Spika\Controller\Web\Installer\InstallerController()); 110 | $app->mount('/admin', new Spika\Controller\Web\Admin\LoginController()); 111 | $app->mount('/admin/', new Spika\Controller\Web\Admin\GroupController()); 112 | $app->mount('/admin/', new Spika\Controller\Web\Admin\NewsController()); 113 | $app->mount('/admin/', new Spika\Controller\Web\Admin\UserController()); 114 | $app->mount('/admin/', new Spika\Controller\Web\Admin\GroupCategoryController()); 115 | $app->mount('/admin/', new Spika\Controller\Web\Admin\EmoticonController()); 116 | $app->mount('/admin/', new Spika\Controller\Web\Admin\ServerController()); 117 | 118 | $app->mount('/client/', new Spika\Controller\Web\Client\LoginController()); 119 | $app->mount('/client/', new Spika\Controller\Web\Client\MainController()); 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /etc/constants.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /files/apns-dev.pem: -------------------------------------------------------------------------------- 1 | Bag Attributes 2 | friendlyName: Apple Development IOS Push Services: com.clover-studio.spika 3 | localKeyID: C6 EF 71 93 F5 EC C5 BC E9 26 D5 14 F9 E7 5D F6 D5 D0 66 9D 4 | subject=/UID=com.clover-studio.spika/CN=Apple Development IOS Push Services: com.clover-studio.spika/OU=YU755VYJCP/C=HR 5 | issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority 6 | -----BEGIN CERTIFICATE----- 7 | MIIFkzCCBHugAwIBAgIIQ1toClOpxVMwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV 8 | BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js 9 | ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3 10 | aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw 11 | HhcNMTQwMTMxMTM0NDQwWhcNMTUwMTMxMTM0NDQwWjCBkjEnMCUGCgmSJomT8ixk 12 | AQEMF2NvbS5jbG92ZXItc3R1ZGlvLnNwaWthMUUwQwYDVQQDDDxBcHBsZSBEZXZl 13 | bG9wbWVudCBJT1MgUHVzaCBTZXJ2aWNlczogY29tLmNsb3Zlci1zdHVkaW8uc3Bp 14 | a2ExEzARBgNVBAsMCllVNzU1VllKQ1AxCzAJBgNVBAYTAkhSMIIBIjANBgkqhkiG 15 | 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwmnKMcF00WjAQ6JDuQcsf/hY5q7h+gIvtLcW 16 | A+f7qdT4L3TrikBiVxnYW6DVMM/+Ceh+enLaWckH/j+tR2klqKMLur4KVeD7kO9c 17 | g/En9siibIQ1/OF2DlczBujYpm+Z26oWc0MYcjzWrhq0mTh8hr24dRPMCRSMJd5l 18 | xMYSQzPO802DoJoGoHHFuRWGe3dqL5udF+zVaSkNZGeOf1nGlKR+9zODTtAWybn+ 19 | vmzjeO8xjPK6i1Fm0EEKXUJ4zZATc+1u8t33sHKWokvxZl/mAD3BMb7EMUEzr/rO 20 | UOSQC3I7fKxVHqc74eoHfVb9mBTjCDtkQR2aCplw1UWuXRJ/hwIDAQABo4IB5TCC 21 | AeEwHQYDVR0OBBYEFMbvcZP17MW86SbVFPnnXfbV0GadMAkGA1UdEwQCMAAwHwYD 22 | VR0jBBgwFoAUiCcXCam2GGCL7Ou69kdZxVJUo7cwggEPBgNVHSAEggEGMIIBAjCB 23 | /wYJKoZIhvdjZAUBMIHxMIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9uIHRo 24 | aXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5jZSBv 25 | ZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBjb25kaXRp 26 | b25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZpY2F0aW9u 27 | IHByYWN0aWNlIHN0YXRlbWVudHMuMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3LmFw 28 | cGxlLmNvbS9hcHBsZWNhLzBNBgNVHR8ERjBEMEKgQKA+hjxodHRwOi8vZGV2ZWxv 29 | cGVyLmFwcGxlLmNvbS9jZXJ0aWZpY2F0aW9uYXV0aG9yaXR5L3d3ZHJjYS5jcmww 30 | CwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMBAGCiqGSIb3Y2QGAwEE 31 | AgUAMA0GCSqGSIb3DQEBBQUAA4IBAQChBvp6jGU0H6bVw8llxFyQ4wOBcHu/nED+ 32 | FDxghhOIUYA47oksPXdADqLObm4DAEyw/vBatn8osVR8uBEYl+IJf8daX38LXSwE 33 | AEWD7aQBUPH8zWaBiLlai8wmGlT0M+CdEKYa4KgLtB3HG3/u6wuNQ/fOVyrxufvz 34 | jV8cTHzAQcYIHOuVZeV1TitR8EzkIxvcMBDxH1QPOPsMmW5JqI1fpcRH8LcSK2Ce 35 | tNun+DJTXXmIyEmjoxTCQC7nXwdRpTUEo6+dmKhxc2ZRcO1LMflixNHK1HE6pWP3 36 | ZMrEc9tTR52az90cS9lEoHj0I42lww/kZjdYWeluzRlxZ2ZH44SF 37 | -----END CERTIFICATE----- 38 | -----BEGIN RSA PRIVATE KEY----- 39 | MIIEpQIBAAKCAQEAwmnKMcF00WjAQ6JDuQcsf/hY5q7h+gIvtLcWA+f7qdT4L3Tr 40 | ikBiVxnYW6DVMM/+Ceh+enLaWckH/j+tR2klqKMLur4KVeD7kO9cg/En9siibIQ1 41 | /OF2DlczBujYpm+Z26oWc0MYcjzWrhq0mTh8hr24dRPMCRSMJd5lxMYSQzPO802D 42 | oJoGoHHFuRWGe3dqL5udF+zVaSkNZGeOf1nGlKR+9zODTtAWybn+vmzjeO8xjPK6 43 | i1Fm0EEKXUJ4zZATc+1u8t33sHKWokvxZl/mAD3BMb7EMUEzr/rOUOSQC3I7fKxV 44 | Hqc74eoHfVb9mBTjCDtkQR2aCplw1UWuXRJ/hwIDAQABAoIBAQCAqhzb0wmp8aaU 45 | 3FXvpZTI2KaVfRYnLL0/34+dZDGFE2JxnfKom7W5qWwsMAQH+w9IpWrXRR3HICm/ 46 | FYtrYGZA9i80FsOmVHCJWjCjTb3CMMR2BwXn55sHIKSvpPiFJgTwgN+8xqHuMN9v 47 | eFMfuGeJkRP7v+9f7w5VnZtCoEfD2uLNL8Zg+v6HyzlT2swn+P7tLYmi3l7k8XjA 48 | 1YdakWP/TkbvcnzTIczWLQnZCDD12K25kXlAQfXGLb6WgvWptrxDgGsgAp4yn0g0 49 | Xc64nmZ78AH/5yj3YVoyb3699oQaWnLwxKUyrsTd6jxBBH6x/tKRFO0P5Qn1GAyb 50 | HCFbOuGZAoGBAP+OnKevn4wiKhd41pW2qyHM5/3q63tb4q4IgIvZwTewn3MIPf+T 51 | +VcxNMqx+cZIyN9JLHm9jpiMYOdVN2I4QE9lk+ndP7Kr1X37/bwryV0gKqOhP8cu 52 | n6MSpFF/t3InxY2XchmSpA1m6pF4ahna5SlA8hprU/uSTdSndZlJCqOzAoGBAMLA 53 | DIq+tltuR8S7eR6K165AjFrdv9HucG2X8FW4lEaSXaZ+DrvDNGHtNQVERHNX9PUG 54 | WqHBn+Y+zWqJQMS89ffylM+A/oRapIEy7vHH5+Qm9tOAxv26J69j8Jztwm63UMjo 55 | rskKYvRr57cRHvdhAd+WztCoAL9NtdXZauQHMRrdAoGBAIEFQAPMv9Eg4n1NLZES 56 | Ux3SdIGWW+LAxhW1BykT+9+g1S9fRuXEkEq79forln3L+1X3fHPOBrLvlHDWbgqx 57 | eY5cKywT3nfXFwbu9PBObvAMMFrCKw/lcwUCgWEACN6iQ7OzdRCCHz8A6YYd8/sv 58 | ryh/uHssGo9VEuQ80ztbS/rPAoGAbaiB52X3fIgeNTJywrXfOCj0Xv3Z0rV17N/O 59 | 3hWuuAYWYXc9iJAj4LgWUL7d5Cy0q3tGcSp7hMP8Gm7qX10fCtw22piBt7jqRC2P 60 | yeiMNDWUagdrBNdbHTEi/NoLzxe9j0Mll+IXUhWoRbaIPzcKPQHHtknDEfUJ3D4u 61 | J/O8vKkCgYEA6nE9hpKZJ2xes1R9dOMW/IkqaQwGgpplXzl92Ds9PqlfwaoIMvF/ 62 | oC85+s5fHoOa8TdD/r5zo+0LgT06noaO0tXS5UlVzwrl15qXk6zi1SdyquLMj0dt 63 | fxEcz9CetSyQjo3Cdj7kZ7Um2TRYBqcPil8AaQ5FpRau2eU1nTckt50= 64 | -----END RSA PRIVATE KEY----- 65 | -------------------------------------------------------------------------------- /files/apns-prod.pem: -------------------------------------------------------------------------------- 1 | Bag Attributes 2 | friendlyName: Apple Production IOS Push Services: com.clover-studio.spika 3 | localKeyID: BA D6 66 45 F3 27 48 FD 66 B8 C7 BF 6F AB 1E 88 41 6A 63 1A 4 | subject=/UID=com.clover-studio.spika/CN=Apple Production IOS Push Services: com.clover-studio.spika/OU=YU755VYJCP/C=HR 5 | issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority 6 | -----BEGIN CERTIFICATE----- 7 | MIIFkjCCBHqgAwIBAgIIKjFIeqKDBMowDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV 8 | BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js 9 | ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3 10 | aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw 11 | HhcNMTQwMTMxMTM0NTUwWhcNMTUwMTMxMTM0NTUwWjCBkTEnMCUGCgmSJomT8ixk 12 | AQEMF2NvbS5jbG92ZXItc3R1ZGlvLnNwaWthMUQwQgYDVQQDDDtBcHBsZSBQcm9k 13 | dWN0aW9uIElPUyBQdXNoIFNlcnZpY2VzOiBjb20uY2xvdmVyLXN0dWRpby5zcGlr 14 | YTETMBEGA1UECwwKWVU3NTVWWUpDUDELMAkGA1UEBhMCSFIwggEiMA0GCSqGSIb3 15 | DQEBAQUAA4IBDwAwggEKAoIBAQDkPto4o4FC+92zreNUsmg1jrQSeUhwdrku324t 16 | KFwPmrQonKrhbr35xX3bkoMyMlaeJj8K5Lm5eONHQ55IcsY5YE8NGEr2pxl6vhI9 17 | U8w+cR69YPdzwnZRNAi+Q0ukSMXEc/xJSW2KFIAEjucAHBmCw5STu46kTEnhiP/x 18 | A5GFrnyA4X3AS1z7791x21N59MWR0QC6OFupLbRMyLnpitpl4MHCmQmh/Y1jk2sd 19 | cQsqW4z7VwKah1H4NhdgSISv4rz6ghEs7zCfaEQGxnDj5EKt49/5ex2+WYGB2c/b 20 | /AHVs6RmSzz6EkGSXUcOjRGA08Qhz+TI1VgbHz+DwvJPRy/nAgMBAAGjggHlMIIB 21 | 4TAdBgNVHQ4EFgQUutZmRfMnSP1muMe/b6seiEFqYxowCQYDVR0TBAIwADAfBgNV 22 | HSMEGDAWgBSIJxcJqbYYYIvs67r2R1nFUlSjtzCCAQ8GA1UdIASCAQYwggECMIH/ 23 | BgkqhkiG92NkBQEwgfEwgcMGCCsGAQUFBwICMIG2DIGzUmVsaWFuY2Ugb24gdGhp 24 | cyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRhbmNlIG9m 25 | IHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlv 26 | bnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRpZmljYXRpb24g 27 | cHJhY3RpY2Ugc3RhdGVtZW50cy4wKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cuYXBw 28 | bGUuY29tL2FwcGxlY2EvME0GA1UdHwRGMEQwQqBAoD6GPGh0dHA6Ly9kZXZlbG9w 29 | ZXIuYXBwbGUuY29tL2NlcnRpZmljYXRpb25hdXRob3JpdHkvd3dkcmNhLmNybDAL 30 | BgNVHQ8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwIwEAYKKoZIhvdjZAYDAgQC 31 | BQAwDQYJKoZIhvcNAQEFBQADggEBAIuviAoxXx8Oya68Rwx4nuVNRa6XUlXZmLso 32 | vI2jAH6EWpWW7T3y0Z2HmMCVZzAQ8jlHpdkeXmGHbvfM0IWJ53Z5kyM2IXA2rd0X 33 | ZGHuB+oBvPQtu4aL+CVXGy0R0Cps6NQkw4rXlvN0aXpDwDmPp15pWlktrwBWD/Bd 34 | HCbucmuDqckxw4MVtQrvHL7QQf2wpN2q97zeZghs/y/v9dLDM17HIdcUrYxcrf80 35 | GQ/cLNhQksXUP10d6l84ya4CR347WZHj640Yhy9+uDfaKepLI2Z7vHgeKutrNuB+ 36 | Nq1zs/HDNu6XinRFa5ImYDy048Bd0p6p6bTSHVli4VHaxwmf5+Q= 37 | -----END CERTIFICATE----- 38 | -----BEGIN RSA PRIVATE KEY----- 39 | MIIEogIBAAKCAQEA5D7aOKOBQvvds63jVLJoNY60EnlIcHa5Lt9uLShcD5q0KJyq 40 | 4W69+cV925KDMjJWniY/CuS5uXjjR0OeSHLGOWBPDRhK9qcZer4SPVPMPnEevWD3 41 | c8J2UTQIvkNLpEjFxHP8SUltihSABI7nABwZgsOUk7uOpExJ4Yj/8QORha58gOF9 42 | wEtc++/dcdtTefTFkdEAujhbqS20TMi56YraZeDBwpkJof2NY5NrHXELKluM+1cC 43 | modR+DYXYEiEr+K8+oIRLO8wn2hEBsZw4+RCrePf+XsdvlmBgdnP2/wB1bOkZks8 44 | +hJBkl1HDo0RgNPEIc/kyNVYGx8/g8LyT0cv5wIDAQABAoIBAGGnoqZpDn0iVhDy 45 | bTlnu75ueA0PZzb3FPRBFFqt0fW7MynNHi+luhKLtPWlEg0ADJ9NrdtzUSNR3aw3 46 | +hj1Qmp6Elh/9FLj27rwZ81ldRWiQIy2WClnIkhMAxGkqVB48mTDW0Xf7MYPT1aj 47 | 7aHWY/PWylMLBFS3b0TX4Om1pSWUW0MD3NzSWV2QjetZ53LYRHEqpCDIVGCkdHYK 48 | GlOGd3F6ifwi/qVJx7mopWhRGEO2qlV0OisLlGfwkWt8Hxi0PAUKsBTtTm7oOR4r 49 | Ue6mDaInVoR/zDoSI6swfdAT/tKEPbr59O9rpNfHOiXo44gywx9THLIjN8QuYhrp 50 | 9q9CAIECgYEA9QIIDjsT8znOVkEz58e3oPLrIbCQ5T3wWvMWRb86ZXbe/0tC0c7A 51 | DXURLOu/Kx4jN5M9c3uZVHSc3e+bP7Df8SchBCEzSvKYEddRlymATJ1XbMaFIasu 52 | Ym+hzezES2phpms2qD5drOGfsQAXkibAWNjhyY7nomwcoJ4/tdlA6N8CgYEA7nxN 53 | DoTbxC5Ikmb/CpWu8Y2+BFRCQdKCLYEmp5smzDcT6iNevPjHNGDiOV1isjVsbYt2 54 | r8aS1935jL12d5FZhdfYpCqBzQXJVIc1TlpFnHHKYWppmRczUoPBdPcEKEzDIGOZ 55 | 8zuEe4itpWuzkSnQHstknHTfFalnNdr1PBWuMfkCgYAIGewYRF3RggzPj1JfDJyG 56 | xuF9eLAh1F15NGZ9IeiVaEvRVzS7aUGycDeEK7tjepihgs3aXrDgOQbi08RnY7rT 57 | 535Q+6QNi1354QvCms2yOtWkNCA8z8M14AkSnQyUjczyysLA52cDi2ZTXPRqkbt0 58 | dJ9qob4JAdgke3cR1UAvMwKBgEmwSrcDwkwZ6P6jqIaCva2RmHcJ+fcQrnyU/Xao 59 | cBKFqjecejd1v0el8AC9pDNgYoJup1ukxdbBlcww9pv3Y2wBx8TiBX1uHklqBcSS 60 | DBRM7LWxBbPyAT+rymjzsmspXNlzLSyE5WiuUMleP/vIqa/6NLpLOmsdDvELGN9Z 61 | 65sxAoGAWSrx/H5JSoNmJn2ZMg0buaKxLd3XtPWzgb5kz5yl67KuzCkgVMx5PtBc 62 | aOUooPHJtJdGBZU20eGQDmVobTzJC6GW+DXSkBFUb5baOTn00Q6sOV4VZ2MM6ikP 63 | imG0+tqhKJTWtU7+PawBf8Oznj0u4KeJmHxGycjPsMZvlqhzgwY= 64 | -----END RSA PRIVATE KEY----- 65 | -------------------------------------------------------------------------------- /install/INSTALL: -------------------------------------------------------------------------------- 1 | git clone https://github.com/cloverstudio/Spika-Server.git 2 | # generate database in couchdb ex) spikademo 3 | # chenge init.php 4 | 5 | # run this commands 6 | git checkout develop 7 | cd Spika-Server 8 | cd install 9 | curl -X POST http://localhost:5984/spikademo -d@designdocuments.dump -H "Content-Type: application/json" 10 | cd .. 11 | php composer.phar install 12 | mkdir logs 13 | chmod 777 logs 14 | mkdir uploads 15 | chmod 777 uploads 16 | 17 | # open http://"docroot"/Spika-Server/wwwroot/install in browser -------------------------------------------------------------------------------- /install/alterTable.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE `message` ADD `delete_at` INT NOT NULL DEFAULT '0' AFTER `modified`, ADD `delete_flagged_at` INT NOT NULL DEFAULT '0' AFTER `delete_at`, ADD `delete_after_shown` BOOLEAN NOT NULL DEFAULT FALSE AFTER `delete_flagged_at`; -------------------------------------------------------------------------------- /install/resouces/categoryimages/cat_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/categoryimages/cat_1.png -------------------------------------------------------------------------------- /install/resouces/categoryimages/cat_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/categoryimages/cat_2.png -------------------------------------------------------------------------------- /install/resouces/categoryimages/cat_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/categoryimages/cat_3.png -------------------------------------------------------------------------------- /install/resouces/categoryimages/cat_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/categoryimages/cat_4.png -------------------------------------------------------------------------------- /install/resouces/categoryimages/cat_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/categoryimages/cat_5.png -------------------------------------------------------------------------------- /install/resouces/emoticons/adore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/adore.png -------------------------------------------------------------------------------- /install/resouces/emoticons/after_boom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/after_boom.png -------------------------------------------------------------------------------- /install/resouces/emoticons/ah.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/ah.png -------------------------------------------------------------------------------- /install/resouces/emoticons/amazed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/amazed.png -------------------------------------------------------------------------------- /install/resouces/emoticons/angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/angry.png -------------------------------------------------------------------------------- /install/resouces/emoticons/bad_smelly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/bad_smelly.png -------------------------------------------------------------------------------- /install/resouces/emoticons/baffle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/baffle.png -------------------------------------------------------------------------------- /install/resouces/emoticons/beat_brick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/beat_brick.png -------------------------------------------------------------------------------- /install/resouces/emoticons/beat_plaster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/beat_plaster.png -------------------------------------------------------------------------------- /install/resouces/emoticons/beat_shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/beat_shot.png -------------------------------------------------------------------------------- /install/resouces/emoticons/beated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/beated.png -------------------------------------------------------------------------------- /install/resouces/emoticons/beauty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/beauty.png -------------------------------------------------------------------------------- /install/resouces/emoticons/big_smile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/big_smile.png -------------------------------------------------------------------------------- /install/resouces/emoticons/boss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/boss.png -------------------------------------------------------------------------------- /install/resouces/emoticons/burn_joss_stick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/burn_joss_stick.png -------------------------------------------------------------------------------- /install/resouces/emoticons/byebye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/byebye.png -------------------------------------------------------------------------------- /install/resouces/emoticons/canny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/canny.png -------------------------------------------------------------------------------- /install/resouces/emoticons/choler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/choler.png -------------------------------------------------------------------------------- /install/resouces/emoticons/cold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/cold.png -------------------------------------------------------------------------------- /install/resouces/emoticons/confident.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/confident.png -------------------------------------------------------------------------------- /install/resouces/emoticons/confuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/confuse.png -------------------------------------------------------------------------------- /install/resouces/emoticons/cool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/cool.png -------------------------------------------------------------------------------- /install/resouces/emoticons/cry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/cry.png -------------------------------------------------------------------------------- /install/resouces/emoticons/doubt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/doubt.png -------------------------------------------------------------------------------- /install/resouces/emoticons/dribble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/dribble.png -------------------------------------------------------------------------------- /install/resouces/emoticons/embarrassed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/embarrassed.png -------------------------------------------------------------------------------- /install/resouces/emoticons/extreme_sexy_girl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/extreme_sexy_girl.png -------------------------------------------------------------------------------- /install/resouces/emoticons/feel_good.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/feel_good.png -------------------------------------------------------------------------------- /install/resouces/emoticons/go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/go.png -------------------------------------------------------------------------------- /install/resouces/emoticons/haha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/haha.png -------------------------------------------------------------------------------- /install/resouces/emoticons/hell_boy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/hell_boy.png -------------------------------------------------------------------------------- /install/resouces/emoticons/hungry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/hungry.png -------------------------------------------------------------------------------- /install/resouces/emoticons/look_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/look_down.png -------------------------------------------------------------------------------- /install/resouces/emoticons/matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/matrix.png -------------------------------------------------------------------------------- /install/resouces/emoticons/misdoubt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/misdoubt.png -------------------------------------------------------------------------------- /install/resouces/emoticons/nosebleed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/nosebleed.png -------------------------------------------------------------------------------- /install/resouces/emoticons/oh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/oh.png -------------------------------------------------------------------------------- /install/resouces/emoticons/ops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/ops.png -------------------------------------------------------------------------------- /install/resouces/emoticons/pudency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/pudency.png -------------------------------------------------------------------------------- /install/resouces/emoticons/rap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/rap.png -------------------------------------------------------------------------------- /install/resouces/emoticons/sad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/sad.png -------------------------------------------------------------------------------- /install/resouces/emoticons/sexy_girl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/sexy_girl.png -------------------------------------------------------------------------------- /install/resouces/emoticons/shame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/shame.png -------------------------------------------------------------------------------- /install/resouces/emoticons/smile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/smile.png -------------------------------------------------------------------------------- /install/resouces/emoticons/spiderman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/spiderman.png -------------------------------------------------------------------------------- /install/resouces/emoticons/still_dreaming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/still_dreaming.png -------------------------------------------------------------------------------- /install/resouces/emoticons/sure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/sure.png -------------------------------------------------------------------------------- /install/resouces/emoticons/surrender.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/surrender.png -------------------------------------------------------------------------------- /install/resouces/emoticons/sweat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/sweat.png -------------------------------------------------------------------------------- /install/resouces/emoticons/sweet_kiss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/sweet_kiss.png -------------------------------------------------------------------------------- /install/resouces/emoticons/tire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/tire.png -------------------------------------------------------------------------------- /install/resouces/emoticons/too_sad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/too_sad.png -------------------------------------------------------------------------------- /install/resouces/emoticons/waaaht.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/waaaht.png -------------------------------------------------------------------------------- /install/resouces/emoticons/what.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/install/resouces/emoticons/what.png -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | ./tests/Spika/ 17 | 18 | 19 | 20 | 21 | ./ 22 | ./vendor/phpunit/phpunit/ 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ./vendor 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/Spika/Controller/CheckUniqueController.php: -------------------------------------------------------------------------------- 1 | get('/checkUnique', function (Request $request) use ($app) { 28 | 29 | $email = $request->get('email'); 30 | $username = $request->get('username'); 31 | $groupname = $request->get('groupname'); 32 | 33 | if(!empty($email)){ 34 | 35 | $result = $app['spikadb']->checkEmailIsUnique($email); 36 | if(count($result) == 0 || $result == false){ 37 | return "[]"; 38 | }else{ 39 | return json_encode($result); 40 | } 41 | } 42 | 43 | if(!empty($username)){ 44 | $result = $app['spikadb']->checkUserNameIsUnique($email); 45 | if(count($result) == 0 || $result == false){ 46 | return "[]"; 47 | }else{ 48 | return json_encode($result); 49 | } 50 | } 51 | 52 | if(!empty($groupname)){ 53 | $result = $app['spikadb']->checkGroupNameIsUnique($email); 54 | if(count($result) == 0 || $result == false){ 55 | return "[]"; 56 | }else{ 57 | return json_encode($result); 58 | } 59 | } 60 | 61 | return ''; 62 | 63 | })->before($app['beforeApiGeneral']); 64 | 65 | return $controllers; 66 | } 67 | 68 | } 69 | 70 | ?> 71 | -------------------------------------------------------------------------------- /src/Spika/Controller/FileController.php: -------------------------------------------------------------------------------- 1 | get('/filedownloader', function (Request $request) use ($app,$self) { 36 | 37 | $fileID = $request->get('file'); 38 | $filePath = __DIR__.'/../../../'.FileController::$fileDirName."/".basename($fileID); 39 | 40 | $app['logger']->addDebug($filePath); 41 | 42 | if(file_exists($filePath)){ 43 | 44 | $response = new Response(); 45 | $lastModified = new \DateTime(); 46 | $file = new \SplFileInfo($filePath); 47 | 48 | $lastModified = new \DateTime(); 49 | $lastModified->setTimestamp($file->getMTime()); 50 | $response->setLastModified($lastModified); 51 | 52 | if ($response->isNotModified($request)) { 53 | $response->prepare($request)->send(); 54 | return $response; 55 | } 56 | 57 | $response = $app->sendFile($filePath); 58 | $currentDate = new \DateTime(null, new \DateTimeZone('UTC')); 59 | $response->setDate($currentDate)->prepare($request)->send(); 60 | 61 | return $response; 62 | 63 | }else{ 64 | return $self->returnErrorResponse("file doesn't exists."); 65 | } 66 | }); 67 | 68 | //})->before($app['beforeTokenChecker']); 69 | 70 | // ToDo: Add token check 71 | $controllers->post('/fileuploader', function (Request $request) use ($app,$self) { 72 | 73 | $file = $request->files->get(FileController::$paramName); 74 | $fineName = \Spika\Utils::randString(20, 20) . time(); 75 | 76 | if(!is_writable(__DIR__.'/../../../'.FileController::$fileDirName)) 77 | return $self->returnErrorResponse(FileController::$fileDirName ." dir is not writable."); 78 | 79 | $file->move(__DIR__.'/../../../'.FileController::$fileDirName, $fineName); 80 | return $fineName; 81 | 82 | })->before($app['beforeApiGeneral']); 83 | 84 | //})->before($app['beforeTokenChecker']); 85 | 86 | return $controllers; 87 | } 88 | 89 | } 90 | 91 | ?> 92 | -------------------------------------------------------------------------------- /src/Spika/Controller/GeneralAPIHandlerController.php: -------------------------------------------------------------------------------- 1 | app = $app; 28 | 29 | $controllers = $app['controllers_factory']; 30 | $self = $this; 31 | 32 | $controllers->post('/', function (Request $request) use ($app,$self) { 33 | 34 | $requestBody = $request->getContent(); 35 | 36 | // convert created and modified fields automatically to be server time 37 | $requestBody = preg_replace("/,\"created\":[0-9]*?}/", ",\"created\":" . time() . "}", $requestBody); 38 | $requestBody = preg_replace("/,\"created\":[0-9]*?,/", ",\"created\":" . time() . ",", $requestBody); 39 | $requestBody = preg_replace("/,\"modified\":[0-9]*?}/", ",\"modified\":" . time() . "}", $requestBody); 40 | $requestBody = preg_replace("/,\"modified\":[0-9]*?,/", ",\"modified\":" . time() . ",", $requestBody); 41 | 42 | $requestBodyAry = json_decode($requestBody,true); 43 | 44 | if($requestBodyAry['type'] == 'message'){ 45 | 46 | $self->handleNewMessage($requestBody); 47 | return $app['spikadb']->doPostRequest($requestBody); 48 | 49 | }else{ 50 | return $app['spikadb']->doPostRequest($requestBody); 51 | } 52 | 53 | })->before($app['beforeTokenChecker']); 54 | 55 | $controllers->get('/{args}', function (Request $request,$args) use ($app){ 56 | 57 | $couchDBQuery = $args . "?" . $request->getQueryString(); 58 | 59 | list($header,$body) = $app['spikadb']->doGetRequestGetHeader($couchDBQuery,true); 60 | 61 | $additionalHeader = array(); 62 | 63 | 64 | 65 | $headers = explode("\n",$header); 66 | foreach($headers as $row){ 67 | 68 | if(preg_match("/Content-Type/", $row)){ 69 | 70 | $tmp = explode(":",$row); 71 | 72 | $key = trim($tmp[0]); 73 | $value = trim($tmp[1]); 74 | 75 | $additionalHeader[$key] = $value; 76 | } 77 | 78 | } 79 | 80 | 81 | return new Response($body, 200, $additionalHeader); 82 | 83 | }) 84 | ->before($app['beforeTokenChecker']) 85 | ->assert('args', '.*') 86 | ->convert('args', function ($args) { 87 | return $args; 88 | }); 89 | 90 | $controllers->put('/{id}', function (Request $request,$id) use ($app) { 91 | 92 | $requestBody = $request->getContent(); 93 | return $app['spikadb']->doPutRequest($id,$requestBody); 94 | 95 | })->before($app['beforeTokenChecker']); 96 | 97 | $controllers->delete('/{id}', function (Request $request,$id) use ($app) { 98 | 99 | return $app['spikadb']->doDeleteRequest($id); 100 | 101 | })->before($app['beforeTokenChecker']); 102 | 103 | 104 | return $controllers; 105 | } 106 | 107 | // this function is kicked when someone post new message to a user or a group. 108 | public function handleNewMessage($requestBody) 109 | { 110 | $logger = $this->app['logger']; 111 | $requestBodyAry = json_decode($requestBody,true); 112 | 113 | $targetType = $requestBodyAry['message_target_type']; 114 | 115 | if ($targetType == 'user') { 116 | 117 | $fromUser = $requestBodyAry['from_user_id']; 118 | $toUser = $requestBodyAry['to_user_id']; 119 | $message = $requestBodyAry['body']; 120 | 121 | // add to activity summary 122 | $this->updateActivitySummary($toUser, $fromUser, "direct_messages"); 123 | 124 | } 125 | 126 | 127 | 128 | return $this->app['spikadb']->doPostRequest($requestBody); 129 | } 130 | 131 | 132 | 133 | } 134 | 135 | ?> 136 | -------------------------------------------------------------------------------- /src/Spika/Controller/PasswordResetController.php: -------------------------------------------------------------------------------- 1 | get('/resetPassword/{resetCode}', function (Request $request,$resetCode) use ($app,$self) { 19 | 20 | if(!$self->checkResetCode($app,$resetCode)){ 21 | return $app['twig']->render('passwordReset/passwordResetError.twig', array( 22 | 'ROOT_URL' => ROOT_URL, 23 | )); 24 | } 25 | 26 | return $app['twig']->render('passwordReset/passwordReset.twig', array( 27 | 'ROOT_URL' => ROOT_URL, 28 | 'resetCode' => $resetCode, 29 | )); 30 | 31 | }); 32 | 33 | // check unique controller 34 | $controllers->post('/resetPassword', function (Request $request) use ($app,$self) { 35 | 36 | $resetCode = $request->get('resetCode'); 37 | if(!$self->checkResetCode($app,$resetCode)){ 38 | return $app['twig']->render('passwordReset/passwordResetError.twig', array( 39 | 'ROOT_URL' => ROOT_URL, 40 | )); 41 | } 42 | 43 | 44 | $newPassword = $request->get('password'); 45 | $newPasswordConfirm = $request->get('confirm'); 46 | $errorMessage = ""; 47 | $Message = ""; 48 | 49 | if(!preg_match("/[a-zA-Z0-9_-]{6}/",$newPassword)){ 50 | $errorMessage = "Password should be alphanumeric and at least 6 characters."; 51 | } 52 | 53 | if($newPassword != $newPasswordConfirm){ 54 | $errorMessage = "Passwords is not same.Plase try again."; 55 | } 56 | 57 | if(strlen($errorMessage) > 0){ 58 | return $app['twig']->render('passwordReset/passwordReset.twig', array( 59 | 'ROOT_URL' => ROOT_URL, 60 | 'error' => $errorMessage, 61 | 'resetCode' => $resetCode 62 | )); 63 | }else{ 64 | 65 | // change password 66 | $resetData = $app['spikadb']->getPassworResetRequest($resetCode); 67 | $app['spikadb']->changePassword($resetData['user_id'],md5($newPassword)); 68 | return $app['twig']->render('passwordReset/passwordResetSucceed.twig', array( 69 | 'ROOT_URL' => ROOT_URL 70 | )); 71 | } 72 | 73 | })->before($app['beforeApiGeneral']); 74 | 75 | 76 | return $controllers; 77 | 78 | } 79 | 80 | function checkResetCode($app,$resetCode){ 81 | 82 | $resetData = $app['spikadb']->getPassworResetRequest($resetCode); 83 | 84 | if(count($resetData) == 0 || isset($resetData['error'])){ 85 | return false; 86 | } 87 | 88 | $requestReceivedTimeStamp = $resetData['created']; 89 | $interval = time() - $requestReceivedTimeStamp; 90 | 91 | if($interval > PW_RESET_CODE_VALID_TIME || $resetData['valid'] == 0){ 92 | return false; 93 | } 94 | 95 | return true; 96 | } 97 | } 98 | 99 | ?> 100 | -------------------------------------------------------------------------------- /src/Spika/Controller/ReportController.php: -------------------------------------------------------------------------------- 1 | get('/reportViolation.php', function (Request $request) use ($app) { 27 | $documentId = $request->get('docment_id'); 28 | 29 | 30 | if(SEND_EMAIL_METHOD == EMAIL_METHOD_LOCALSMTP){ 31 | 32 | $message = \Swift_Message::newInstance() 33 | ->setSubject("SpilaViolationReport") 34 | ->setFrom(AdministratorEmail) 35 | ->setTo(AdministratorEmail) 36 | ->setBody($documentId); 37 | 38 | $app['mailer']->send($message); 39 | 40 | } 41 | 42 | if(SEND_EMAIL_METHOD == EMAIL_METHOD_GMAIL){ 43 | 44 | $transport = \Swift_SmtpTransport::newInstance('smtp.googlemail.com', 465, 'ssl') 45 | ->setUsername(GMAIL_USER) 46 | ->setPassword(GMAIL_PASSWORD); 47 | 48 | $message = \Swift_Message::newInstance($transport) 49 | ->setSubject("Spika Reset Password") 50 | ->setFrom(AdministratorEmail) 51 | ->setTo(AdministratorEmail) 52 | ->setBody($documentId); 53 | 54 | $mailer->send($message); 55 | 56 | } 57 | 58 | return 'OK'; 59 | })->before($app['beforeApiGeneral'])->before($app['beforeTokenChecker']); 60 | 61 | return $controllers; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Spika/Controller/SearchUserController.php: -------------------------------------------------------------------------------- 1 | app = $app; 29 | $self = $this; 30 | 31 | $controllers->get('/searchUsers', function (Request $request) use ($app,$self) { 32 | $searchResult = $self->app['spikadb']->searchUser($request->get('n'),$request->get('af'),$request->get('at'),$request->get('g')); 33 | return json_encode($searchResult); 34 | })->before($app['beforeApiGeneral']); 35 | 36 | return $controllers; 37 | } 38 | 39 | } 40 | 41 | ?> 42 | -------------------------------------------------------------------------------- /src/Spika/Controller/SendPasswordController.php: -------------------------------------------------------------------------------- 1 | get('/resetPassword', function (Request $request) use ($app,$self) { 28 | 29 | $email = $request->get('email'); 30 | 31 | $user = $app['spikadb']->findUserByEmail($email); 32 | 33 | if (isset($user['_id'])) { 34 | 35 | $user = $app['spikadb']->findUserById($user['_id'],false); 36 | 37 | $resetCode = $app['spikadb']->addPassworResetRequest($user['_id']); 38 | 39 | $resetPasswordUrl = ROOT_URL . "/page/resetPassword/" . $resetCode; 40 | 41 | $body = "Please reset password here {$resetPasswordUrl}"; 42 | 43 | try{ 44 | 45 | if(SEND_EMAIL_METHOD == EMAIL_METHOD_LOCALSMTP){ 46 | 47 | $message = \Swift_Message::newInstance() 48 | ->setSubject("Spika Reset Password") 49 | ->setFrom(AdministratorEmail) 50 | ->setTo($user['email']) 51 | ->setBody($body); 52 | 53 | $mailer = \Swift_Mailer::newInstance(); 54 | 55 | $mailer->send($message); 56 | 57 | } 58 | 59 | if(SEND_EMAIL_METHOD == EMAIL_METHOD_GMAIL){ 60 | 61 | $transport = \Swift_SmtpTransport::newInstance('smtp.googlemail.com', 465, 'ssl') 62 | ->setUsername(GMAIL_USER) 63 | ->setPassword(GMAIL_PASSWORD); 64 | 65 | $message = \Swift_Message::newInstance() 66 | ->setSubject("Spika Reset Password") 67 | ->setFrom(AdministratorEmail) 68 | ->setTo($user['email']) 69 | ->setBody($body); 70 | 71 | $mailer = \Swift_Mailer::newInstance($transport); 72 | 73 | $mailer->send($message); 74 | 75 | } 76 | 77 | 78 | } catch(\Exception $e){ 79 | 80 | } 81 | 82 | return 'OK'; 83 | 84 | }else{ 85 | 86 | return $self->returnErrorResponse("invalid email"); 87 | 88 | } 89 | 90 | return 'OK'; 91 | 92 | })->before($app['beforeApiGeneral']); 93 | 94 | return $controllers; 95 | } 96 | 97 | } 98 | 99 | ?> 100 | -------------------------------------------------------------------------------- /src/Spika/Controller/ServerListController.php: -------------------------------------------------------------------------------- 1 | get('/servers', function (Request $request) use ($app,$self) { 27 | 28 | $serverList = $app['spikadb']->findAllServersWitoutId(); 29 | return json_encode($serverList); 30 | 31 | })->before($app['beforeApiGeneral']);; 32 | 33 | return $controllers; 34 | } 35 | 36 | 37 | } 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/Spika/Controller/SignoutController.php: -------------------------------------------------------------------------------- 1 | get('/unregistToken', function (Request $request) use ($app) { 28 | 29 | $userId = $request->get('user_id'); 30 | return $app['spikadb']->unregistToken($userId); 31 | 32 | })->before($app['beforeApiGeneral']); 33 | 34 | return $controllers; 35 | 36 | } 37 | 38 | } 39 | 40 | ?> 41 | -------------------------------------------------------------------------------- /src/Spika/Controller/SpikaBaseController.php: -------------------------------------------------------------------------------- 1 | app = $app; 29 | $controllers = $app['controllers_factory']; 30 | 31 | return $controllers; 32 | } 33 | 34 | 35 | public function validateRequestParams($requestBody,$requiredParams){ 36 | $requestParams = json_decode($requestBody,true); 37 | 38 | if(!is_array($requestParams)) 39 | return false; 40 | 41 | foreach($requiredParams as $param){ 42 | if(!isset($requestParams[$param])) 43 | return false; 44 | } 45 | 46 | return true; 47 | } 48 | 49 | public function returnErrorResponse($errorMessage,$httpCode = 500){ 50 | $arr = array('message' => $errorMessage, 'error' => 'error'); 51 | $json = json_encode($arr); 52 | return new Response($json, $httpCode); 53 | } 54 | 55 | public function doAsyncRequest($app,$request,$apiName,$params = null){ 56 | 57 | $client = new Client(); 58 | $client->addSubscriber(new AsyncPlugin()); 59 | 60 | $requestURL = LOCAL_ROOT_URL . "/api/{$apiName}"; 61 | 62 | $app['monolog']->addDebug($requestURL); 63 | 64 | 65 | $request = $client->post($requestURL,array(),array('timeout'=>0,'connect_timeout'=>0)); 66 | 67 | $json = json_encode($params); 68 | $request->setBody($json,'application/json'); 69 | 70 | $request->send(); 71 | 72 | } 73 | 74 | } 75 | 76 | ?> 77 | -------------------------------------------------------------------------------- /src/Spika/Controller/Web/Client/MainController.php: -------------------------------------------------------------------------------- 1 | get('/main', function (Request $request) use ($app,$self) { 37 | 38 | if(!$self->checkLogin()){ 39 | return $app->redirect(ROOT_URL . '/client/login'); 40 | } 41 | 42 | $self->setVariables(); 43 | 44 | return $self->render('client/main.twig', array( 45 | 'ROOT_URL' => ROOT_URL, 46 | )); 47 | }); 48 | 49 | 50 | $controllers->get('/user/{userId}', function (Request $request,$userId) use ($app,$self) { 51 | 52 | if(!$self->checkLogin()){ 53 | return $app->redirect(ROOT_URL . '/client/login'); 54 | } 55 | 56 | $self->setVariables(); 57 | 58 | return $self->render('client/main.twig', array( 59 | 'ROOT_URL' => ROOT_URL, 60 | 'targetUserId' => $userId 61 | )); 62 | }); 63 | 64 | 65 | $controllers->get('/group/{groupId}', function (Request $request,$groupId) use ($app,$self) { 66 | 67 | if(!$self->checkLogin()){ 68 | return $app->redirect(ROOT_URL . '/client/login'); 69 | } 70 | 71 | $self->setVariables(); 72 | 73 | return $self->render('client/main.twig', array( 74 | 'ROOT_URL' => ROOT_URL, 75 | 'targetGroupId' => $groupId 76 | )); 77 | }); 78 | 79 | return $controllers; 80 | 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/Spika/Controller/Web/StaticPageController.php: -------------------------------------------------------------------------------- 1 | get('/eula/{language}', function (Request $request,$language) use ($app,$self) { 34 | 35 | return $app['twig']->render("static/eula_{$language}.twig", array( 36 | )); 37 | 38 | }); 39 | 40 | $controllers->get('/privacypolicy/{language}', function (Request $request,$language) use ($app,$self) { 41 | 42 | return $app['twig']->render("static/privacy_{$language}.twig", array( 43 | )); 44 | 45 | }); 46 | 47 | $controllers->get('/information/{token}', function (Request $request,$token) use ($app,$self) { 48 | 49 | $user = $app['spikadb']->findUserByToken($token); 50 | 51 | if (empty($user['token']) || $token !== $user['token']) { 52 | return $app['twig']->render("static/tokenExpired.twig", array( 53 | 'ROOT_URL' => ROOT_URL, 54 | 55 | )); 56 | } 57 | 58 | $app['session']->set('user', $user); 59 | 60 | return $app['twig']->render("static/information.twig", array( 61 | 'ROOT_URL' => ROOT_URL, 62 | 'user' => $user 63 | )); 64 | 65 | }); 66 | 67 | return $controllers; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/Spika/Middleware/APIGeneralBeforeHandler.php: -------------------------------------------------------------------------------- 1 | db = $db; 24 | $this->logger = $logger; 25 | } 26 | 27 | public function __invoke(Request $request,\Silex\Application $app) 28 | { 29 | 30 | // maintainance mode 31 | // return new Response("maintainance mode", 503); 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/Spika/Middleware/AdminChecker.php: -------------------------------------------------------------------------------- 1 | app = $app; 19 | } 20 | 21 | public function __invoke(Request $request,\Silex\Application $app) 22 | { 23 | if ($app['session']->get('user') === null) { 24 | return $app->redirect(ROOT_URL . '/admin/login'); 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/Spika/Middleware/TokenChecker.php: -------------------------------------------------------------------------------- 1 | db = $db; 24 | $this->logger = $logger; 25 | } 26 | 27 | public function __invoke(Request $request,\Silex\Application $app) 28 | { 29 | 30 | $tokenReceived = $request->headers->get('token'); 31 | 32 | $user = $this->db->findUserByToken($tokenReceived); 33 | 34 | if (empty($user['token']) || $tokenReceived !== $user['token']) { 35 | return $this->abortManually("Invalid token"); 36 | } 37 | 38 | $tokenTimestamp = $user['token_timestamp']; 39 | $currentTimestamp = time(); 40 | $tokenTime = $tokenTimestamp + TOKEN_VALID_TIME; 41 | 42 | if ($tokenTime < $currentTimestamp) { 43 | return $this->abortManually("Token expired"); 44 | } 45 | 46 | $app['currentUser'] = $user; 47 | } 48 | 49 | private function abortManually($errMessage) 50 | { 51 | $arr = array('message' => $errMessage, 'error' => 'logout'); 52 | $json = json_encode($arr); 53 | 54 | return new Response($json, 403); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Spika/Provider/SpikaDbServiceProvider.php: -------------------------------------------------------------------------------- 1 | share(function () use ($app) { 15 | return new MySQL( 16 | $app['logger'], 17 | $app['db'] 18 | ); 19 | }); 20 | 21 | } 22 | 23 | public function boot(Application $app) 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Spika/Provider/TokenCheckerServiceProvider.php: -------------------------------------------------------------------------------- 1 | share(function () use ($app) { 14 | return new TokenChecker( 15 | $app['spikadb'], 16 | $app['logger'], 17 | $app 18 | ); 19 | }); 20 | } 21 | } 22 | 23 | public function boot(Application $app) 24 | { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/alerts.twig: -------------------------------------------------------------------------------- 1 | 2 | {% if infoMessage is defined %} 3 |
4 | 5 | {{infoMessage}} 6 |
7 | {% endif %} 8 | 9 | {% if errorMessage is defined %} 10 |
11 | 12 | {{errorMessage}} 13 |
14 | {% endif %} 15 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/categoryDelete.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 | 6 |
7 |
8 |
9 | {{lang.messageConfirmDeleteGroupCategory}} 10 |
11 |
12 |
13 | 14 |
15 |
16 | 17 | {% include "admin/alerts.twig" %} 18 | 19 |
20 | 21 |
22 |
23 | {{lang.labelpicture}} 24 |
25 |
26 | {% if formValues.avatar_file_id != '' %} 27 | 28 | {% else %} 29 | 30 | {% endif %} 31 |
32 |
33 | 34 |
35 | 36 |
{{formValues.title}}
37 |
38 | 39 |
40 | 41 |
{{formValues.created|date('Y.m.d H:i:s')}}
42 |
43 |
44 | 45 |
{{formValues.modified|date('Y.m.d H:i:s')}}
46 |
47 | 48 | 49 | 50 | 51 |
52 | 53 |
54 | 55 |
56 | 57 | 58 | 59 | {% endblock %} 60 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/categoryList.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

{{lang.labelGroupCategory}} {{lang.btnNewGroupCategory}}

8 |
9 |
10 | 11 |
12 |
13 | {% include "admin/alerts.twig" %} 14 |
15 |
16 | 17 |
18 |
19 | 20 |
21 | {% include "admin/pager.twig" %} 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | {% for category in categories %} 39 | 40 | 41 | 42 | 50 | 51 | 52 | 53 | 68 | 69 | 70 | {% endfor %} 71 | 72 | 73 |
#{{lang.formGroupCategoryAvatar}}{{lang.formGroupCategoryName}}{{lang.labelCreated}}{{lang.labelModified}}
{{category.value._id}} 43 | {% if category.value.avatar_file_id != '' %} 44 | 45 | {% else %} 46 | 47 | 48 | {% endif %} 49 | {{category.value.title}}{{category.value.created}}{{category.value.modified}} 54 | 55 | 56 | {{lang.labelView}} 57 | 58 | 59 | 60 | {{lang.labelEdit}} 61 | 62 | 63 | 64 | {{lang.labelDelete}} 65 | 66 | 67 |
74 | 75 |
76 | {% include "admin/pager.twig" %} 77 |
78 | 79 |
80 | 81 |
82 | 83 | {% endblock %} 84 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/dashboard.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

{{lang.labelDashboard}}

8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 |
{{lang.labelDashboardStatistics}}
17 |
18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
{{lang.labelDashboardTotalUsers}}{{countUsers}}
{{lang.labelDashboardTotalMessages}}{{countMessages}}
{{lang.labelDashboardActiveUsers}}{{countLastLoginedUsers}}
36 | 37 |
38 | 39 | {% if isAdmin %} 40 |
41 |
{{lang.labelDashboardEndpoint}}
42 |
43 | 44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 61 | 62 | 63 | 64 | 65 | 66 | 74 | 75 | 76 | 77 |
{{lang.labelDashboardiOSSettings}} ( Constants.h )
52 | 53 | 54 | /* change here */
55 | #define ServerListAPIURL @"{{ROOT_URL}}/api/servers"
56 | #define DefaultAPIEndPoint @"{{ROOT_URL}}"
57 | #define DefaultPageUrl @"{{ROOT_URL}}/page"
58 | /* end change here */
59 |
60 |
{{lang.labelDashboardAndroidSettings}} ( com.cloverstudio.spika.utils.ConstServer )
67 | 68 | public static final String BASE_URL = "{{ROOT_URL}}";
69 | public static final String INFORMATION_URL = "{{ROOT_URL}}/page/information/";
70 | public static final String LIST_SERVERS_URL = BASE_URL + "/" + Const.API_FOLDER + "servers"; 71 |
72 | 73 |
78 | 79 |
80 | 81 | {% endif %} 82 | 83 |
84 | 85 |
86 | 87 | 88 |
89 | 90 | 91 | {% endblock %} 92 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/emoticonDelete.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |
8 | {{lang.messageConfirmDeleteEmoticon}} 9 |
10 |
11 |
12 | 13 |
14 |
15 | 16 | {% include "admin/alerts.twig" %} 17 | 18 |
19 | 20 |
21 |
22 | {{lang.formGroupEmoticonPicture}} 23 |
24 |
25 | {% if formValues.file_id != '' %} 26 | 27 | {% else %} 28 | 29 | {% endif %} 30 |
31 |
32 | 33 |
34 | 35 |
{{formValues.identifier}}
36 |
37 | 38 |
39 | 40 |
{{formValues.created|date('Y.m.d H:i:s')}}
41 |
42 |
43 | 44 |
{{formValues.modified|date('Y.m.d H:i:s')}}
45 |
46 | 47 | 48 | 49 | 50 | 51 |
52 | 53 |
54 | 55 | 56 |
57 | 58 | 59 | 60 | {% endblock %} 61 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/emoticonForm.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

8 | {% if mode == 'new' %} 9 | {{lang.labelAddEmoticon}} 10 | {% elseif mode == 'view' %} 11 | {{lang.labelViewEmoticon}} 12 | {% elseif mode == 'edit' %} 13 | {{lang.labelEditEmoticon}} 14 | {% endif %} 15 |

16 |
17 |
18 | 19 |
20 |
21 | 22 | {% include "admin/alerts.twig" %} 23 | 24 | {% if mode == 'edit' %} 25 |
26 | {% else %} 27 | 28 | {% endif %} 29 | 30 | {% if mode == 'view' or mode == 'edit' %} 31 | 32 |
33 |
34 | {{lang.formGroupEmoticonPicture}} 35 |
36 |
37 | {% if formValues.file_id != '' %} 38 | 39 | {% else %} 40 | 41 | {% endif %} 42 |
43 |
44 | 45 | {% endif %} 46 | 47 |
48 | 49 | {% if mode == 'new' or mode == 'edit' %}{{lang.noteRequired}}{% endif %} 50 | 51 | {% if mode == 'new' or mode == 'edit'%} 52 | 53 | {% else %} 54 |
{{formValues.identifier}}
55 | {% endif %} 56 | 57 |
58 | 59 | {% if mode == 'new' or mode == 'edit' %} 60 |
61 | 62 | {% if mode == 'new' or mode == 'edit' %}{{lang.noteRequired}}{% endif %} 63 | 64 |
65 | {% endif %} 66 | 67 | {% if mode == 'view'%} 68 |
69 | 70 |
{{formValues.created|date('Y.m.d H:i:s')}}
71 |
72 |
73 | 74 |
{{formValues.modified|date('Y.m.d H:i:s')}}
75 |
76 | {% endif %} 77 | 78 | {% if mode == 'new' or mode == 'edit' %} 79 | 80 | {% else %} 81 | 82 | {% endif %} 83 | 84 |
85 | 86 |
87 | 88 |
89 | 90 | 91 | 92 | {% endblock %} 93 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/emoticonList.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 |
6 |
7 |

{{lang.labelEmoticon}} {{lang.btnNewEmoticon}}

8 |
9 |
10 | 11 |
12 |
13 | {% include "admin/alerts.twig" %} 14 |
15 |
16 | 17 |
18 |
19 | 20 |
21 | {% include "admin/pager.twig" %} 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | {% for emoticon in emoticons %} 39 | 40 | 41 | 42 | 50 | 51 | 52 | 53 | 68 | 69 | 70 | {% endfor %} 71 | 72 | 73 |
#{{lang.formGroupEmoticonPicture}}{{lang.formGroupEmoticonIdentifier}}{{lang.labelCreated}}{{lang.labelModified}}
{{emoticon.value._id}} 43 | {% if emoticon.value.file_id != '' %} 44 | 45 | {% else %} 46 | 47 | 48 | {% endif %} 49 | {{emoticon.value.identifier}}{{emoticon.value.created}}{{emoticon.value.modified}} 54 | 55 | 56 | {{lang.labelView}} 57 | 58 | 59 | 60 | {{lang.labelEdit}} 61 | 62 | 63 | 64 | {{lang.labelDelete}} 65 | 66 | 67 |
74 | 75 |
76 | {% include "admin/pager.twig" %} 77 |
78 | 79 |
80 | 81 |
82 | 83 | {% endblock %} -------------------------------------------------------------------------------- /src/Spika/Views/admin/groupAdd.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 | 29 | 30 |
31 |
32 |

33 | {{lang.labelAddGroup}} 34 |

35 |
36 |
37 | 38 |
39 |
40 | 41 | {% include "admin/alerts.twig" %} 42 | 43 |
44 |
45 | 46 | 51 |
52 | 53 |
54 | {{lang.noteRequired}} 55 | 56 |
57 | 58 |
59 | 60 | 61 |
62 | 63 |
64 | 65 | 66 |
67 | 68 |
69 | {{lang.noteRequired}} 70 | 71 |
72 | 73 | 74 | 75 | 76 |
77 | 78 |
79 | 80 | 81 |
82 | 83 | 84 | 85 | {% endblock %} 86 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/groupDelete.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 | 6 |
7 |
8 |
9 | {{lang.messageConfirmDeleteGroup}} 10 |
11 |
12 |
13 | 14 |
15 |
16 | 17 | {% include "admin/alerts.twig" %} 18 | 19 |
20 | 21 |
22 |
23 | {{lang.labelpicture}} 24 |
25 |
26 | {% if formValues.avatar_thumb_file_id != '' %} 27 | 28 | {% else %} 29 | 30 | {% endif %} 31 | 32 |
33 |
34 | 35 |
36 | 37 |
{{formValues.categoryName}}
38 |
39 | 40 |
41 | 42 |
{{formValues.name}}
43 |
44 | 45 |
46 | 47 |
{% if formValues.group_password != "" %}Yes{% else %}No{% endif %}
48 |
49 | 50 |
51 | 52 |
{{formValues.description}}
53 |
54 | 55 | 56 | 57 | 58 |
59 | 60 |
61 | 62 |
63 | 64 | 65 | 66 | {% endblock %} 67 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/login.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{lang.adminSiteTitle}} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 |
26 | 53 |
54 |
55 |
56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/newsDelete.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 | 6 |
7 |
8 |
9 | {{lang.messageConfirmDeleteStory}} 10 |
11 |
12 |
13 | 14 |
15 |
16 | 17 | {% include "admin/alerts.twig" %} 18 | 19 |
20 | 21 |
22 | 23 |
{{formValues.title}}
24 |
25 | 26 |
27 | 28 |
{{formValues.story_url}}
29 |
30 | 31 |
32 | 33 |
{{formValues.content}}
34 |
35 | 36 | 37 | 38 | 39 |
40 | 41 |
42 | 43 | 44 |
45 | 46 | 47 | 48 | {% endblock %} 49 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/newsForm.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 | 29 | 30 |
31 |
32 |

33 | {% if mode == 'new' %} 34 | {{lang.labelAddNews}} 35 | {% elseif mode == 'view' %} 36 | {{lang.labelViewNews}} 37 | {% elseif mode == 'edit' %} 38 | {{lang.labelEditNews}} 39 | {% endif %} 40 |

41 |
42 |
43 | 44 |
45 |
46 | 47 | {% include "admin/alerts.twig" %} 48 | 49 | {% if mode == 'edit' %} 50 |
51 | {% else %} 52 | 53 | {% endif %} 54 | 55 |
56 | 57 | {% if mode == 'new' or mode == 'edit' %}{{lang.noteRequired}}{% endif %} 58 | 59 | {% if mode == 'new' or mode == 'edit'%} 60 | 61 | {% else %} 62 |
{{formValues.title}}
63 | {% endif %} 64 | 65 |
66 | 67 |
68 | 69 | 70 | {% if mode == 'new' or mode == 'edit'%} 71 | 72 | {% else %} 73 |
{{formValues.story_url}}
74 | {% endif %} 75 | 76 |
77 | 78 |
79 | 80 | {% if mode == 'new' or mode == 'edit' %}{{lang.noteRequired}}{% endif %} 81 | 82 | {% if mode == 'new' or mode == 'edit'%} 83 | 84 | {% else %} 85 |
{{formValues.content}}
86 | {% endif %} 87 | 88 |
89 | 90 | {% if mode == 'new' or mode == 'edit' %} 91 | 92 | {% else %} 93 | 94 | {% endif %} 95 | 96 |
97 | 98 |
99 | 100 | 101 |
102 | 103 | 104 | 105 | {% endblock %} 106 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/pager.twig: -------------------------------------------------------------------------------- 1 | {% set showPages = 8 %} 2 | 3 | 87 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/serversDelete.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 | 6 |
7 |
8 |
9 | {{lang.messageConfirmDeleteServer}} 10 |
11 |
12 |
13 | 14 |
15 |
16 | 17 | {% include "admin/alerts.twig" %} 18 | 19 |
20 | 21 |
22 | 23 |
{{formValues.name}}
24 |
25 | 26 |
27 | 28 |
{{formValues.url}}
29 |
30 | 31 | 32 | 33 | 34 |
35 | 36 |
37 | 38 | 39 |
40 | 41 | 42 | 43 | {% endblock %} 44 | -------------------------------------------------------------------------------- /src/Spika/Views/admin/serversForm.twig: -------------------------------------------------------------------------------- 1 | {% extends "admin/adminBase.twig" %} 2 | 3 | {% block content %} 4 | 5 | 29 | 30 |
31 |
32 |

33 | {% if mode == 'new' %} 34 | {{lang.labelAddServer}} 35 | {% elseif mode == 'view' %} 36 | {{lang.labelViewServer}} 37 | {% elseif mode == 'edit' %} 38 | {{lang.labelEditServer}} 39 | {% endif %} 40 |

41 |
42 |
43 | 44 |
45 |
46 | 47 | {% include "admin/alerts.twig" %} 48 | 49 | {% if mode == 'edit' %} 50 |
51 | {% else %} 52 | 53 | {% endif %} 54 | 55 |
56 | 57 | {% if mode == 'new' or mode == 'edit' %}{{lang.noteRequired}}{% endif %} 58 | 59 | {% if mode == 'new' or mode == 'edit'%} 60 | 61 | {% else %} 62 |
{{formValues.name}}
63 | {% endif %} 64 | 65 |
66 | 67 |
68 | 69 | {% if mode == 'new' or mode == 'edit' %}{{lang.noteRequired}}{% endif %} 70 | 71 | {% if mode == 'new' or mode == 'edit'%} 72 | 73 | {% else %} 74 |
{{formValues.url}}
75 | {% endif %} 76 | 77 |
78 | 79 | {% if mode == 'new' or mode == 'edit' %} 80 | 81 | {% else %} 82 | 83 | {% endif %} 84 | 85 |
86 | 87 |
88 | 89 |
90 | 91 | 92 | 93 | {% endblock %} 94 | -------------------------------------------------------------------------------- /src/Spika/Views/client/login.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{lang.clientSiteTitle}} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |
22 | 55 |
56 |
57 |
58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/Spika/Views/client/regist.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{lang.clientSiteTitle}} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 |
26 | 52 |
53 |
54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/Spika/Views/client/resetpassword.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{lang.clientSiteTitle}} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 |
26 | 48 |
49 |
50 |
51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/Spika/Views/installer/installerError.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Spika Installer 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 50 | 51 | 52 | 53 | 54 |
55 | 56 | 57 |
58 |

Welcome to Spika server installer

59 |

60 | Spika is opensource mobile messenger system. Please follow this setup to install Spika backend to your server. 61 |

62 |
63 | 64 |
65 |
66 | 67 |
68 |
69 | Sotfware Requirements 70 |
71 | 72 |
73 |
    74 |
  • 75 | PHP 5.3.3+
    76 | Modules required 77 |
      78 |
    • PDO
    • 79 |
    • cURL
    • 80 |
    81 |
  • 82 |
  • 83 | MySQL 5.0.0+ 84 |
  • 85 |
  • 86 | curl 7.16.2+ 87 |
  • 88 |
  • 89 | postfix 2.0.0+ 90 |
  • 91 |
92 | 93 |
94 |
95 | 96 | 106 | 107 | 108 |
109 |
110 |
111 | Failed to install Spika backend. Please start again from here. 112 |
113 |
114 |
115 | 116 | 117 |
118 | 119 | 120 | -------------------------------------------------------------------------------- /src/Spika/Views/passwordReset/passwordReset.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Spika Reset Password 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 71 | 72 | 73 | 74 | 75 |
76 | 77 | {% if error is defined %}{% if error != "" %} 78 |
{{error}}
79 | {% endif %}{% endif %} 80 | 81 | 82 |
83 | Please enter new password 84 | 85 | 86 | 87 | 88 |
89 | 90 |
91 | 92 | 93 | -------------------------------------------------------------------------------- /src/Spika/Views/passwordReset/passwordResetError.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Spika Reset Password 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 71 | 72 | 73 | 74 | 75 |
76 | 77 |
Invalid reset code or it's already expired.
78 | 79 |
80 | 81 | 82 | -------------------------------------------------------------------------------- /src/Spika/Views/passwordReset/passwordResetSucceed.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Spika Reset Password 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 71 | 72 | 73 | 74 | 75 |
76 | 77 |
Your password is successfully changed.Please login now.
78 | 79 |
80 | 81 | 82 | -------------------------------------------------------------------------------- /src/Spika/Views/static/information.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Information 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 29 | 34 | 35 | 36 | 37 | 38 |
39 | 40 |
41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/Spika/Views/static/tokenExpired.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Information 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 29 | 30 | 31 | 32 | 33 |
34 | 35 |
Token Expired
36 | 37 |
38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/Spika/Views/webview/alerts.twig: -------------------------------------------------------------------------------- 1 | 2 | {% if infoMessage != '' %} 3 |
4 | 5 | {{infoMessage}} 6 |
7 | {% endif %} 8 | 9 | {% if errorMessage != '' %} 10 |
11 | 12 | {{errorMessage}} 13 |
14 | {% endif %} 15 | -------------------------------------------------------------------------------- /src/Spika/Views/webview/nav_bar.twig: -------------------------------------------------------------------------------- 1 | 2 | 16 | -------------------------------------------------------------------------------- /src/Spika/Views/webview/newsListDevice.twig: -------------------------------------------------------------------------------- 1 | {% extends "webview/webViewBaseForDevice.twig" %} 2 | 3 | {% block content %} 4 | 5 | {% include "webview/nav_bar.twig" %} 6 | 7 | {% for story in news %} 8 |
9 | {% autoescape false %} 10 |
{{ story.title }}{{ story.created }}
11 |
{{ story.content }}
12 | {% if story.story_url == '' %} 13 | 14 | {% else %} 15 | 16 | {% endif %} 17 |
18 | {% endautoescape %} 19 |
20 | {% endfor %} 21 | 22 |
23 | {% include "webview/pager.twig" %} 24 |
25 | 26 | {% endblock %} -------------------------------------------------------------------------------- /src/Spika/Views/webview/newsViewDevice.twig: -------------------------------------------------------------------------------- 1 | {% extends "webview/webViewBaseForDevice.twig" %} 2 | 3 | {% block content %} 4 | 5 | {% set isNew=1 %} 6 | {% include "webview/nav_bar.twig" %} 7 | 8 |
9 | {% autoescape false %} 10 |
{{ story.title }}{{ story.created }}
11 |
{{ story.content }}
12 | {% endautoescape %} 13 |
14 | 15 |
16 | {% include "webview/alerts.twig" %} 17 |
18 | 19 |
20 | {% for com in comments %} 21 |
22 | 23 | {% if com.avatar != '' %} 24 | 25 | {% else %} 26 | 27 | {% endif %} 28 | 29 |
30 |
31 |
{{com.user_name}}
32 | {{ com.created }} 33 |
34 | {{com.comment}} 35 |
36 |
37 | {% endfor %} 38 |
39 | 40 |
41 | {% include "webview/pager.twig" %} 42 |
43 | 44 |
45 |
46 | 47 | 48 | 49 | 50 |
51 |
52 | 53 | {% endblock %} 54 | 55 | -------------------------------------------------------------------------------- /src/Spika/Views/webview/pager.twig: -------------------------------------------------------------------------------- 1 | {% if pager.pageCount > 0 %} 2 | 26 | {% endif %} 27 | -------------------------------------------------------------------------------- /src/Spika/Views/webview/webViewBaseForDevice.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{lang.labelNews}} 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 | {% block content %}{% endblock %} 47 |
48 | 49 | -------------------------------------------------------------------------------- /tests/Spika/Controller/ReportControllerTest.php: -------------------------------------------------------------------------------- 1 | $pimple->protect(function () { 18 | }) 19 | ); 20 | 21 | require SPIKA_ROOT . '/etc/app.php'; 22 | 23 | $mailer = $this->getMockBuilder('\Silex\Provider\SwiftmailerServiceProvider') 24 | ->setMethods(array('send')) 25 | ->disableOriginalConstructor() 26 | ->getMock(); 27 | $mailer->expects(once()) 28 | ->method('send') 29 | ->with(isInstanceOf('Swift_Message')); 30 | $app['mailer'] = $mailer; 31 | 32 | return $app; 33 | } 34 | 35 | /** @test */ 36 | public function reportViolationSendsMailAndReturnsOK() 37 | { 38 | $client = $this->createClient(); 39 | $crawler = $client->request('GET', '/api/reportViolation.php', array('docment_id' => 'testid')); 40 | assertSame('OK', $client->getResponse()->getContent()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Spika/Controller/SearchUserControllerTest.php: -------------------------------------------------------------------------------- 1 | getMock('\Spika\Db\DbInterface'); 22 | 23 | $spikadb->expects($this->any()) 24 | ->method('searchUserByName') 25 | ->will($this->returnValue('[]')); 26 | 27 | $spikadb->expects($this->any()) 28 | ->method('searchUserByGender') 29 | ->will($this->returnValue('[]')); 30 | 31 | $spikadb->expects($this->any()) 32 | ->method('searchUserByAge') 33 | ->will($this->returnValue('[]')); 34 | 35 | $spikadb->expects($this->any()) 36 | ->method('searchUser') 37 | ->will($this->returnValue('[]')); 38 | 39 | $app['spikadb'] = $spikadb; 40 | 41 | return $app; 42 | } 43 | 44 | /** @test */ 45 | public function searchUserByName() 46 | { 47 | $client = $this->createClient(); 48 | $crawler = $client->request('GET', '/api/searchUsers?n=test'); 49 | assertRegExp('/\[\]/', $client->getResponse()->getContent()); 50 | } 51 | 52 | /** @test */ 53 | public function searchUserByGender() 54 | { 55 | $client = $this->createClient(); 56 | $crawler = $client->request('GET', '/api/searchUsers?g=male'); 57 | assertRegExp('/\[\]/', $client->getResponse()->getContent()); 58 | } 59 | 60 | /** @test */ 61 | public function searchUserByAge() 62 | { 63 | $client = $this->createClient(); 64 | $crawler = $client->request('GET', '/api/searchUsers?af=30&at=35'); 65 | assertRegExp('/\[\]/', $client->getResponse()->getContent()); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/Spika/Middleware/TokenCheckerTest.php: -------------------------------------------------------------------------------- 1 | createFixtureUser(); 21 | $db = $this->createMockDb(); 22 | 23 | $db->expects(any()) 24 | ->method('findUserByToken') 25 | ->will(returnValue($user)); 26 | 27 | $checker = $this->createTokenChecker($db); 28 | $request = $this->createValidRequest(); 29 | 30 | $this->assertNull($checker($request,$app)); 31 | } 32 | 33 | /** 34 | * @test 35 | */ 36 | public function whenTokenIsNotMatched() 37 | { 38 | require realpath(__DIR__ . '/../../../') . '/etc/app.php'; 39 | $db = $this->createMockDb(); 40 | $user = array_merge( 41 | $this->createFixtureUser(), 42 | array('token' => 'token_not_matched') 43 | ); 44 | 45 | $db->expects(any()) 46 | ->method('findUserByToken') 47 | ->will(returnValue($user)); 48 | 49 | $checker = $this->createTokenChecker($db); 50 | $request = $this->createValidRequest(); 51 | 52 | $this->assertErrorResponse( 53 | 403, 54 | 'Invalid token', 55 | $checker($request,$app) 56 | ); 57 | } 58 | 59 | /** 60 | * @test 61 | */ 62 | public function whenTokenExpirationIsLeftOneSecond() 63 | { 64 | require realpath(__DIR__ . '/../../../') . '/etc/app.php'; 65 | $db = $this->createMockDb(); 66 | $user = array_merge( 67 | $this->createFixtureUser(), 68 | array('token_timestamp' => time() - TOKEN_VALID_TIME) 69 | ); 70 | 71 | $db->expects(any()) 72 | ->method('findUserByToken') 73 | ->will(returnValue($user)); 74 | 75 | $checker = $this->createTokenChecker($db); 76 | $request = $this->createValidRequest(); 77 | 78 | $this->assertNull($checker($request,$app)); 79 | } 80 | 81 | /** 82 | * @test 83 | */ 84 | public function whenTokenIsExpired() 85 | { 86 | require realpath(__DIR__ . '/../../../') . '/etc/app.php'; 87 | $db = $this->createMockDb(); 88 | $user = array_merge( 89 | $this->createFixtureUser(), 90 | array('token_timestamp' => time() - TOKEN_VALID_TIME - 1) 91 | ); 92 | 93 | $db->expects(any()) 94 | ->method('findUserByToken') 95 | ->will(returnValue($user)); 96 | 97 | $checker = $this->createTokenChecker($db); 98 | $request = $this->createValidRequest(); 99 | 100 | $this->assertErrorResponse( 101 | 403, 102 | 'Token expired', 103 | $checker($request,$app) 104 | ); 105 | } 106 | 107 | private function createTokenChecker(DbInterface $db) 108 | { 109 | return new TokenChecker( 110 | $db, 111 | $this->getMock('Psr\Log\LoggerInterface') 112 | ); 113 | } 114 | 115 | private function createMockDb() 116 | { 117 | return $this->getMock('Spika\Db\DbInterface'); 118 | } 119 | 120 | private function createFixtureUser() 121 | { 122 | return array( 123 | '_id' => self::FIXTURE_USER_ID, 124 | 'token' => self::FIXTURE_TOKEN, 125 | 'token_timestamp' => time(), 126 | ); 127 | } 128 | 129 | private function createValidRequest($path = "", $method = "GET", $requestBody = "") 130 | { 131 | 132 | return Request::create( 133 | $path, 134 | $method, 135 | array(), 136 | array(), 137 | array(), 138 | array( 139 | 'HTTP_TOKEN' => self::FIXTURE_TOKEN, 140 | ), 141 | $requestBody 142 | ); 143 | 144 | } 145 | 146 | private function assertErrorResponse($expectedStatus, $expectedMessage, $response) 147 | { 148 | $this->assertInstanceOf( 149 | 'Symfony\Component\HttpFoundation\Response', 150 | $response 151 | ); 152 | $this->assertSame($expectedStatus, $response->getStatusCode()); 153 | 154 | $message = json_decode($response->getContent())->message; 155 | 156 | $this->assertSame($expectedMessage, $message); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /tests/Spika/PsrTest.php: -------------------------------------------------------------------------------- 1 | assertResult(`$cmd`); 23 | } 24 | 25 | public function testPsr2() 26 | { 27 | $cmd = self::$PHP_CS . ' --standard=PSR2 ' . self::$TARGET_DIR; 28 | $this->assertResult(`$cmd`); 29 | } 30 | 31 | protected function assertResult($result) 32 | { 33 | assertThat($result, logicalOr(matchesRegularExpression(self::$RESULT_SUCCESS_RE), isNull())); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | 2 | Options -MultiViews 3 | 4 | RewriteEngine On 5 | RewriteCond %{REQUEST_FILENAME} !-f 6 | RewriteRule ^ api.php [QSA,L] 7 | -------------------------------------------------------------------------------- /wwwroot/api.php: -------------------------------------------------------------------------------- 1 | run(); 6 | -------------------------------------------------------------------------------- /wwwroot/assets/css/plugins/morris/morris-0.4.3.min.css: -------------------------------------------------------------------------------- 1 | .morris-hover{position:absolute;z-index:1000;}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255, 255, 255, 0.8);border:solid 2px rgba(230, 230, 230, 0.8);font-family:sans-serif;font-size:12px;text-align:center;}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0;} 2 | .morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0;} -------------------------------------------------------------------------------- /wwwroot/assets/css/plugins/timeline/timeline.css: -------------------------------------------------------------------------------- 1 | .timeline { 2 | position: relative; 3 | padding: 20px 0 20px; 4 | list-style: none; 5 | } 6 | 7 | .timeline:before { 8 | content: " "; 9 | position: absolute; 10 | top: 0; 11 | bottom: 0; 12 | left: 50%; 13 | width: 3px; 14 | margin-left: -1.5px; 15 | background-color: #eeeeee; 16 | } 17 | 18 | .timeline > li { 19 | position: relative; 20 | margin-bottom: 20px; 21 | } 22 | 23 | .timeline > li:before, 24 | .timeline > li:after { 25 | content: " "; 26 | display: table; 27 | } 28 | 29 | .timeline > li:after { 30 | clear: both; 31 | } 32 | 33 | .timeline > li:before, 34 | .timeline > li:after { 35 | content: " "; 36 | display: table; 37 | } 38 | 39 | .timeline > li:after { 40 | clear: both; 41 | } 42 | 43 | .timeline > li > .timeline-panel { 44 | float: left; 45 | position: relative; 46 | width: 46%; 47 | padding: 20px; 48 | border: 1px solid #d4d4d4; 49 | border-radius: 2px; 50 | -webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.175); 51 | box-shadow: 0 1px 6px rgba(0,0,0,0.175); 52 | } 53 | 54 | .timeline > li > .timeline-panel:before { 55 | content: " "; 56 | display: inline-block; 57 | position: absolute; 58 | top: 26px; 59 | right: -15px; 60 | border-top: 15px solid transparent; 61 | border-right: 0 solid #ccc; 62 | border-bottom: 15px solid transparent; 63 | border-left: 15px solid #ccc; 64 | } 65 | 66 | .timeline > li > .timeline-panel:after { 67 | content: " "; 68 | display: inline-block; 69 | position: absolute; 70 | top: 27px; 71 | right: -14px; 72 | border-top: 14px solid transparent; 73 | border-right: 0 solid #fff; 74 | border-bottom: 14px solid transparent; 75 | border-left: 14px solid #fff; 76 | } 77 | 78 | .timeline > li > .timeline-badge { 79 | z-index: 100; 80 | position: absolute; 81 | top: 16px; 82 | left: 50%; 83 | width: 50px; 84 | height: 50px; 85 | margin-left: -25px; 86 | border-radius: 50% 50% 50% 50%; 87 | text-align: center; 88 | font-size: 1.4em; 89 | line-height: 50px; 90 | color: #fff; 91 | background-color: #999999; 92 | } 93 | 94 | .timeline > li.timeline-inverted > .timeline-panel { 95 | float: right; 96 | } 97 | 98 | .timeline > li.timeline-inverted > .timeline-panel:before { 99 | right: auto; 100 | left: -15px; 101 | border-right-width: 15px; 102 | border-left-width: 0; 103 | } 104 | 105 | .timeline > li.timeline-inverted > .timeline-panel:after { 106 | right: auto; 107 | left: -14px; 108 | border-right-width: 14px; 109 | border-left-width: 0; 110 | } 111 | 112 | .timeline-badge.primary { 113 | background-color: #2e6da4 !important; 114 | } 115 | 116 | .timeline-badge.success { 117 | background-color: #3f903f !important; 118 | } 119 | 120 | .timeline-badge.warning { 121 | background-color: #f0ad4e !important; 122 | } 123 | 124 | .timeline-badge.danger { 125 | background-color: #d9534f !important; 126 | } 127 | 128 | .timeline-badge.info { 129 | background-color: #5bc0de !important; 130 | } 131 | 132 | .timeline-title { 133 | margin-top: 0; 134 | color: inherit; 135 | } 136 | 137 | .timeline-body > p, 138 | .timeline-body > ul { 139 | margin-bottom: 0; 140 | } 141 | 142 | .timeline-body > p + p { 143 | margin-top: 5px; 144 | } -------------------------------------------------------------------------------- /wwwroot/assets/css/sb-device.css: -------------------------------------------------------------------------------- 1 | /* Global Styles */ 2 | 3 | /* ------------------------------- */ 4 | 5 | body { 6 | background-color: #f8f8f8; 7 | } 8 | 9 | #wrapper { 10 | width: 100%; 11 | } 12 | 13 | .panel{ 14 | margin: 20px; 15 | } 16 | 17 | .panel-heading{ 18 | font-weight: bold; 19 | overflow: hidden; 20 | } 21 | .panel-body button{ 22 | float: right; 23 | } 24 | .alert{ 25 | margin-left: 20px; 26 | margin-right: 20px; 27 | } 28 | 29 | .alert_wrapper{ 30 | width: 100%; 31 | } 32 | #comment_wrapper img{ 33 | width: 64px; 34 | height: 64px; 35 | } -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/wwwroot/assets/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/wwwroot/assets/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/wwwroot/assets/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/wwwroot/assets/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .@{fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: -@fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon-rotate(@degrees, @rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation); 6 | -webkit-transform: rotate(@degrees); 7 | -moz-transform: rotate(@degrees); 8 | -ms-transform: rotate(@degrees); 9 | -o-transform: rotate(@degrees); 10 | transform: rotate(@degrees); 11 | } 12 | 13 | .fa-icon-flip(@horiz, @vert, @rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1); 15 | -webkit-transform: scale(@horiz, @vert); 16 | -moz-transform: scale(@horiz, @vert); 17 | -ms-transform: scale(@horiz, @vert); 18 | -o-transform: scale(@horiz, @vert); 19 | transform: scale(@horiz, @vert); 20 | } 21 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 9 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 10 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 11 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/spinning.less: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @-ms-keyframes spin { 24 | 0% { -ms-transform: rotate(0deg); } 25 | 100% { -ms-transform: rotate(359deg); } 26 | } 27 | @keyframes spin { 28 | 0% { transform: rotate(0deg); } 29 | 100% { transform: rotate(359deg); } 30 | } 31 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .pull-right { float: right; } 11 | .pull-left { float: left; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.pull-left { margin-right: .3em; } 15 | &.pull-right { margin-left: .3em; } 16 | } 17 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font-family: FontAwesome; 7 | font-style: normal; 8 | font-weight: normal; 9 | line-height: 1; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon-rotate($degrees, $rotation) { 5 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation); 6 | -webkit-transform: rotate($degrees); 7 | -moz-transform: rotate($degrees); 8 | -ms-transform: rotate($degrees); 9 | -o-transform: rotate($degrees); 10 | transform: rotate($degrees); 11 | } 12 | 13 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 14 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation); 15 | -webkit-transform: scale($horiz, $vert); 16 | -moz-transform: scale($horiz, $vert); 17 | -ms-transform: scale($horiz, $vert); 18 | -o-transform: scale($horiz, $vert); 19 | transform: scale($horiz, $vert); 20 | } 21 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 9 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 10 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 11 | //src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 12 | font-weight: normal; 13 | font-style: normal; 14 | } 15 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_spinning.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: spin 2s infinite linear; 6 | -moz-animation: spin 2s infinite linear; 7 | -o-animation: spin 2s infinite linear; 8 | animation: spin 2s infinite linear; 9 | } 10 | 11 | @-moz-keyframes spin { 12 | 0% { -moz-transform: rotate(0deg); } 13 | 100% { -moz-transform: rotate(359deg); } 14 | } 15 | @-webkit-keyframes spin { 16 | 0% { -webkit-transform: rotate(0deg); } 17 | 100% { -webkit-transform: rotate(359deg); } 18 | } 19 | @-o-keyframes spin { 20 | 0% { -o-transform: rotate(0deg); } 21 | 100% { -o-transform: rotate(359deg); } 22 | } 23 | @-ms-keyframes spin { 24 | 0% { -ms-transform: rotate(0deg); } 25 | 100% { -ms-transform: rotate(359deg); } 26 | } 27 | @keyframes spin { 28 | 0% { transform: rotate(0deg); } 29 | 100% { transform: rotate(359deg); } 30 | } 31 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /wwwroot/assets/font-awesome/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "spinning"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | -------------------------------------------------------------------------------- /wwwroot/assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/wwwroot/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /wwwroot/assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/wwwroot/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /wwwroot/assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloverstudio/Spika-Server/e1936821502cba8c8bf59b1268c574ed4101dcce/wwwroot/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /wwwroot/assets/js/cookies.min.js: -------------------------------------------------------------------------------- 1 | /*! Cookies.js - 0.3.1; Copyright (c) 2013, Scott Hamper; http://www.opensource.org/licenses/MIT */ 2 | (function(e){"use strict";var a=function(b,d,c){return 1===arguments.length?a.get(b):a.set(b,d,c)};a._document=document;a._navigator=navigator;a.defaults={path:"/"};a.get=function(b){a._cachedDocumentCookie!==a._document.cookie&&a._renewCache();return a._cache[b]};a.set=function(b,d,c){c=a._getExtendedOptions(c);c.expires=a._getExpiresDate(d===e?-1:c.expires);a._document.cookie=a._generateCookieString(b,d,c);return a};a.expire=function(b,d){return a.set(b,e,d)};a._getExtendedOptions=function(b){return{path:b&& b.path||a.defaults.path,domain:b&&b.domain||a.defaults.domain,expires:b&&b.expires||a.defaults.expires,secure:b&&b.secure!==e?b.secure:a.defaults.secure}};a._isValidDate=function(b){return"[object Date]"===Object.prototype.toString.call(b)&&!isNaN(b.getTime())};a._getExpiresDate=function(b,d){d=d||new Date;switch(typeof b){case "number":b=new Date(d.getTime()+1E3*b);break;case "string":b=new Date(b)}if(b&&!a._isValidDate(b))throw Error("`expires` parameter cannot be converted to a valid Date instance"); return b};a._generateCookieString=function(b,a,c){b=encodeURIComponent(b);a=(a+"").replace(/[^!#$&-+\--:<-\[\]-~]/g,encodeURIComponent);c=c||{};b=b+"="+a+(c.path?";path="+c.path:"");b+=c.domain?";domain="+c.domain:"";b+=c.expires?";expires="+c.expires.toUTCString():"";return b+=c.secure?";secure":""};a._getCookieObjectFromString=function(b){var d={};b=b?b.split("; "):[];for(var c=0;ca?b.length:a;return{key:decodeURIComponent(b.substr(0,a)),value:decodeURIComponent(b.substr(a+1))}};a._renewCache=function(){a._cache=a._getCookieObjectFromString(a._document.cookie);a._cachedDocumentCookie=a._document.cookie};a._areEnabled=function(){var b="1"===a.set("cookies.js",1).get("cookies.js");a.expire("cookies.js");return b};a.enabled=a._areEnabled();"function"===typeof define&&define.amd?define(function(){return a}):"undefined"!==typeof exports?("undefined"!== typeof module&&module.exports&&(exports=module.exports=a),exports.Cookies=a):window.Cookies=a})(); -------------------------------------------------------------------------------- /wwwroot/assets/js/plugins/flot/jquery.flot.resize.js: -------------------------------------------------------------------------------- 1 | /* Flot plugin for automatically redrawing plots as the placeholder resizes. 2 | 3 | Copyright (c) 2007-2013 IOLA and Ole Laursen. 4 | Licensed under the MIT license. 5 | 6 | It works by listening for changes on the placeholder div (through the jQuery 7 | resize event plugin) - if the size changes, it will redraw the plot. 8 | 9 | There are no options. If you need to disable the plugin for some plots, you 10 | can just fix the size of their placeholders. 11 | 12 | */ 13 | 14 | /* Inline dependency: 15 | * jQuery resize event - v1.1 - 3/14/2010 16 | * http://benalman.com/projects/jquery-resize-plugin/ 17 | * 18 | * Copyright (c) 2010 "Cowboy" Ben Alman 19 | * Dual licensed under the MIT and GPL licenses. 20 | * http://benalman.com/about/license/ 21 | */ 22 | 23 | (function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this); 24 | 25 | (function ($) { 26 | var options = { }; // no options 27 | 28 | function init(plot) { 29 | function onResize() { 30 | var placeholder = plot.getPlaceholder(); 31 | 32 | // somebody might have hidden us and we can't plot 33 | // when we don't have the dimensions 34 | if (placeholder.width() == 0 || placeholder.height() == 0) 35 | return; 36 | 37 | plot.resize(); 38 | plot.setupGrid(); 39 | plot.draw(); 40 | } 41 | 42 | function bindEvents(plot, eventHolder) { 43 | plot.getPlaceholder().resize(onResize); 44 | } 45 | 46 | function shutdown(plot, eventHolder) { 47 | plot.getPlaceholder().unbind("resize", onResize); 48 | } 49 | 50 | plot.hooks.bindEvents.push(bindEvents); 51 | plot.hooks.shutdown.push(shutdown); 52 | } 53 | 54 | $.plot.plugins.push({ 55 | init: init, 56 | options: options, 57 | name: 'resize', 58 | version: '1.0' 59 | }); 60 | })(jQuery); -------------------------------------------------------------------------------- /wwwroot/assets/js/plugins/flot/jquery.flot.tooltip.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jquery.flot.tooltip 3 | * 4 | * description: easy-to-use tooltips for Flot charts 5 | * version: 0.6.2 6 | * author: Krzysztof Urbas @krzysu [myviews.pl] 7 | * website: https://github.com/krzysu/flot.tooltip 8 | * 9 | * build on 2013-09-30 10 | * released under MIT License, 2012 11 | */ 12 | (function(t){var o={tooltip:!1,tooltipOpts:{content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,shifts:{x:10,y:20},defaultTheme:!0,onHover:function(){}}},i=function(t){this.tipPosition={x:0,y:0},this.init(t)};i.prototype.init=function(o){function i(t){var o={};o.x=t.pageX,o.y=t.pageY,s.updateTooltipPosition(o)}function e(t,o,i){var e=s.getDomElement();if(i){var n;n=s.stringFormat(s.tooltipOptions.content,i),e.html(n),s.updateTooltipPosition({x:o.pageX,y:o.pageY}),e.css({left:s.tipPosition.x+s.tooltipOptions.shifts.x,top:s.tipPosition.y+s.tooltipOptions.shifts.y}).show(),"function"==typeof s.tooltipOptions.onHover&&s.tooltipOptions.onHover(i,e)}else e.hide().html("")}var s=this;o.hooks.bindEvents.push(function(o,n){s.plotOptions=o.getOptions(),s.plotOptions.tooltip!==!1&&void 0!==s.plotOptions.tooltip&&(s.tooltipOptions=s.plotOptions.tooltipOpts,s.getDomElement(),t(o.getPlaceholder()).bind("plothover",e),t(n).bind("mousemove",i))}),o.hooks.shutdown.push(function(o,s){t(o.getPlaceholder()).unbind("plothover",e),t(s).unbind("mousemove",i)})},i.prototype.getDomElement=function(){var o;return t("#flotTip").length>0?o=t("#flotTip"):(o=t("
").attr("id","flotTip"),o.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&o.css({background:"#fff","z-index":"100",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"})),o},i.prototype.updateTooltipPosition=function(o){var i=t("#flotTip").outerWidth()+this.tooltipOptions.shifts.x,e=t("#flotTip").outerHeight()+this.tooltipOptions.shifts.y;o.x-t(window).scrollLeft()>t(window).innerWidth()-i&&(o.x-=i),o.y-t(window).scrollTop()>t(window).innerHeight()-e&&(o.y-=e),this.tipPosition.x=o.x,this.tipPosition.y=o.y},i.prototype.stringFormat=function(t,o){var i=/%p\.{0,1}(\d{0,})/,e=/%s/,s=/%x\.{0,1}(?:\d{0,})/,n=/%y\.{0,1}(?:\d{0,})/;return"function"==typeof t&&(t=t(o.series.label,o.series.data[o.dataIndex][0],o.series.data[o.dataIndex][1],o)),o.series.percent!==void 0&&(t=this.adjustValPrecision(i,t,o.series.percent)),o.series.label!==void 0&&(t=t.replace(e,o.series.label)),this.isTimeMode("xaxis",o)&&this.isXDateFormat(o)&&(t=t.replace(s,this.timestampToDate(o.series.data[o.dataIndex][0],this.tooltipOptions.xDateFormat))),this.isTimeMode("yaxis",o)&&this.isYDateFormat(o)&&(t=t.replace(n,this.timestampToDate(o.series.data[o.dataIndex][1],this.tooltipOptions.yDateFormat))),"number"==typeof o.series.data[o.dataIndex][0]&&(t=this.adjustValPrecision(s,t,o.series.data[o.dataIndex][0])),"number"==typeof o.series.data[o.dataIndex][1]&&(t=this.adjustValPrecision(n,t,o.series.data[o.dataIndex][1])),o.series.xaxis.tickFormatter!==void 0&&(t=t.replace(s,o.series.xaxis.tickFormatter(o.series.data[o.dataIndex][0],o.series.xaxis))),o.series.yaxis.tickFormatter!==void 0&&(t=t.replace(n,o.series.yaxis.tickFormatter(o.series.data[o.dataIndex][1],o.series.yaxis))),t},i.prototype.isTimeMode=function(t,o){return o.series[t].options.mode!==void 0&&"time"===o.series[t].options.mode},i.prototype.isXDateFormat=function(){return this.tooltipOptions.xDateFormat!==void 0&&null!==this.tooltipOptions.xDateFormat},i.prototype.isYDateFormat=function(){return this.tooltipOptions.yDateFormat!==void 0&&null!==this.tooltipOptions.yDateFormat},i.prototype.timestampToDate=function(o,i){var e=new Date(o);return t.plot.formatDate(e,i)},i.prototype.adjustValPrecision=function(t,o,i){var e,s=o.match(t);return null!==s&&""!==RegExp.$1&&(e=RegExp.$1,i=i.toFixed(e),o=o.replace(t,i)),o};var e=function(t){new i(t)};t.plot.plugins.push({init:e,options:o,name:"tooltip",version:"0.6.1"})})(jQuery); -------------------------------------------------------------------------------- /wwwroot/assets/js/plugins/metisMenu/jquery.metisMenu.js: -------------------------------------------------------------------------------- 1 | ;(function ($, window, document, undefined) { 2 | 3 | var pluginName = "metisMenu", 4 | defaults = { 5 | toggle: true 6 | }; 7 | 8 | function Plugin(element, options) { 9 | this.element = element; 10 | this.settings = $.extend({}, defaults, options); 11 | this._defaults = defaults; 12 | this._name = pluginName; 13 | this.init(); 14 | } 15 | 16 | Plugin.prototype = { 17 | init: function () { 18 | 19 | var $this = $(this.element), 20 | $toggle = this.settings.toggle; 21 | 22 | $this.find('li.active').has('ul').children('ul').addClass('collapse in'); 23 | $this.find('li').not('.active').has('ul').children('ul').addClass('collapse'); 24 | 25 | $this.find('li').has('ul').children('a').on('click', function (e) { 26 | e.preventDefault(); 27 | 28 | $(this).parent('li').toggleClass('active').children('ul').collapse('toggle'); 29 | 30 | if ($toggle) { 31 | $(this).parent('li').siblings().removeClass('active').children('ul.in').collapse('hide'); 32 | } 33 | }); 34 | } 35 | }; 36 | 37 | $.fn[ pluginName ] = function (options) { 38 | return this.each(function () { 39 | if (!$.data(this, "plugin_" + pluginName)) { 40 | $.data(this, "plugin_" + pluginName, new Plugin(this, options)); 41 | } 42 | }); 43 | }; 44 | 45 | })(jQuery, window, document); 46 | -------------------------------------------------------------------------------- /wwwroot/assets/js/sb-admin.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | $('#side-menu').metisMenu(); 4 | 5 | }); 6 | 7 | //Loads the correct sidebar on window load, 8 | //collapses the sidebar on window resize. 9 | $(function() { 10 | $(window).bind("load resize", function() { 11 | if ($(this).width() < 768) { 12 | $('div.sidebar-collapse').addClass('collapse') 13 | } else { 14 | $('div.sidebar-collapse').removeClass('collapse') 15 | } 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /wwwroot/assets/js/webclient/alert-manager.js: -------------------------------------------------------------------------------- 1 | 2 | // handles modal dialogs 3 | var alertManager = { 4 | 5 | showAlert : function(title,message,buttonText,onClose){ 6 | 7 | $('#modalAlertDialog #modalTitle').text(title); 8 | $('#modalAlertDialog #modalText').text(message); 9 | $('#modalAlertDialog #modalDismissButton').text(buttonText); 10 | 11 | $('#modalAlertDialog').modal('show'); 12 | $('#modalAlertDialog').unbind('hide.bs.modal'); 13 | $('#modalAlertDialog').on('hide.bs.modal', function (e) { 14 | onClose(); 15 | }) 16 | }, 17 | showError : function(message){ 18 | 19 | $('#modalAlertDialog #modalTitle').text(_lang.labelErrorDialogTitle); 20 | $('#modalAlertDialog #modalText').text(message); 21 | $('#modalAlertDialog #modalDismissButton').text(_lang.labelCloseButton); 22 | 23 | $('#modalAlertDialog').modal('show'); 24 | }, 25 | showLoading : function(){ 26 | $('#modalLoading').modal('show'); 27 | }, 28 | hideLoading : function(){ 29 | $('#modalLoading').modal('hide'); 30 | }, 31 | showPasswordDialog : function(onEnter,defaultValue){ 32 | 33 | $('#passwordInputDialog #modalDismissButton').text('OK'); 34 | $('#passwordInputDialog #modalTitle').text('Please input password'); 35 | 36 | if(_.isUndefined(defaultValue)){ 37 | $('#passwordField').val(''); 38 | }else{ 39 | $('#passwordField').val(defaultValue); 40 | } 41 | 42 | $('#passwordInputDialog').modal('show'); 43 | $('#passwordInputDialog').unbind('hide.bs.modal'); 44 | $('#passwordInputDialog').on('hide.bs.modal', function (e) { 45 | var password = $('#passwordField').val(); 46 | onEnter(password); 47 | }) 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /wwwroot/assets/js/webclient/file-uploader.js: -------------------------------------------------------------------------------- 1 | 2 | var fileUploadManager = { 3 | handleFileSelect : function(event){ 4 | 5 | event.preventDefault(); 6 | 7 | var files = event.dataTransfer.files; 8 | 9 | if(_.isUndefined(files)){ 10 | return; 11 | } 12 | 13 | var filesCount = files.length; 14 | 15 | if(filesCount > 1){ 16 | alertManager.showError(_lang.messageValidationErrorTooManyFiles); 17 | return; 18 | } 19 | 20 | var file = files[0]; 21 | var fileType = file.type; 22 | 23 | if(fileType != 'image/jpeg' && fileType != 'image/pjpeg' && fileType != 'video/mp4' && fileType != 'audio/mp3' && fileType != 'audio/mpeg'){ 24 | alertManager.showError(_lang.messageValidationErrorWrongFileType); 25 | return; 26 | } 27 | 28 | if(!_chatManager.isInConversation()){ 29 | return; 30 | } 31 | 32 | // upload 33 | $('#fileupload-box').css('display','none'); 34 | $('#fileuploading').css('display','block'); 35 | 36 | $('#btn-chat-send').attr('disabled','disabled'); 37 | 38 | 39 | if(fileType == 'image/jpeg' || fileType == 'image/pjpeg'){ 40 | _chatManager.sendMediaMessage(file,_spikaClient.MEDIA_TYPE_IMAGE,function(){ 41 | $('#fileupload-box').css('display','block'); 42 | $('#fileuploading').css('display','none'); 43 | }); 44 | } 45 | 46 | if(fileType == 'video/mp4'){ 47 | _chatManager.sendMediaMessage(file,_spikaClient.MEDIA_TYPE_VIDEO,function(){ 48 | $('#fileupload-box').css('display','block'); 49 | $('#fileuploading').css('display','none'); 50 | }); 51 | } 52 | 53 | if(fileType == 'audio/mp3' || fileType == 'audio/mpeg'){ 54 | _chatManager.sendMediaMessage(file,_spikaClient.MEDIA_TYPE_AUDIO,function(){ 55 | $('#fileupload-box').css('display','block'); 56 | $('#fileuploading').css('display','none'); 57 | }); 58 | } 59 | 60 | }, 61 | handleDragOver : function(event){ 62 | event.preventDefault(); 63 | $('#fileupload-box').css('border-color','#f88'); 64 | }, 65 | handleDragLeave : function(event){ 66 | event.preventDefault(); 67 | $('#fileupload-box').css('border-color','#888'); 68 | } 69 | }; -------------------------------------------------------------------------------- /wwwroot/assets/js/webclient/spika-client-app.js: -------------------------------------------------------------------------------- 1 | var _spikaApp = { 2 | 3 | initApp : function(){ 4 | 5 | alertManager.showLoading(); 6 | 7 | // login 8 | _spikaClient.login(_loginedUser.email,_loginedUser.password,function(data){ 9 | 10 | _loginedUser = data; 11 | _spikaClient.setCurrentUser(_loginedUser); 12 | 13 | windowManager.init(window); 14 | _chatManager.init(); 15 | mediaViewManager.init(); 16 | 17 | navigationBarManager.renderContacts(); 18 | navigationBarManager.renderGroups(); 19 | newMessageChecker.startUpdating(); 20 | 21 | if(_targetUserId != 0){ 22 | _chatManager.startPrivateChat(_targetUserId); 23 | }else if(_targetGroupId != 0){ 24 | _chatManager.startGroupChat(_targetGroupId); 25 | } 26 | 27 | },function(errorString){ 28 | 29 | alertManager.hideLoading(); 30 | _spikaApp.handleError(errorString,"login"); 31 | 32 | }); 33 | 34 | // file dropzone setup 35 | var dropZone = document.getElementById('fileupload-box'); 36 | dropZone.addEventListener('dragleave', fileUploadManager.handleDragLeave, false); 37 | dropZone.addEventListener('dragover', fileUploadManager.handleDragOver, false); 38 | dropZone.addEventListener('drop', fileUploadManager.handleFileSelect , false); 39 | 40 | }, 41 | showMediaView : function(messageId){ 42 | 43 | $('#chat-view').css('display','none'); 44 | $('#media-view').css('display','block'); 45 | 46 | $('#submenu .submenubutton').each(function(){ 47 | $(this).css('background-color','#f8f8f8'); 48 | }); 49 | 50 | $('#tab-media-view').css('background-color','#e7e7e7'); 51 | 52 | // allow scrolling 53 | $('#media-view').css('overflow-y','auto'); 54 | 55 | mediaViewManager.loadMedia(messageId); 56 | 57 | }, 58 | showChatView : function(){ 59 | 60 | $('#chat-view').css('display','block'); 61 | $('#media-view').css('display','none'); 62 | 63 | $('#submenu .submenubutton').each(function(){ 64 | $(this).css('background-color','#f8f8f8'); 65 | }); 66 | 67 | $('#tab-chat-view').css('background-color','#e7e7e7'); 68 | 69 | // disable scrolling 70 | $('#media-view').css('overflow-y','hidden'); 71 | 72 | }, 73 | handleError : function(response,from){ 74 | 75 | console.log( " error from " + from + " respnse " + response ); 76 | console.log(response ); 77 | 78 | // strting to object 79 | 80 | if(!_.isObject(response)) 81 | eval("var response = " + response); 82 | 83 | if(!_.isNull(response.error) && response.error == 'logout'){ 84 | 85 | alertManager.showAlert(_lang.labelErrorDialogTitle,_lang.messageTokenError,_lang.labelCloseButton,function(){ 86 | location.href = "login"; 87 | }); 88 | 89 | } else{ 90 | 91 | alertManager.showError(_lang.messageGeneralError); 92 | 93 | } 94 | } 95 | 96 | }; 97 | 98 | (function() { 99 | 100 | $(document).ready(function() { 101 | _spikaApp.initApp(); 102 | }); 103 | 104 | })(); 105 | -------------------------------------------------------------------------------- /wwwroot/assets/js/webclient/stickes-view.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | var stickerViewManager = { 4 | templateSticker : _.template('
  • '), 5 | sending : false, 6 | isLoaded : false, 7 | render : function(){ 8 | 9 | var self = this; 10 | 11 | if(this.isLoaded) 12 | return; 13 | 14 | _spikaClient.loadStickers(function(data){ 15 | 16 | if(!_.isArray(data.rows)) 17 | return; 18 | 19 | var html = ''; 20 | 21 | _.each(data.rows,function(row,key,list){ 22 | 23 | var value = row.value; 24 | 25 | if(_.isUndefined(value)) 26 | return; 27 | 28 | value.stickerUrl = _consts.RootURL + "/api/Emoticon/" + value._id; 29 | html += self.templateSticker(value); 30 | 31 | }); 32 | 33 | $('#sticker-holder').html(html); 34 | 35 | $('#sticker-holder').css('width',130 * data.rows.length); 36 | 37 | $('.sticker-view').click(function(){ 38 | 39 | if(!_chatManager.isInConversation()){ 40 | return; 41 | } 42 | 43 | var stickerIdentifier = $(this).attr('stickerId'); 44 | 45 | if(!_.isUndefined(stickerIdentifier)){ 46 | 47 | if(self.sending == true) 48 | return; 49 | 50 | self.sending = true; 51 | $('.sticker-view').css('cursor','progress'); 52 | 53 | _chatManager.sendSticker(stickerIdentifier,function(){ 54 | self.sending = false; 55 | $('.sticker-view').css('cursor','pointer'); 56 | }); 57 | 58 | $('#btn-chat-send').html(' Sending'); 59 | $('#btn-chat-send').attr('disabled','disabled'); 60 | 61 | } 62 | 63 | }); 64 | 65 | this.isLoaded = true; 66 | 67 | },function(errorString){ 68 | 69 | _spikaApp.handleError(errorString,"loadStickers"); 70 | }); 71 | 72 | } 73 | }; -------------------------------------------------------------------------------- /wwwroot/assets/js/webclient/window-manager.js: -------------------------------------------------------------------------------- 1 | // handles window ( mainly size change ) 2 | var windowManager = { 3 | 4 | init : function(window){ 5 | 6 | var self = this; 7 | $(window).resize(function() { 8 | self.onResize(); 9 | }); 10 | 11 | this.onResize(); 12 | 13 | }, 14 | onResize : function(){ 15 | var headerHeight = $('.navbar-static-top').outerHeight(); 16 | var chatboxHeight = $('#chat_block').outerHeight(); 17 | var submenuHeight = $('#submenu').outerHeight(); 18 | 19 | $('body').height(window.innerHeight); 20 | $('#main-view').height(window.innerHeight - headerHeight - submenuHeight); 21 | $('#media-view').height(window.innerHeight - headerHeight - submenuHeight); 22 | $('.sidebar-collapse .tab-content').height(window.innerHeight - headerHeight); 23 | $('#conversation_block').height(window.innerHeight - headerHeight - chatboxHeight - submenuHeight - 20); 24 | 25 | } 26 | 27 | }; 28 | -------------------------------------------------------------------------------- /wwwroot/index.php: -------------------------------------------------------------------------------- 1 | run(); 6 | --------------------------------------------------------------------------------