├── .editorconfig ├── .gitignore ├── .npmignore ├── .travis.yml ├── .tx └── config ├── Cakefile ├── LICENSE ├── README.md ├── build ├── client │ └── public │ │ ├── app-icons │ │ └── sprite-svg-data.css │ │ ├── favicon.ico │ │ ├── fonts │ │ ├── adobeblank.woff │ │ ├── fontawesome-webfont.woff │ │ ├── fontawesome-webfont.woff2 │ │ ├── fonts.css │ │ ├── mavenpro-bold.woff │ │ ├── mavenpro-bold.woff2 │ │ ├── mavenpro-regular.woff │ │ ├── mavenpro-regular.woff2 │ │ ├── sourcecodepro-bold.woff │ │ ├── sourcecodepro-regular.woff │ │ ├── sourcesanspro-bold-italic.woff │ │ ├── sourcesanspro-bold-italic.woff2 │ │ ├── sourcesanspro-bold.woff │ │ ├── sourcesanspro-bold.woff2 │ │ ├── sourcesanspro-italic.woff │ │ ├── sourcesanspro-italic.woff2 │ │ ├── sourcesanspro-regular.woff │ │ └── sourcesanspro-regular.woff2 │ │ ├── img │ │ ├── apps │ │ │ ├── account.svg │ │ │ ├── banks.svg │ │ │ ├── bookmarks.svg │ │ │ ├── calendar.svg │ │ │ ├── contacts.svg │ │ │ ├── cozic.svg │ │ │ ├── databrowser.svg │ │ │ ├── emails.svg │ │ │ ├── feeds.svg │ │ │ ├── files.svg │ │ │ ├── frost.svg │ │ │ ├── ghost.svg │ │ │ ├── hari.svg │ │ │ ├── hastebin.svg │ │ │ ├── help.svg │ │ │ ├── isen.png │ │ │ ├── isen.svg │ │ │ ├── konnectors.svg │ │ │ ├── kresus.svg │ │ │ ├── kyou.svg │ │ │ ├── leave-google.svg │ │ │ ├── maif.svg │ │ │ ├── map.svg │ │ │ ├── moimois.svg │ │ │ ├── mstsc.svg │ │ │ ├── music.svg │ │ │ ├── my-accounts.svg │ │ │ ├── my-apps.svg │ │ │ ├── nirc.svg │ │ │ ├── notes.svg │ │ │ ├── owm.svg │ │ │ ├── photos.svg │ │ │ ├── polybios.svg │ │ │ ├── remote_storage.svg │ │ │ ├── settings.svg │ │ │ ├── shout.svg │ │ │ ├── state.svg │ │ │ ├── store.svg │ │ │ ├── sync.svg │ │ │ ├── tasky.svg │ │ │ ├── term.svg │ │ │ ├── thelounge.svg │ │ │ ├── tiddlywiki.svg │ │ │ └── todos.svg │ │ ├── backgrounds │ │ │ ├── background_01.jpg │ │ │ ├── background_01_th.png │ │ │ ├── background_02.jpg │ │ │ ├── background_02_th.png │ │ │ ├── background_03.jpg │ │ │ ├── background_03_th.png │ │ │ ├── background_04.jpg │ │ │ ├── background_04_th.png │ │ │ ├── background_05.jpg │ │ │ ├── background_05_th.png │ │ │ ├── background_06.jpg │ │ │ ├── background_06_th.png │ │ │ ├── background_07.jpg │ │ │ ├── background_07_th.png │ │ │ ├── background_08.jpg │ │ │ ├── background_08_th.png │ │ │ └── background_none_th.png │ │ ├── broken.png │ │ ├── broken.svg │ │ ├── default.svg │ │ ├── en-play-badge.png │ │ ├── git-white.png │ │ ├── glyphicons-halflings-white.png │ │ ├── glyphicons-halflings.png │ │ ├── happycloud-black.png │ │ ├── happycloud-black.svg │ │ ├── happycloud-small.png │ │ ├── happycloud-white.svg │ │ ├── happycloud.png │ │ ├── link-white.png │ │ ├── link.png │ │ ├── linux.svg │ │ ├── logo-brand.png │ │ ├── marker.png │ │ ├── mask.png │ │ ├── qwant-logo.jpg │ │ ├── spinner-white-thin.svg │ │ ├── spinner-white.svg │ │ ├── spinner.svg │ │ ├── sprites │ │ │ └── sprite-home-icons.svg │ │ ├── star-white.png │ │ └── stopped.png │ │ ├── javascripts │ │ ├── app.js │ │ ├── app.js.map │ │ ├── vendor.js │ │ └── vendor.js.map │ │ ├── sounds │ │ └── notification.wav │ │ ├── stylesheets │ │ ├── app.css │ │ └── app.css.map │ │ └── test │ │ └── javascripts │ │ ├── test.js │ │ └── test.js.map ├── server.js └── server │ ├── config.js │ ├── controllers │ ├── account.js │ ├── album.js │ ├── applications.js │ ├── backgrounds.js │ ├── devices.js │ ├── file.js │ ├── help.js │ ├── index.js │ ├── logs.js │ ├── monitor.js │ ├── notifications.js │ ├── photo.js │ ├── proxy.js │ ├── routes.js │ ├── sharing.js │ ├── stack_application.js │ └── usetrackers.js │ ├── helpers │ ├── downloader.js │ ├── errors.js │ ├── localization_manager.js │ └── thumb.js │ ├── initializers │ ├── proxy.js │ ├── realtime.js │ └── updates.js │ ├── lib │ ├── adapter.js │ ├── alarm_manager.js │ ├── applications.js │ ├── autostop.js │ ├── git_providers.js │ ├── icon.js │ ├── logging.js │ ├── logs.js │ ├── manifest.js │ ├── market.js │ ├── memory.js │ ├── paas.js │ ├── passport_utils.js │ └── sharing_manager.js │ ├── locales │ ├── en.json │ └── fr.json │ ├── models │ ├── alarm.js │ ├── album.js │ ├── application.js │ ├── background.js │ ├── binary.js │ ├── cozyinstance.js │ ├── device.js │ ├── event.js │ ├── file.js │ ├── notification.js │ ├── photo.js │ ├── requests.js │ ├── sharing.js │ ├── stack_application.js │ ├── user.js │ └── usetracker.js │ └── views │ └── index.js ├── client ├── app │ ├── assets │ │ ├── app-icons │ │ │ └── sprite-svg-data.css │ │ ├── favicon.ico │ │ ├── fonts │ │ │ ├── adobeblank.woff │ │ │ ├── fontawesome-webfont.woff │ │ │ ├── fontawesome-webfont.woff2 │ │ │ ├── fonts.css │ │ │ ├── mavenpro-bold.woff │ │ │ ├── mavenpro-bold.woff2 │ │ │ ├── mavenpro-regular.woff │ │ │ ├── mavenpro-regular.woff2 │ │ │ ├── sourcecodepro-bold.woff │ │ │ ├── sourcecodepro-regular.woff │ │ │ ├── sourcesanspro-bold-italic.woff │ │ │ ├── sourcesanspro-bold-italic.woff2 │ │ │ ├── sourcesanspro-bold.woff │ │ │ ├── sourcesanspro-bold.woff2 │ │ │ ├── sourcesanspro-italic.woff │ │ │ ├── sourcesanspro-italic.woff2 │ │ │ ├── sourcesanspro-regular.woff │ │ │ └── sourcesanspro-regular.woff2 │ │ ├── img │ │ │ ├── apps │ │ │ │ ├── account.svg │ │ │ │ ├── banks.svg │ │ │ │ ├── bookmarks.svg │ │ │ │ ├── calendar.svg │ │ │ │ ├── contacts.svg │ │ │ │ ├── cozic.svg │ │ │ │ ├── databrowser.svg │ │ │ │ ├── emails.svg │ │ │ │ ├── feeds.svg │ │ │ │ ├── files.svg │ │ │ │ ├── frost.svg │ │ │ │ ├── ghost.svg │ │ │ │ ├── hari.svg │ │ │ │ ├── hastebin.svg │ │ │ │ ├── isen.png │ │ │ │ ├── isen.svg │ │ │ │ ├── kresus.svg │ │ │ │ ├── kyou.svg │ │ │ │ ├── leave-google.svg │ │ │ │ ├── maif.svg │ │ │ │ ├── map.svg │ │ │ │ ├── moimois.svg │ │ │ │ ├── mstsc.svg │ │ │ │ ├── music.svg │ │ │ │ ├── my-accounts.svg │ │ │ │ ├── my-apps.svg │ │ │ │ ├── nirc.svg │ │ │ │ ├── notes.svg │ │ │ │ ├── owm.svg │ │ │ │ ├── photos.svg │ │ │ │ ├── polybios.svg │ │ │ │ ├── remote_storage.svg │ │ │ │ ├── settings.svg │ │ │ │ ├── state.svg │ │ │ │ ├── store.svg │ │ │ │ ├── sync.svg │ │ │ │ ├── tasky.svg │ │ │ │ ├── term.svg │ │ │ │ ├── thelounge.svg │ │ │ │ ├── tiddlywiki.svg │ │ │ │ └── todos.svg │ │ │ ├── backgrounds │ │ │ │ ├── background_01.jpg │ │ │ │ ├── background_01_th.png │ │ │ │ ├── background_02.jpg │ │ │ │ ├── background_02_th.png │ │ │ │ ├── background_03.jpg │ │ │ │ ├── background_03_th.png │ │ │ │ ├── background_04.jpg │ │ │ │ ├── background_04_th.png │ │ │ │ ├── background_05.jpg │ │ │ │ ├── background_05_th.png │ │ │ │ ├── background_06.jpg │ │ │ │ ├── background_06_th.png │ │ │ │ ├── background_07.jpg │ │ │ │ ├── background_07_th.png │ │ │ │ ├── background_08.jpg │ │ │ │ ├── background_08_th.png │ │ │ │ └── background_none_th.png │ │ │ ├── broken.png │ │ │ ├── broken.svg │ │ │ ├── default.svg │ │ │ ├── en-play-badge.png │ │ │ ├── git-white.png │ │ │ ├── glyphicons-halflings-white.png │ │ │ ├── glyphicons-halflings.png │ │ │ ├── happycloud-black.png │ │ │ ├── happycloud-black.svg │ │ │ ├── happycloud-small.png │ │ │ ├── happycloud-white.svg │ │ │ ├── happycloud.png │ │ │ ├── link-white.png │ │ │ ├── link.png │ │ │ ├── linux.svg │ │ │ ├── logo-brand.png │ │ │ ├── marker.png │ │ │ ├── mask.png │ │ │ ├── qwant-logo.jpg │ │ │ ├── spinner-white-thin.svg │ │ │ ├── spinner-white.svg │ │ │ ├── spinner.svg │ │ │ ├── sprites │ │ │ │ └── sprite-home-icons.svg │ │ │ ├── star-white.png │ │ │ └── stopped.png │ │ └── sounds │ │ │ └── notification.wav │ ├── collections │ │ ├── application.coffee │ │ ├── background.coffee │ │ ├── device.coffee │ │ ├── notifications.coffee │ │ └── stackApplication.coffee │ ├── helpers │ │ ├── client.coffee │ │ ├── color-set.coffee │ │ ├── locales.coffee │ │ ├── slugify.coffee │ │ └── timezone.coffee │ ├── initialize.coffee │ ├── lib │ │ ├── base_collection.coffee │ │ ├── base_model.coffee │ │ ├── base_view.coffee │ │ ├── intent_manager.coffee │ │ ├── proxyclient.coffee │ │ ├── request.coffee │ │ ├── socket_listener.coffee │ │ ├── usetracker.coffee │ │ └── view_collection.coffee │ ├── locales │ │ └── en.json │ ├── models │ │ ├── application.coffee │ │ ├── background.coffee │ │ ├── device.coffee │ │ ├── instance.coffee │ │ ├── notification.coffee │ │ ├── photo.coffee │ │ ├── stack_application.coffee │ │ ├── token.coffee │ │ └── user.coffee │ ├── routers │ │ └── main_router.coffee │ ├── styles │ │ ├── base │ │ │ ├── _alerts.styl │ │ │ ├── _buttons.styl │ │ │ ├── _colors.styl │ │ │ ├── _form.styl │ │ │ ├── _grid.styl │ │ │ ├── _icons.styl │ │ │ └── _reset.styl │ │ ├── components │ │ │ ├── _desktop.styl │ │ │ ├── _help.styl │ │ │ ├── _modal.styl │ │ │ ├── _notifications.styl │ │ │ ├── _object-picker.styl │ │ │ ├── _settings.styl │ │ │ ├── _status.styl │ │ │ └── _store.styl │ │ └── main.styl │ ├── templates │ │ ├── account.jade │ │ ├── album_thumb.jade │ │ ├── application_iframe.jade │ │ ├── background_list.jade │ │ ├── background_list_item.jade │ │ ├── config_application.jade │ │ ├── config_application_list.jade │ │ ├── config_applications.jade │ │ ├── config_device.jade │ │ ├── config_device_list.jade │ │ ├── error_modal.jade │ │ ├── help.jade │ │ ├── help_url.jade │ │ ├── home.jade │ │ ├── home_application.jade │ │ ├── layout.jade │ │ ├── long_list_image.jade │ │ ├── market.jade │ │ ├── market_application.jade │ │ ├── menu_application.jade │ │ ├── menu_applications.jade │ │ ├── navbar.jade │ │ ├── navbar_app_btn.jade │ │ ├── notification.jade │ │ ├── notifications.jade │ │ ├── object_picker.jade │ │ ├── object_picker_photourl.jade │ │ ├── object_picker_search.jade │ │ ├── object_picker_upload.jade │ │ ├── popover_description.jade │ │ ├── popover_permissions.jade │ │ ├── tutorial.jade │ │ └── update_stack_modal.jade │ ├── views │ │ ├── account.coffee │ │ ├── background_list.coffee │ │ ├── background_list_item.coffee │ │ ├── config_application.coffee │ │ ├── config_application_list.coffee │ │ ├── config_applications.coffee │ │ ├── config_device.coffee │ │ ├── config_device_list.coffee │ │ ├── error_modal.coffee │ │ ├── help.coffee │ │ ├── home.coffee │ │ ├── home_application.coffee │ │ ├── image_list.coffee │ │ ├── main.coffee │ │ ├── market.coffee │ │ ├── market_application.coffee │ │ ├── menu_application.coffee │ │ ├── menu_applications.coffee │ │ ├── modal.coffee │ │ ├── navbar.coffee │ │ ├── notification_view.coffee │ │ ├── notifications_view.coffee │ │ ├── object_picker.coffee │ │ ├── object_picker_album.coffee │ │ ├── object_picker_image.coffee │ │ ├── object_picker_photourl.coffee │ │ ├── object_picker_search.coffee │ │ ├── object_picker_upload.coffee │ │ ├── popover_description.coffee │ │ ├── search_bar_mix.coffee │ │ ├── tab_controller.coffee │ │ └── update_stack_modal.coffee │ └── widgets │ │ └── install_button.coffee ├── config.coffee ├── package.json ├── test-functional │ ├── account.coffee │ ├── helpers.coffee │ ├── login.coffee │ └── register.coffee ├── test │ ├── application_collection_test.coffee │ ├── application_view_test.coffee │ ├── home_view_test.coffee │ └── test-helpers.coffee └── vendor │ ├── scripts │ ├── backbone-1.0.0.js │ ├── backbone-mediator.js │ ├── bootstrap-editable-inline.min.js │ ├── bootstrap.js │ ├── color-hash.js │ ├── console-helper.js │ ├── cozy-realtime.js │ ├── expect.js │ ├── farbtastic.js │ ├── jquery-1.7.1.js │ ├── jquery-hashchange.js │ ├── jquery-ui-1.10.3.custom.js │ ├── jquery.Jcrop.min-0.9.12.js │ ├── jquery.nicescroll.js │ ├── mocha.js │ ├── moment-with-locales.min.2.10.2.js │ ├── polyglot.js │ ├── qr.min.js │ ├── socket.io.js │ ├── sonic.js │ ├── spinner.js │ ├── talkerjs-1.0.1.js │ ├── typeahead.bundle.js │ └── underscore-1.4.4.js │ └── styles │ ├── farbtastic.css │ ├── jquery.Jcrop.min.css │ ├── jquery.gridster.css │ ├── knacss.css │ ├── nanoscroller.css │ └── resizable.css ├── coffeelint.json ├── commands.coffee ├── doc └── 2fa.md ├── init.coffee ├── log └── .gitkeep ├── package.json ├── postinstall.js ├── server.coffee ├── server ├── config.coffee ├── controllers │ ├── account.coffee │ ├── album.coffee │ ├── applications.coffee │ ├── backgrounds.coffee │ ├── devices.coffee │ ├── file.coffee │ ├── help.coffee │ ├── index.coffee │ ├── logs.coffee │ ├── monitor.coffee │ ├── notifications.coffee │ ├── photo.coffee │ ├── proxy.coffee │ ├── routes.coffee │ ├── sharing.coffee │ ├── stack_application.coffee │ └── usetrackers.coffee ├── helpers │ ├── downloader.coffee │ ├── errors.coffee │ ├── localization_manager.coffee │ └── thumb.coffee ├── initializers │ ├── proxy.coffee │ ├── realtime.coffee │ └── updates.coffee ├── lib │ ├── adapter.coffee │ ├── alarm_manager.coffee │ ├── applications.coffee │ ├── autostop.coffee │ ├── git_providers.coffee │ ├── icon.coffee │ ├── logging.coffee │ ├── logs.coffee │ ├── manifest.coffee │ ├── market.coffee │ ├── memory.coffee │ ├── paas.coffee │ ├── passport_utils.coffee │ └── sharing_manager.coffee ├── locales │ └── en.json ├── models │ ├── alarm.coffee │ ├── album.coffee │ ├── application.coffee │ ├── background.coffee │ ├── binary.coffee │ ├── cozyinstance.coffee │ ├── device.coffee │ ├── event.coffee │ ├── file.coffee │ ├── notification.coffee │ ├── photo.coffee │ ├── requests.coffee │ ├── sharing.coffee │ ├── stack_application.coffee │ ├── user.coffee │ └── usetracker.coffee └── views │ └── index.jade └── test ├── account_tests.coffee ├── alarms_tests.coffee ├── applications_tests.coffee ├── autostop.coffee ├── fixtures └── notifications.json ├── helpers.coffee ├── lib ├── applications_tests.coffee ├── icon_tests.coffee └── market_tests.coffee ├── lib_manifest.coffee ├── monitor.coffee ├── notifications_tests.coffee ├── paas_tests.coffee ├── photo-set ├── package.json └── photo-generator.coffee └── update_initializer.coffee /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | # editorconfig is a unified configuration file that all editors can take 3 | # into account 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | end_of_line = lf 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | indent_style = space 12 | indent_size = 4 13 | 14 | [*.jade] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.swp 3 | *.log 4 | 5 | # the apps fetched from the registry 6 | market 7 | market.json 8 | 9 | # no need to track build twice 10 | client/public 11 | 12 | # iconizr stuff, could be probably be used / not-generated 13 | client/app/assets/app-icons/icons 14 | client/app/assets/app-icons/sprite-svg-sprite.css 15 | client/app/assets/app-icons/sprite-loader-fragment.html 16 | client/app/assets/app-icons/sprite-png-sprite.css 17 | client/app/assets/app-icons/sprite-png-data.css 18 | 19 | # keep only the source for transifex 20 | locales 21 | !locales/en.json 22 | 23 | test/photo-set/photo 24 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .tx 2 | test 3 | server 4 | !build/server 5 | client 6 | !build/client 7 | log 8 | server.coffee 9 | .editorconfig 10 | .travis.yml 11 | coffeelint.json 12 | Cakefile 13 | market 14 | market.json 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | matrix: 4 | fast_finish: true 5 | allow_failures: 6 | - node_js: "5" 7 | node_js: 8 | - "0.10" 9 | - "0.12" 10 | - "4" 11 | - "5" 12 | services: 13 | - couchdb 14 | env: 15 | global: 16 | - NODE_ENV=test 17 | - TOKEN=token 18 | - CXX=g++-4.8 19 | addons: 20 | apt: 21 | sources: 22 | - ubuntu-toolchain-r-test 23 | packages: 24 | - gcc-4.8 25 | - g++-4.8 26 | 27 | before_install: 28 | - travis_retry git clone git://github.com/cozy/cozy-data-system.git 29 | - travis_retry npm install npm@latest-2 -g 30 | - cd cozy-data-system 31 | - travis_retry npm install forever coffee-script -g 32 | - travis_retry npm install 33 | - pwd 34 | - NAME=data-system forever start -o forever-ds.log -e forever-ds-err.log build/server.js 35 | - sleep 5 36 | - ps aux | grep server.js 37 | - curl http://localhost:9101/ 38 | - cat forever-ds.log 39 | - cd .. 40 | - export NAME=home 41 | 42 | script: 43 | - npm run build 44 | - npm run test 45 | 46 | after_failure: 47 | - cat cozy-data-system/forever-ds.log 48 | - cat cozy-data-system/forever-ds-err.log 49 | - curl http://localhost:9101/ 50 | -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | 4 | [cozy-home.enjson] 5 | file_filter = client/app/locales/.json 6 | source_file = client/app/locales/en.json 7 | source_lang = en 8 | type = KEYVALUEJSON 9 | 10 | [cozy-home.server-enjson] 11 | file_filter = server/locales/.json 12 | source_file = server/locales/en.json 13 | source_lang = en 14 | type = KEYVALUEJSON -------------------------------------------------------------------------------- /build/client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/favicon.ico -------------------------------------------------------------------------------- /build/client/public/fonts/adobeblank.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/adobeblank.woff -------------------------------------------------------------------------------- /build/client/public/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /build/client/public/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /build/client/public/fonts/mavenpro-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/mavenpro-bold.woff -------------------------------------------------------------------------------- /build/client/public/fonts/mavenpro-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/mavenpro-bold.woff2 -------------------------------------------------------------------------------- /build/client/public/fonts/mavenpro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/mavenpro-regular.woff -------------------------------------------------------------------------------- /build/client/public/fonts/mavenpro-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/mavenpro-regular.woff2 -------------------------------------------------------------------------------- /build/client/public/fonts/sourcecodepro-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcecodepro-bold.woff -------------------------------------------------------------------------------- /build/client/public/fonts/sourcecodepro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcecodepro-regular.woff -------------------------------------------------------------------------------- /build/client/public/fonts/sourcesanspro-bold-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcesanspro-bold-italic.woff -------------------------------------------------------------------------------- /build/client/public/fonts/sourcesanspro-bold-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcesanspro-bold-italic.woff2 -------------------------------------------------------------------------------- /build/client/public/fonts/sourcesanspro-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcesanspro-bold.woff -------------------------------------------------------------------------------- /build/client/public/fonts/sourcesanspro-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcesanspro-bold.woff2 -------------------------------------------------------------------------------- /build/client/public/fonts/sourcesanspro-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcesanspro-italic.woff -------------------------------------------------------------------------------- /build/client/public/fonts/sourcesanspro-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcesanspro-italic.woff2 -------------------------------------------------------------------------------- /build/client/public/fonts/sourcesanspro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcesanspro-regular.woff -------------------------------------------------------------------------------- /build/client/public/fonts/sourcesanspro-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/fonts/sourcesanspro-regular.woff2 -------------------------------------------------------------------------------- /build/client/public/img/apps/account.svg: -------------------------------------------------------------------------------- 1 | icon-account 2 | -------------------------------------------------------------------------------- /build/client/public/img/apps/files.svg: -------------------------------------------------------------------------------- 1 | filesCreated with Sketch. -------------------------------------------------------------------------------- /build/client/public/img/apps/hastebin.svg: -------------------------------------------------------------------------------- 1 | hastebinCreated with Sketch. -------------------------------------------------------------------------------- /build/client/public/img/apps/isen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/apps/isen.png -------------------------------------------------------------------------------- /build/client/public/img/apps/isen.svg: -------------------------------------------------------------------------------- 1 | isenCreated with Sketch. -------------------------------------------------------------------------------- /build/client/public/img/apps/leave-google.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /build/client/public/img/apps/maif.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /build/client/public/img/apps/music.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /build/client/public/img/apps/my-accounts.svg: -------------------------------------------------------------------------------- 1 | icon-account -------------------------------------------------------------------------------- /build/client/public/img/apps/my-apps.svg: -------------------------------------------------------------------------------- 1 | icon-monitor -------------------------------------------------------------------------------- /build/client/public/img/apps/notes.svg: -------------------------------------------------------------------------------- 1 | notesCreated with Sketch. -------------------------------------------------------------------------------- /build/client/public/img/apps/photos.svg: -------------------------------------------------------------------------------- 1 | photosCreated with Sketch. -------------------------------------------------------------------------------- /build/client/public/img/apps/remote_storage.svg: -------------------------------------------------------------------------------- 1 | remote_storageCreated with Sketch. -------------------------------------------------------------------------------- /build/client/public/img/apps/shout.svg: -------------------------------------------------------------------------------- 1 | shout IRCCreated with Sketch. -------------------------------------------------------------------------------- /build/client/public/img/apps/store.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /build/client/public/img/apps/tasky.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tasky 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /build/client/public/img/apps/term.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | term 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /build/client/public/img/apps/todos.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | todos 8 | Created with Sketch. 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_01.jpg -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_01_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_01_th.png -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_02.jpg -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_02_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_02_th.png -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_03.jpg -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_03_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_03_th.png -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_04.jpg -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_04_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_04_th.png -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_05.jpg -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_05_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_05_th.png -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_06.jpg -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_06_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_06_th.png -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_07.jpg -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_07_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_07_th.png -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_08.jpg -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_08_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_08_th.png -------------------------------------------------------------------------------- /build/client/public/img/backgrounds/background_none_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/backgrounds/background_none_th.png -------------------------------------------------------------------------------- /build/client/public/img/broken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/broken.png -------------------------------------------------------------------------------- /build/client/public/img/broken.svg: -------------------------------------------------------------------------------- 1 | brokenCreated with Sketch. -------------------------------------------------------------------------------- /build/client/public/img/default.svg: -------------------------------------------------------------------------------- 1 | cozy-defaultCreated with Sketch. -------------------------------------------------------------------------------- /build/client/public/img/en-play-badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/en-play-badge.png -------------------------------------------------------------------------------- /build/client/public/img/git-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/git-white.png -------------------------------------------------------------------------------- /build/client/public/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /build/client/public/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /build/client/public/img/happycloud-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/happycloud-black.png -------------------------------------------------------------------------------- /build/client/public/img/happycloud-black.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /build/client/public/img/happycloud-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/happycloud-small.png -------------------------------------------------------------------------------- /build/client/public/img/happycloud-white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /build/client/public/img/happycloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/happycloud.png -------------------------------------------------------------------------------- /build/client/public/img/link-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/link-white.png -------------------------------------------------------------------------------- /build/client/public/img/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/link.png -------------------------------------------------------------------------------- /build/client/public/img/logo-brand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/logo-brand.png -------------------------------------------------------------------------------- /build/client/public/img/marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/marker.png -------------------------------------------------------------------------------- /build/client/public/img/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/mask.png -------------------------------------------------------------------------------- /build/client/public/img/qwant-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/qwant-logo.jpg -------------------------------------------------------------------------------- /build/client/public/img/spinner-white-thin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /build/client/public/img/spinner-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /build/client/public/img/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /build/client/public/img/star-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/star-white.png -------------------------------------------------------------------------------- /build/client/public/img/stopped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/img/stopped.png -------------------------------------------------------------------------------- /build/client/public/sounds/notification.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/build/client/public/sounds/notification.wav -------------------------------------------------------------------------------- /build/server.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var application; 3 | 4 | process.on('uncaughtException', function(err) { 5 | console.error(err); 6 | return console.error(err.stack); 7 | }); 8 | 9 | application = module.exports = function(callback) { 10 | var americano, autoStop, initProxy, localization, options, request, setupRealtime, versionChecking; 11 | americano = require('americano'); 12 | request = require('request-json'); 13 | localization = require('./server/helpers/localization_manager'); 14 | initProxy = require('./server/initializers/proxy'); 15 | setupRealtime = require('./server/initializers/realtime'); 16 | versionChecking = require('./server/initializers/updates'); 17 | autoStop = require('./server/lib/autostop'); 18 | options = { 19 | name: 'Cozy Home', 20 | port: process.env.PORT || 9103, 21 | host: process.env.HOST || "127.0.0.1", 22 | root: __dirname 23 | }; 24 | return americano.start(options, function(err, app, server) { 25 | app.server = server; 26 | if (process.env.NODE_ENV !== "test") { 27 | initProxy(); 28 | } 29 | return localization.initialize(function() { 30 | return setupRealtime(app, function() { 31 | versionChecking(); 32 | autoStop.init(); 33 | if (callback != null) { 34 | return callback(app, server); 35 | } 36 | }); 37 | }); 38 | }); 39 | }; 40 | 41 | if (!module.parent) { 42 | application(); 43 | } 44 | -------------------------------------------------------------------------------- /build/server/config.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var americano, clientPath, config, fs, path, useBuildView; 3 | 4 | americano = require('americano'); 5 | 6 | fs = require('fs'); 7 | 8 | path = require('path'); 9 | 10 | clientPath = path.resolve(__dirname, '..', 'client', 'public'); 11 | 12 | useBuildView = fs.existsSync(path.resolve(__dirname, 'views', 'index.js')); 13 | 14 | config = { 15 | common: { 16 | set: { 17 | 'view engine': useBuildView ? 'js' : 'jade', 18 | 'views': path.resolve(__dirname, 'views') 19 | }, 20 | engine: { 21 | js: function(path, locales, callback) { 22 | return callback(null, require(path)(locales)); 23 | } 24 | }, 25 | use: [ 26 | americano.bodyParser(), americano.methodOverride(), americano.errorHandler({ 27 | dumpExceptions: true, 28 | showStack: true 29 | }), americano["static"](clientPath, { 30 | maxAge: 86400000 31 | }) 32 | ] 33 | }, 34 | development: [americano.logger('dev')], 35 | production: [americano.logger('short')], 36 | plugins: ['cozydb'] 37 | }; 38 | 39 | module.exports = config; 40 | -------------------------------------------------------------------------------- /build/server/controllers/album.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Album, NotAllowed, NotFound, Photo, async, log, ref, sharing; 3 | 4 | async = require('async'); 5 | 6 | Album = require('../models/album'); 7 | 8 | Photo = require('../models/photo'); 9 | 10 | sharing = require('./sharing'); 11 | 12 | ref = require('../helpers/errors'), NotFound = ref.NotFound, NotAllowed = ref.NotAllowed; 13 | 14 | log = require('printit')({ 15 | date: false, 16 | prefix: "album" 17 | }); 18 | 19 | module.exports.fetch = function(req, res, next, id) { 20 | return Album.find(id, function(err, album) { 21 | if (err) { 22 | return next(err); 23 | } else if (!album) { 24 | return next(NotFound("Album " + id)); 25 | } else { 26 | req.album = album; 27 | return next(); 28 | } 29 | }); 30 | }; 31 | 32 | module.exports.list = function(req, res, next) { 33 | return Album.listWithThumbs(function(err, albums) { 34 | if (err) { 35 | return next(err); 36 | } 37 | return res.send(albums); 38 | }); 39 | }; 40 | 41 | module.exports.read = function(req, res, next) { 42 | return sharing.checkPermissions(req.album, req, function(err, isAllowed) { 43 | if (!isAllowed) { 44 | return next(NotAllowed()); 45 | } else { 46 | return Photo.fromAlbum(req.album, function(err, photos) { 47 | var out; 48 | if (err) { 49 | return next(err); 50 | } 51 | out = req.album.toObject(); 52 | out.photos = photos; 53 | return res.send(out); 54 | }); 55 | } 56 | }); 57 | }; 58 | -------------------------------------------------------------------------------- /build/server/controllers/backgrounds.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Background, baseController, cozydb, localizationManager, multiparty; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | multiparty = require('multiparty'); 7 | 8 | localizationManager = require('../helpers/localization_manager'); 9 | 10 | Background = require('../models/background'); 11 | 12 | baseController = new cozydb.SimpleController({ 13 | model: Background, 14 | reqParamID: 'backgroundid' 15 | }); 16 | 17 | module.exports = { 18 | fetch: baseController.fetch, 19 | all: baseController.listAll, 20 | "delete": baseController.destroy, 21 | picture: baseController.sendBinary({ 22 | filename: 'file' 23 | }), 24 | thumb: baseController.sendBinary({ 25 | filename: 'thumb' 26 | }), 27 | create: function(req, res, next) { 28 | var form; 29 | res.on('close', function() { 30 | return req.abort(); 31 | }); 32 | form = new multiparty.Form(); 33 | return form.parse(req, function(err, fields, files) { 34 | var file; 35 | if (err) { 36 | return next(err); 37 | } else if ((files != null) && (files.picture != null) && files.picture.length > 0) { 38 | file = files.picture[0]; 39 | return Background.createNew(file.path, function(err, background) { 40 | if (err) { 41 | return next(err); 42 | } 43 | return res.send(background); 44 | }); 45 | } else { 46 | return next(new Error(localizationManager.t('cant change background'))); 47 | } 48 | }); 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /build/server/controllers/devices.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Client, Device, ds, fs, ref; 3 | 4 | Client = require("request-json").JsonClient; 5 | 6 | fs = require('fs'); 7 | 8 | Device = require('../models/device'); 9 | 10 | ds = new Client("http://localhost:9101/"); 11 | 12 | if ((ref = process.env.NODE_ENV) === 'test' || ref === 'production') { 13 | ds.setBasicAuth(process.env.NAME, process.env.TOKEN); 14 | } 15 | 16 | module.exports = { 17 | devices: function(req, res, next) { 18 | return Device.all(function(err, devices) { 19 | if (err) { 20 | return next(err); 21 | } else { 22 | return res.send({ 23 | rows: devices 24 | }); 25 | } 26 | }); 27 | }, 28 | remove: function(req, res, next) { 29 | var id; 30 | id = req.params.deviceid; 31 | return Device.find(id, function(err, device) { 32 | if (err != null) { 33 | return next(err); 34 | } else { 35 | return ds.del("access/" + id + "/", function(err, response, body) { 36 | if (err) { 37 | log.error(err); 38 | } 39 | return device.destroy(function(err) { 40 | err = err || body.error; 41 | if (err != null) { 42 | return next(err); 43 | } else { 44 | return res.status(200).send({ 45 | success: true 46 | }); 47 | } 48 | }); 49 | }); 50 | } 51 | }); 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /build/server/controllers/logs.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var fs, localizationManager, log, logs; 3 | 4 | fs = require('fs'); 5 | 6 | logs = require('../lib/logs'); 7 | 8 | log = require('printit')({ 9 | prefix: 'home:client' 10 | }); 11 | 12 | localizationManager = require('../helpers/localization_manager'); 13 | 14 | module.exports = { 15 | logs: function(req, res, next) { 16 | var filepath; 17 | filepath = logs.getLogPath(req.params.moduleslug); 18 | return fs.exists(filepath, function(exists) { 19 | var stream; 20 | if (exists) { 21 | stream = fs.createReadStream("" + filepath); 22 | res.set({ 23 | 'Content-Type': 'text/plain' 24 | }); 25 | stream.on('data', function(data) { 26 | return res.write(data.toString().replace(logs.colors, '')); 27 | }); 28 | return stream.on('end', function() { 29 | return res.end(); 30 | }); 31 | } else { 32 | return res.status(404).send(localizationManager.t('file not found')); 33 | } 34 | }); 35 | }, 36 | logClient: function(req, res) { 37 | var ref; 38 | log.error(req.body.data); 39 | log.error((ref = req.body.data.error) != null ? ref.stack : void 0); 40 | return res.send('ok'); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /build/server/controllers/monitor.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var MemoryManager; 3 | 4 | MemoryManager = require('../lib/memory').MemoryManager; 5 | 6 | module.exports = { 7 | sysData: function(req, res, next) { 8 | var memoryManager; 9 | memoryManager = new MemoryManager(); 10 | return memoryManager.getDiskInfos(function(err, diskInfos) { 11 | if (err) { 12 | return next(err); 13 | } else { 14 | return memoryManager.getMemoryInfos(function(err, memoryInfos) { 15 | var data, prop, value; 16 | if (err) { 17 | return next(err); 18 | } else { 19 | data = diskInfos; 20 | for (prop in memoryInfos) { 21 | value = memoryInfos[prop]; 22 | data[prop] = value; 23 | } 24 | return res.send(data); 25 | } 26 | }); 27 | } 28 | }); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /build/server/controllers/proxy.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var request; 3 | 4 | request = require('request'); 5 | 6 | module.exports.get = function(req, res) { 7 | return req.pipe(request(req.query.url)).pipe(res); 8 | }; 9 | -------------------------------------------------------------------------------- /build/server/controllers/usetrackers.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | 3 | /* 4 | App usage tracking 5 | */ 6 | var TIMING, UseTracker, appTracker, moment; 7 | 8 | moment = require('moment-timezone'); 9 | 10 | UseTracker = require('../models/usetracker'); 11 | 12 | TIMING = 10 * 1000; 13 | 14 | appTracker = {}; 15 | 16 | module.exports = { 17 | heartbeat: function(req, res, next) { 18 | var appInfo, appName; 19 | appName = req.body.appName; 20 | if (appTracker[appName] == null) { 21 | appTracker[appName] = { 22 | dateStart: req.body.timestamp, 23 | dateEnd: null, 24 | timeout: null 25 | }; 26 | } 27 | appInfo = appTracker[appName]; 28 | appInfo.dateEnd = req.body.timestamp; 29 | clearTimeout(appInfo.timeout); 30 | appInfo.timeout = setTimeout(function() { 31 | var data, duration; 32 | duration = moment(appInfo.dateEnd) - moment(appInfo.dateStart); 33 | duration = Math.round(duration / 1000) * 1000; 34 | data = { 35 | app: appName, 36 | dateStart: appInfo.dateStart, 37 | dateEnd: appInfo.dateEnd, 38 | duration: duration 39 | }; 40 | delete appTracker[appName]; 41 | return UseTracker.create(data, function(err, res, body) { 42 | if (err != null) { 43 | return console.log("Couldn't add app tracking info -- " + err); 44 | } 45 | }); 46 | }, TIMING); 47 | return res.status(201).send('ok'); 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /build/server/helpers/downloader.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var http; 3 | 4 | http = require('http'); 5 | 6 | module.exports = { 7 | download: function(path, callback) { 8 | var basic, id, options, pwd; 9 | id = process.env.NAME; 10 | pwd = process.env.TOKEN; 11 | basic = "Basic " + (new Buffer(id + ":" + pwd).toString('base64')); 12 | options = { 13 | host: 'localhost', 14 | port: 9101, 15 | path: path, 16 | headers: { 17 | Authorization: basic 18 | } 19 | }; 20 | return http.get(options, callback); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /build/server/helpers/errors.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | module.exports.NotFound = function(what) { 3 | var err; 4 | err = new Error(what + ': Not Found'); 5 | err.status = 404; 6 | return err; 7 | }; 8 | 9 | module.exports.NotAllowed = function() { 10 | var err; 11 | err = new Error('Not allowed'); 12 | err.status = 401; 13 | return err; 14 | }; 15 | 16 | module.exports.BadUsage = function() { 17 | var err; 18 | err = new Error('Bad Usage'); 19 | err.status = 400; 20 | return err; 21 | }; 22 | -------------------------------------------------------------------------------- /build/server/helpers/thumb.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var fs, im, resize; 3 | 4 | fs = require('fs'); 5 | 6 | im = require('imagemagick'); 7 | 8 | resize = function(raw, file, name, callback) { 9 | var options; 10 | options = { 11 | mode: 'crop', 12 | width: 300, 13 | height: 300 14 | }; 15 | options.srcPath = raw; 16 | options.dstPath = "/tmp/2-" + file.name; 17 | fs.openSync(options.dstPath, 'w'); 18 | return im[options.mode](options, function(err, stdout, stderr) { 19 | if (err) { 20 | return callback(err); 21 | } 22 | return file.attachBinary(options.dstPath, { 23 | name: name 24 | }, function(err) { 25 | return fs.unlink(options.dstPath, function() { 26 | return callback(err); 27 | }); 28 | }); 29 | }); 30 | }; 31 | 32 | module.exports.create = function(file, callback) { 33 | var rawFile, ref; 34 | if (file.binary == null) { 35 | return callback(new Error('no binary')); 36 | } 37 | if (((ref = file.binary) != null ? ref.thumb : void 0) != null) { 38 | console.log("createThumb " + file.id + " : already done"); 39 | return callback(); 40 | } else { 41 | rawFile = "/tmp/" + file.name; 42 | return fs.open(rawFile, 'w', function(err) { 43 | var stream; 44 | stream = file.getBinary('file', function(err) { 45 | if (err) { 46 | return callback(err); 47 | } 48 | }); 49 | stream.pipe(fs.createWriteStream(rawFile)); 50 | stream.on('error', callback); 51 | return stream.on('end', function() { 52 | return resize(rawFile, file, 'thumb', function(err) { 53 | return fs.unlink(rawFile, function() { 54 | console.log("createThumb " + file.id + " : done"); 55 | return callback(err); 56 | }); 57 | }); 58 | }); 59 | }); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /build/server/lib/adapter.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Adapter, client, request; 3 | 4 | request = require("request-json"); 5 | 6 | client = request.createClient("http://localhost:9101/"); 7 | 8 | module.exports = Adapter = (function() { 9 | function Adapter() {} 10 | 11 | Adapter.prototype.updateKeys = function(pwd, callback) { 12 | var name, ref, token; 13 | if ((ref = process.env.NODE_ENV) === 'production' || ref === 'test') { 14 | name = process.env.NAME; 15 | token = process.env.TOKEN; 16 | client.setBasicAuth(name, token); 17 | } 18 | return client.put("accounts/password/", { 19 | password: pwd 20 | }, function(err, res, body) { 21 | return callback(err); 22 | }); 23 | }; 24 | 25 | Adapter.prototype.initializeKeys = function(pwd, callback) { 26 | var name, ref, token; 27 | if ((ref = process.env.NODE_ENV) === 'production' || ref === 'test') { 28 | name = process.env.NAME; 29 | token = process.env.TOKEN; 30 | client.setBasicAuth(name, token); 31 | } 32 | return client.post("accounts/password/", { 33 | password: pwd 34 | }, function(err, res, body) { 35 | return callback(err); 36 | }); 37 | }; 38 | 39 | Adapter.prototype.updateUser = function(user, data, callback) { 40 | var name, ref, token; 41 | if ((ref = process.env.NODE_ENV) === 'production' || ref === 'test') { 42 | name = process.env.NAME; 43 | token = process.env.TOKEN; 44 | client.setBasicAuth(name, token); 45 | } 46 | return client.put("user/merge/" + user.id, data, function(err, res, body) { 47 | return callback(err); 48 | }); 49 | }; 50 | 51 | return Adapter; 52 | 53 | })(); 54 | -------------------------------------------------------------------------------- /build/server/lib/logging.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var fs, path; 3 | 4 | fs = require('fs'); 5 | 6 | path = require('path'); 7 | 8 | exports.stream = null; 9 | 10 | exports.init = function(compound, callback) { 11 | var app, logDir, logFile; 12 | app = compound.app; 13 | logDir = path.join(compound.root, 'log'); 14 | logFile = path.join(logDir, app.get('env') + '.log'); 15 | return fs.exists(logDir, function(exists) { 16 | var options; 17 | if (exists) { 18 | options = { 19 | flags: 'a', 20 | mode: 0x1b6, 21 | encoding: 'utf8' 22 | }; 23 | exports.stream = fs.createWriteStream(logFile, options); 24 | return callback(exports.stream); 25 | } else { 26 | return callback(null); 27 | } 28 | }); 29 | }; 30 | 31 | exports.write = function(text) { 32 | var stream; 33 | stream = exports.stream || process.stdout; 34 | return stream.write(text + '\n' || console.log(text)); 35 | }; 36 | -------------------------------------------------------------------------------- /build/server/lib/passport_utils.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var bcrypt; 3 | 4 | bcrypt = require('bcrypt'); 5 | 6 | exports.cryptPassword = function(password) { 7 | var hash, salt; 8 | salt = bcrypt.genSaltSync(10); 9 | hash = bcrypt.hashSync(password, salt); 10 | return hash; 11 | }; 12 | 13 | exports.checkPassword = function(password, hash) { 14 | return bcrypt.compareSync(password, hash); 15 | }; 16 | -------------------------------------------------------------------------------- /build/server/models/alarm.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Alarm, cozydb; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | module.exports = Alarm = cozydb.getModel('Alarm', { 7 | action: { 8 | type: String, 9 | "default": 'DISPLAY' 10 | }, 11 | trigg: String, 12 | rrule: String, 13 | timezone: String, 14 | description: String, 15 | related: { 16 | type: String, 17 | "default": null 18 | } 19 | }); 20 | 21 | Alarm.all = function(params, callback) { 22 | return Alarm.request("all", params, callback); 23 | }; 24 | -------------------------------------------------------------------------------- /build/server/models/binary.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Binary, cozydb; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | module.exports = Binary = cozydb.getModel('Binary', {}); 7 | -------------------------------------------------------------------------------- /build/server/models/cozyinstance.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var CozyInstance, cozydb; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | module.exports = CozyInstance = cozydb.getModel('CozyInstance', { 7 | domain: String, 8 | locale: String, 9 | helpUrl: String, 10 | background: String, 11 | connectedOnce: Boolean 12 | }); 13 | 14 | CozyInstance.first = function(callback) { 15 | return CozyInstance.request('all', function(err, instances) { 16 | if (err) { 17 | return callback(err); 18 | } else if (!instances || instances.length === 0) { 19 | return callback(null, null); 20 | } else { 21 | return callback(null, instances[0]); 22 | } 23 | }); 24 | }; 25 | 26 | CozyInstance.getLocale = function(callback) { 27 | return CozyInstance.first(function(err, instance) { 28 | return callback(err, (instance != null ? instance.locale : void 0) || null); 29 | }); 30 | }; 31 | 32 | CozyInstance.all = function(callback) { 33 | return CozyInstance.request('all', callback); 34 | }; 35 | 36 | CozyInstance.destroyAll = function(callback) { 37 | return CozyInstance.requestDestroy('all', callback); 38 | }; 39 | -------------------------------------------------------------------------------- /build/server/models/device.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Device, cozydb; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | module.exports = Device = cozydb.getModel('Device', { 7 | login: String, 8 | configuration: Object 9 | }); 10 | 11 | Device.all = function(params, callback) { 12 | return Device.request("all", params, callback); 13 | }; 14 | -------------------------------------------------------------------------------- /build/server/models/file.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var File, cozydb; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | module.exports = File = cozydb.getModel('File', { 7 | id: String, 8 | name: String, 9 | path: String, 10 | lastModification: String, 11 | binary: cozydb.NoSchema, 12 | "class": String 13 | }); 14 | 15 | File.imageByMonth = function(options, callback) { 16 | return File.rawRequest('imageByMonth', options, callback); 17 | }; 18 | 19 | File.imageByDate = function(options, callback) { 20 | return File.request('imageByDate', options, callback); 21 | }; 22 | 23 | File.withoutThumb = function(callback) { 24 | return File.request('withoutThumb', {}, callback); 25 | }; 26 | -------------------------------------------------------------------------------- /build/server/models/notification.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Notification, cozydb; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | module.exports = Notification = cozydb.getModel('Notification', { 7 | text: String, 8 | type: String, 9 | resource: { 10 | type: cozydb.NoSchema, 11 | "default": null 12 | }, 13 | publishDate: { 14 | type: String, 15 | "default": Date.now 16 | }, 17 | app: String, 18 | ref: String 19 | }); 20 | 21 | Notification.all = function(callback) { 22 | return Notification.request("byDate", callback); 23 | }; 24 | -------------------------------------------------------------------------------- /build/server/models/requests.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var allSlug, byApps, cozydb, imageByDate; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | byApps = function() { 7 | if (doc.type === 'persistent') { 8 | return emit([doc.app, doc.ref], doc); 9 | } 10 | }; 11 | 12 | allSlug = function() { 13 | return emit(doc.slug, doc); 14 | }; 15 | 16 | imageByDate = function(doc) { 17 | var ref; 18 | if (doc["class"] === "image" && (((ref = doc.binary) != null ? ref.file : void 0) != null)) { 19 | return emit(doc.lastModification, doc); 20 | } 21 | }; 22 | 23 | module.exports = { 24 | user: { 25 | all: cozydb.defaultRequests.all 26 | }, 27 | alarm: { 28 | all: cozydb.defaultRequests.all 29 | }, 30 | event: { 31 | all: cozydb.defaultRequests.all 32 | }, 33 | cozyinstance: { 34 | all: cozydb.defaultRequests.all 35 | }, 36 | notification: { 37 | all: cozydb.defaultRequests.all, 38 | byDate: function(doc) { 39 | return emit(doc.publishDate, doc); 40 | }, 41 | byApps: byApps 42 | }, 43 | application: { 44 | all: cozydb.defaultRequests.all, 45 | bySlug: allSlug 46 | }, 47 | stack_application: { 48 | all: cozydb.defaultRequests.all 49 | }, 50 | background: { 51 | all: cozydb.defaultRequests.all 52 | }, 53 | file: { 54 | imageByDate: imageByDate, 55 | imageByMonth: { 56 | map: function(doc) { 57 | var d, ref; 58 | if (doc["class"] === "image" && (((ref = doc.binary) != null ? ref.file : void 0) != null)) { 59 | d = new Date(doc.lastModification); 60 | return emit([d.getFullYear(), d.getMonth() + 1, d.getDate()], doc._id); 61 | } 62 | }, 63 | reduce: '_count' 64 | } 65 | }, 66 | sharing: { 67 | all: cozydb.defaultRequests.all 68 | } 69 | }; 70 | -------------------------------------------------------------------------------- /build/server/models/sharing.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Sharing, cozydb; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | module.exports = Sharing = cozydb.getModel('Sharing', { 7 | sharerUrl: String, 8 | sharerName: String, 9 | desc: String, 10 | rules: [Object], 11 | targets: [Object] 12 | }); 13 | 14 | Sharing.all = function(params, callback) { 15 | return Sharing.request("all", params, callback); 16 | }; 17 | -------------------------------------------------------------------------------- /build/server/models/stack_application.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var Manifest, StackApplication, cozydb; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | Manifest = require('../lib/manifest').Manifest; 7 | 8 | module.exports = StackApplication = cozydb.getModel('StackApplication', { 9 | name: String, 10 | version: String, 11 | lastVersion: String, 12 | "package": cozydb.NoSchema, 13 | git: String 14 | }); 15 | 16 | StackApplication.all = function(params, callback) { 17 | return StackApplication.request("all", params, callback); 18 | }; 19 | 20 | StackApplication.prototype.checkForUpdate = function(callback) { 21 | var manifest, setFlag; 22 | setFlag = (function(_this) { 23 | return function(repoVersion, cb) { 24 | return _this.updateAttributes({ 25 | lastVersion: repoVersion 26 | }, function(err) { 27 | if (err) { 28 | return cb(err); 29 | } else { 30 | return cb(); 31 | } 32 | }); 33 | }; 34 | })(this); 35 | manifest = new Manifest(); 36 | manifest["package"] = "cozy-" + this.name; 37 | return manifest.download(this, (function(_this) { 38 | return function(err) { 39 | var repoVersion; 40 | if (err) { 41 | return callback(err); 42 | } else { 43 | repoVersion = manifest.getVersion(); 44 | if (repoVersion == null) { 45 | return callback(null, false); 46 | } else { 47 | return setFlag(repoVersion, function(err) { 48 | if (err != null) { 49 | return callback(err); 50 | } 51 | if ((_this.version == null) || _this.version !== repoVersion) { 52 | return callback(null, true); 53 | } else { 54 | return callback(null, false); 55 | } 56 | }); 57 | } 58 | } 59 | }; 60 | })(this)); 61 | }; 62 | -------------------------------------------------------------------------------- /build/server/models/user.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var User, cozydb; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | module.exports = User = cozydb.getModel('User', { 7 | email: String, 8 | public_name: String, 9 | timezone: { 10 | type: String, 11 | "default": "Europe/Paris" 12 | }, 13 | password: String, 14 | owner: { 15 | type: Boolean, 16 | "default": false 17 | }, 18 | activated: { 19 | type: Boolean, 20 | "default": false 21 | }, 22 | authType: String, 23 | encryptedOtpKey: String, 24 | hotpCounter: Number, 25 | encryptedRecoveryCodes: String, 26 | mesinfosUseTracker: { 27 | type: Boolean, 28 | "default": false 29 | } 30 | }); 31 | 32 | User.all = function(callback) { 33 | return User.request("all", callback); 34 | }; 35 | 36 | User.first = function(callback) { 37 | return User.all(function(err, users) { 38 | return callback(err, users != null ? users[0] : void 0); 39 | }); 40 | }; 41 | 42 | User.destroyAll = function(callback) { 43 | return User.requestDestroy("all", callback); 44 | }; 45 | -------------------------------------------------------------------------------- /build/server/models/usetracker.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.10.0 2 | var UseTracker, async, cozydb, request; 3 | 4 | cozydb = require('cozydb'); 5 | 6 | request = require('request'); 7 | 8 | async = require('async'); 9 | 10 | module.exports = UseTracker = cozydb.getModel('UseTracker', { 11 | app: String, 12 | dateStart: Date, 13 | dateEnd: Date, 14 | duration: Number, 15 | sent: { 16 | type: Boolean, 17 | "default": false 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /build/server/views/index.js: -------------------------------------------------------------------------------- 1 | var jade = require('jade/runtime'); 2 | module.exports = function template(locals) { 3 | var buf = []; 4 | var jade_mixins = {}; 5 | var jade_interp; 6 | ;var locals_for_with = (locals || {});(function (argsFromLocationHash, imports) { 7 | buf.push("Cozy - Home");}.call(this,"argsFromLocationHash" in locals_for_with?locals_for_with.argsFromLocationHash:typeof argsFromLocationHash!=="undefined"?argsFromLocationHash:undefined,"imports" in locals_for_with?locals_for_with.imports:typeof imports!=="undefined"?imports:undefined));;return buf.join(""); 8 | } -------------------------------------------------------------------------------- /client/app/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/favicon.ico -------------------------------------------------------------------------------- /client/app/assets/fonts/adobeblank.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/adobeblank.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /client/app/assets/fonts/mavenpro-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/mavenpro-bold.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/mavenpro-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/mavenpro-bold.woff2 -------------------------------------------------------------------------------- /client/app/assets/fonts/mavenpro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/mavenpro-regular.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/mavenpro-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/mavenpro-regular.woff2 -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcecodepro-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcecodepro-bold.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcecodepro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcecodepro-regular.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcesanspro-bold-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcesanspro-bold-italic.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcesanspro-bold-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcesanspro-bold-italic.woff2 -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcesanspro-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcesanspro-bold.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcesanspro-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcesanspro-bold.woff2 -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcesanspro-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcesanspro-italic.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcesanspro-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcesanspro-italic.woff2 -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcesanspro-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcesanspro-regular.woff -------------------------------------------------------------------------------- /client/app/assets/fonts/sourcesanspro-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/fonts/sourcesanspro-regular.woff2 -------------------------------------------------------------------------------- /client/app/assets/img/apps/account.svg: -------------------------------------------------------------------------------- 1 | icon-account 2 | -------------------------------------------------------------------------------- /client/app/assets/img/apps/files.svg: -------------------------------------------------------------------------------- 1 | filesCreated with Sketch. -------------------------------------------------------------------------------- /client/app/assets/img/apps/hastebin.svg: -------------------------------------------------------------------------------- 1 | hastebinCreated with Sketch. -------------------------------------------------------------------------------- /client/app/assets/img/apps/isen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/apps/isen.png -------------------------------------------------------------------------------- /client/app/assets/img/apps/isen.svg: -------------------------------------------------------------------------------- 1 | isenCreated with Sketch. -------------------------------------------------------------------------------- /client/app/assets/img/apps/leave-google.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /client/app/assets/img/apps/maif.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /client/app/assets/img/apps/music.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /client/app/assets/img/apps/my-accounts.svg: -------------------------------------------------------------------------------- 1 | icon-account -------------------------------------------------------------------------------- /client/app/assets/img/apps/my-apps.svg: -------------------------------------------------------------------------------- 1 | icon-monitor -------------------------------------------------------------------------------- /client/app/assets/img/apps/notes.svg: -------------------------------------------------------------------------------- 1 | notesCreated with Sketch. -------------------------------------------------------------------------------- /client/app/assets/img/apps/photos.svg: -------------------------------------------------------------------------------- 1 | photosCreated with Sketch. -------------------------------------------------------------------------------- /client/app/assets/img/apps/remote_storage.svg: -------------------------------------------------------------------------------- 1 | remote_storageCreated with Sketch. -------------------------------------------------------------------------------- /client/app/assets/img/apps/store.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /client/app/assets/img/apps/tasky.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tasky 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /client/app/assets/img/apps/term.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | term 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /client/app/assets/img/apps/todos.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | todos 8 | Created with Sketch. 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_01.jpg -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_01_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_01_th.png -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_02.jpg -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_02_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_02_th.png -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_03.jpg -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_03_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_03_th.png -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_04.jpg -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_04_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_04_th.png -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_05.jpg -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_05_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_05_th.png -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_06.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_06.jpg -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_06_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_06_th.png -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_07.jpg -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_07_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_07_th.png -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_08.jpg -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_08_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_08_th.png -------------------------------------------------------------------------------- /client/app/assets/img/backgrounds/background_none_th.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/backgrounds/background_none_th.png -------------------------------------------------------------------------------- /client/app/assets/img/broken.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/broken.png -------------------------------------------------------------------------------- /client/app/assets/img/broken.svg: -------------------------------------------------------------------------------- 1 | brokenCreated with Sketch. -------------------------------------------------------------------------------- /client/app/assets/img/default.svg: -------------------------------------------------------------------------------- 1 | cozy-defaultCreated with Sketch. -------------------------------------------------------------------------------- /client/app/assets/img/en-play-badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/en-play-badge.png -------------------------------------------------------------------------------- /client/app/assets/img/git-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/git-white.png -------------------------------------------------------------------------------- /client/app/assets/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /client/app/assets/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /client/app/assets/img/happycloud-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/happycloud-black.png -------------------------------------------------------------------------------- /client/app/assets/img/happycloud-black.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /client/app/assets/img/happycloud-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/happycloud-small.png -------------------------------------------------------------------------------- /client/app/assets/img/happycloud-white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /client/app/assets/img/happycloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/happycloud.png -------------------------------------------------------------------------------- /client/app/assets/img/link-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/link-white.png -------------------------------------------------------------------------------- /client/app/assets/img/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/link.png -------------------------------------------------------------------------------- /client/app/assets/img/logo-brand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/logo-brand.png -------------------------------------------------------------------------------- /client/app/assets/img/marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/marker.png -------------------------------------------------------------------------------- /client/app/assets/img/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/mask.png -------------------------------------------------------------------------------- /client/app/assets/img/qwant-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/qwant-logo.jpg -------------------------------------------------------------------------------- /client/app/assets/img/spinner-white-thin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /client/app/assets/img/spinner-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /client/app/assets/img/spinner.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /client/app/assets/img/star-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/star-white.png -------------------------------------------------------------------------------- /client/app/assets/img/stopped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/img/stopped.png -------------------------------------------------------------------------------- /client/app/assets/sounds/notification.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/assets/sounds/notification.wav -------------------------------------------------------------------------------- /client/app/collections/application.coffee: -------------------------------------------------------------------------------- 1 | BaseCollection = require 'lib/base_collection' 2 | Application = require 'models/application' 3 | 4 | 5 | 6 | # List of installed applications. 7 | module.exports = class ApplicationCollection extends BaseCollection 8 | 9 | model: Application 10 | url: 'api/applications/' 11 | apps: [] 12 | 13 | 14 | get: (idorslug) -> 15 | out = super idorslug 16 | return out if out 17 | 18 | for app in @models 19 | return app if idorslug is app.get 'id' 20 | 21 | 22 | # Apps are automatically sorted by display name. Official apps are 23 | # sorted first. 24 | comparator: (modelLeft, modelRight) -> 25 | leftIsOfficial = modelLeft.isOfficial() 26 | rightIsOfficial = modelRight.isOfficial() 27 | 28 | if leftIsOfficial and not rightIsOfficial 29 | -1 30 | else if rightIsOfficial and not leftIsOfficial 31 | 1 32 | else 33 | left = modelLeft.get('displayName') or modelLeft.get('name') 34 | right = modelRight.get('displayName') or modelRight.get('name') 35 | left.localeCompare right 36 | 37 | -------------------------------------------------------------------------------- /client/app/collections/background.coffee: -------------------------------------------------------------------------------- 1 | BaseCollection = require 'lib/base_collection' 2 | Background = require 'models/background' 3 | 4 | 5 | # List of available backgrounds. 6 | module.exports = class BackgroundCollection extends Backbone.Collection 7 | url: 'api/backgrounds' 8 | model: Background 9 | 10 | addPredefinedBackgrounds: -> 11 | @add [ 12 | id: 'background-none' 13 | predefined: true 14 | , 15 | id: 'background-01' 16 | predefined: true 17 | , 18 | id: 'background-02' 19 | predefined: true 20 | , 21 | id: 'background-03' 22 | predefined: true 23 | , 24 | id: 'background-04' 25 | predefined: true 26 | , 27 | id: 'background-05' 28 | predefined: true 29 | , 30 | id: 'background-06' 31 | predefined: true 32 | , 33 | id: 'background-07' 34 | predefined: true 35 | , 36 | id: 'background-08' 37 | predefined: true 38 | ] 39 | 40 | init: -> 41 | @fetch 42 | success: (models) => 43 | @addPredefinedBackgrounds() 44 | selected = @findWhere id: window.app.instance.background 45 | selected ?= @at 0 46 | selected.set 'selected': true if selected? 47 | error: -> 48 | 49 | -------------------------------------------------------------------------------- /client/app/collections/device.coffee: -------------------------------------------------------------------------------- 1 | BaseCollection = require 'lib/base_collection' 2 | Device = require 'models/device' 3 | 4 | 5 | # List of installed devices. 6 | module.exports = class DeviceCollection extends BaseCollection 7 | 8 | model: Device 9 | url: 'api/devices/' -------------------------------------------------------------------------------- /client/app/collections/notifications.coffee: -------------------------------------------------------------------------------- 1 | BaseCollection = require 'lib/base_collection' 2 | Notification = require 'models/notification' 3 | 4 | 5 | # List of installed applications. 6 | module.exports = class NotificationCollection extends Backbone.Collection 7 | 8 | model: Notification 9 | url: 'api/notifications' 10 | 11 | 12 | removeAll: (options) -> 13 | options ?= {} 14 | success = options.success 15 | options.success = => 16 | @reset [] 17 | success?.apply this, arguments 18 | 19 | @sync 'delete', this, options 20 | -------------------------------------------------------------------------------- /client/app/collections/stackApplication.coffee: -------------------------------------------------------------------------------- 1 | BaseCollection = require 'lib/base_collection' 2 | StackApplication = require 'models/stack_application' 3 | 4 | 5 | # List of installed applications. 6 | module.exports = class ApplicationCollection extends BaseCollection 7 | 8 | model: StackApplication 9 | url: 'api/applications/stack' 10 | 11 | -------------------------------------------------------------------------------- /client/app/helpers/client.coffee: -------------------------------------------------------------------------------- 1 | # Make ajax request easier to do. 2 | # Expected callbacks: success and error 3 | exports.request = (type, url, data, callbacks) -> 4 | $.ajax 5 | type: type 6 | url: url 7 | data: data 8 | dataType: 'json' 9 | success: callbacks.success 10 | error: callbacks.error 11 | 12 | # Sends a get request 13 | # Expected callbacks: success and error 14 | exports.get = (url, callbacks) -> 15 | exports.request "GET", url, null, callbacks 16 | 17 | # Sends a post request with data as body 18 | # Expected callbacks: success and error 19 | exports.post = (url, data, callbacks) -> 20 | exports.request "POST", url, data, callbacks 21 | 22 | # Sends a put request with data as body 23 | # Expected callbacks: success and error 24 | exports.put = (url, data, callbacks) -> 25 | exports.request "PUT", url, data, callbacks 26 | 27 | # Sends a delete request 28 | # Expected callbacks: success and error 29 | exports.del = (url, callbacks) -> 30 | exports.request "DELETE", url, null, callbacks 31 | 32 | # Sends a head request 33 | # Expected callbacks: success and error 34 | exports.head = (url, callbacks) -> 35 | exports.request "HEAD", url, null, callbacks 36 | 37 | # Handle SAMEORIGIN error 38 | # Invalid hash could be iframe source 39 | # Force refresh to root application 40 | exports.getSAMEORIGINError = (hash) -> 41 | return hash.match /^(\w*:\/\/\w+\.)/ 42 | -------------------------------------------------------------------------------- /client/app/helpers/color-set.coffee: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | 'ead1ad' 3 | 'fbf0c2' 4 | '3cd7c3' 5 | '8FBAff' 6 | 'B4AED9' 7 | '78dc9a' 8 | '8DED2A' 9 | '8eecB9' 10 | 'bbcaA9' 11 | 'cdb19b' 12 | 'ec7e63' 13 | '8cec56' 14 | 'ffb1be' 15 | 'DD99CE' 16 | 'E26987' 17 | '8CB1FF' 18 | 'f5dd16' 19 | 'f1fab8' 20 | 'ffbe56' 21 | '6EE1C8' 22 | 'C4BEE9' 23 | '59C1ef' 24 | 'EC7E63' 25 | '8BEE8C' 26 | ] 27 | -------------------------------------------------------------------------------- /client/app/helpers/locales.coffee: -------------------------------------------------------------------------------- 1 | exports.locales = 2 | 'en': 'English' 3 | 'fr': 'Français' 4 | # 'es': 'Español' 5 | # 'ja': '日本語' 6 | -------------------------------------------------------------------------------- /client/app/helpers/slugify.coffee: -------------------------------------------------------------------------------- 1 | 2 | # Change a string into its slug shape (only alphanumeric char and hyphens 3 | # instead of spaces. 4 | module.exports = slugify = (string) -> 5 | _slugify_strip_re = /[^\w\s-]/g 6 | _slugify_hyphenate_re = /[-\s]+/g 7 | string = string.replace(_slugify_strip_re, '').trim().toLowerCase() 8 | string = string.replace _slugify_hyphenate_re, '-' 9 | string 10 | -------------------------------------------------------------------------------- /client/app/lib/base_collection.coffee: -------------------------------------------------------------------------------- 1 | # Base class to share common methods between collections. 2 | module.exports = class BaseCollection extends Backbone.Collection 3 | 4 | # Select which field from backend response to use for parsing to populate 5 | # collection. 6 | parse: (response) -> 7 | response.rows 8 | -------------------------------------------------------------------------------- /client/app/lib/base_model.coffee: -------------------------------------------------------------------------------- 1 | # Base class that contains commomn methods for models. 2 | class exports.BaseModel extends Backbone.Model 3 | 4 | isNew: () -> 5 | @id is undefined 6 | -------------------------------------------------------------------------------- /client/app/lib/base_view.coffee: -------------------------------------------------------------------------------- 1 | module.exports = class BaseView extends Backbone.View 2 | tagName: 'section' 3 | 4 | template: -> 5 | 6 | initialize: -> 7 | @render() 8 | super() 9 | 10 | getRenderData: -> 11 | if @model? and @model.toJSON? 12 | model: @model.toJSON() 13 | 14 | render: -> 15 | # console.debug "Rendering #{@constructor.name}", @ 16 | @beforeRender() 17 | @$el.html @template(@getRenderData()) 18 | @afterRender() 19 | @ 20 | 21 | beforeRender: -> 22 | 23 | afterRender: -> 24 | 25 | destroy: -> 26 | @undelegateEvents() 27 | @$el.removeData().unbind() 28 | @remove() 29 | Backbone.View::remove.call @ 30 | -------------------------------------------------------------------------------- /client/app/lib/intent_manager.coffee: -------------------------------------------------------------------------------- 1 | ObjectPicker = require 'views/object_picker' 2 | 3 | module.exports = class IntentManager 4 | 5 | 6 | registerIframe : (iframe, remoteOrigin)-> 7 | talker = new Talker(iframe.contentWindow, remoteOrigin) 8 | talker.onMessage = @handleIntent 9 | 10 | 11 | handleIntent : (message) -> 12 | intent = message.data 13 | switch intent.type 14 | 15 | when 'goto' 16 | window.app.routers.main.navigate "apps/#{intent.params}", true 17 | 18 | when 'pickObject' 19 | switch intent.params.objectType 20 | when 'singlePhoto' 21 | if intent.params.isCropped 22 | new ObjectPicker(intent.params , \ 23 | (newPhotoChosen, dataUrl) -> 24 | message.respond( 25 | newPhotoChosen :newPhotoChosen 26 | dataUrl :dataUrl 27 | ) 28 | ) 29 | else 30 | new ObjectPicker(intent.params , \ 31 | (newPhotoChosen, dataUrl) -> 32 | message.respond( 33 | newPhotoChosen :newPhotoChosen 34 | dataUrl :dataUrl 35 | ) 36 | ) 37 | # usefull to check from the client (app) that the home is there and 38 | # has the intent manager available 39 | when 'ping' 40 | message.respond('pong') 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /client/app/lib/proxyclient.coffee: -------------------------------------------------------------------------------- 1 | request = require('lib/request') 2 | exports.get = (url, callback) -> 3 | request.request('get', 'api/proxy', url, callback) -------------------------------------------------------------------------------- /client/app/lib/socket_listener.coffee: -------------------------------------------------------------------------------- 1 | Application = require 'models/application' 2 | Notification = require 'models/notification' 3 | Device = require 'models/device' 4 | 5 | application_idx = 0 6 | notification_idx = 1 7 | device_idx = 2 8 | 9 | class SocketListener extends CozySocketListener 10 | 11 | 12 | models: 13 | 'notification': Notification 14 | 'device': Device 15 | 'application' : Application 16 | 17 | events: [ 18 | 'notification.create', 'notification.update', 'notification.delete', 19 | 'device.create', 'device.update', 'device.delete', 20 | 'application.create', 'application.update', 'application.delete' 21 | ] 22 | 23 | onRemoteCreate: (model) -> 24 | if model instanceof Application 25 | @collections[application_idx].add model 26 | else if model instanceof Notification 27 | @collections[notification_idx].add model 28 | else if model instanceof Device 29 | @collections[device_idx].add model 30 | 31 | onRemoteDelete: (model) -> 32 | if model instanceof Application 33 | @collections[application_idx].remove model 34 | else if model instanceof Notification 35 | @collections[notification_idx].remove model 36 | else if model instanceof Device 37 | @collections[device_idx].remove model 38 | 39 | 40 | module.exports = new SocketListener() 41 | -------------------------------------------------------------------------------- /client/app/lib/usetracker.coffee: -------------------------------------------------------------------------------- 1 | INTERVAL = 1 * 1000 # 1s 2 | 3 | module.exports = class UseTracker 4 | 5 | constructor: -> 6 | if app.mesinfosUseTracker 7 | setInterval @_heartbeat, INTERVAL 8 | 9 | setApp: (appName) -> 10 | @appName = appName 11 | 12 | _heartbeat: => 13 | if document.hasFocus() 14 | $.post 'usetrackers', 15 | timestamp: new Date().toISOString() 16 | appName: @appName 17 | , 'json' 18 | -------------------------------------------------------------------------------- /client/app/models/background.coffee: -------------------------------------------------------------------------------- 1 | {BaseModel} = require 'lib/base_model' 2 | 3 | # Describes a background selectable in account section. 4 | module.exports = class Background extends BaseModel 5 | urlRoot: '/api/backgrounds/' 6 | 7 | 8 | # Get path to the background image (handle predefined background and 9 | # background added by the user). 10 | getSrc: -> 11 | id = @get 'id' 12 | if id.indexOf('background') > -1 13 | id = id.replace '-', '_' 14 | return "/img/backgrounds/#{id}.jpg" 15 | else 16 | return "/api/backgrounds/#{id}/picture.jpg" 17 | 18 | 19 | # Get path to the background image thumbnail (handle predefined background 20 | # and background added by the user). 21 | getThumbSrc: -> 22 | id = @get 'id' 23 | if id.indexOf('background') > -1 24 | id = id.replace '-', '_' 25 | return "/img/backgrounds/#{id}_th.png" 26 | else 27 | return "/api/backgrounds/#{id}/thumb.jpg" 28 | 29 | 30 | -------------------------------------------------------------------------------- /client/app/models/device.coffee: -------------------------------------------------------------------------------- 1 | {BaseModel} = require 'lib/base_model' 2 | 3 | # Describes a device installed in mycloud. 4 | module.exports = class Device extends Backbone.Model 5 | 6 | urlRoot: 'api/devices/' 7 | -------------------------------------------------------------------------------- /client/app/models/instance.coffee: -------------------------------------------------------------------------------- 1 | request = require 'lib/request' 2 | 3 | 4 | # Model to describe instance options required at home startup like locale, 5 | # background, etc. 6 | module.exports = class Instance extends Backbone.Model 7 | 8 | saveData: (data, callback) -> 9 | @set data 10 | request.post "api/instance", data, callback 11 | 12 | -------------------------------------------------------------------------------- /client/app/models/notification.coffee: -------------------------------------------------------------------------------- 1 | {BaseModel} = require 'lib/base_model' 2 | 3 | # Describes a notification 4 | module.exports = class Notification extends BaseModel 5 | 6 | urlRoot: 'api/notifications' 7 | -------------------------------------------------------------------------------- /client/app/models/photo.coffee: -------------------------------------------------------------------------------- 1 | request = require('../lib/request') 2 | 3 | # A photo 4 | # maintains attributes src / thumbsrc depending of the state of the model 5 | module.exports = class Photo extends Backbone.Model 6 | 7 | defaults: ()-> 8 | thumbsrc: 'img/loading.gif' 9 | src: '' 10 | orientation: 1 11 | 12 | 13 | url: ()-> 14 | super + app.urlKey 15 | 16 | 17 | # build img src attributes from id. 18 | parse: (attrs) -> 19 | if not attrs.id then attrs 20 | else _.extend attrs, 21 | thumbsrc: "photos/thumbs/#{attrs.id}.jpg" + app.urlKey 22 | src: "photos/#{attrs.id}.jpg" + app.urlKey 23 | orientation: attrs.orientation 24 | 25 | 26 | # Return screen size photo src built from id. 27 | getPrevSrc: ()-> 28 | "photos/#{@get 'id'}.jpg" 29 | 30 | 31 | Photo.getMonthdistribution = (callback)-> 32 | request.get "files/photo/monthdistribution", callback 33 | 34 | 35 | Photo.listFromFiles = (skip, limit, callback)-> 36 | request.get "files/photo/range/#{skip}/#{limit}", callback 37 | 38 | 39 | Photo.makeFromFile = (fileid, attr, callback) -> 40 | request.post "files/#{fileid}/toPhoto", attr, callback 41 | 42 | -------------------------------------------------------------------------------- /client/app/models/token.coffee: -------------------------------------------------------------------------------- 1 | client = require 'helpers/client' 2 | 3 | # Describes an application installed in mycloud. 4 | module.exports = class Token 5 | 6 | constructor: (name) -> 7 | @name = name 8 | 9 | getToken: (callbacks) -> 10 | client.get "api/getToken/#{@name}", callbacks 11 | 12 | -------------------------------------------------------------------------------- /client/app/models/user.coffee: -------------------------------------------------------------------------------- 1 | {BaseModel} = require 'lib/base_model' 2 | client = require 'lib/request' 3 | 4 | # Describes an application installed in mycloud. 5 | module.exports = class User extends BaseModel 6 | 7 | 8 | constructor: (@email, @password) -> 9 | super() 10 | 11 | 12 | logout: (callback) -> 13 | client.get "logout/", callback 14 | 15 | -------------------------------------------------------------------------------- /client/app/styles/base/_alerts.styl: -------------------------------------------------------------------------------- 1 | .alert-error 2 | .alert-success 3 | display none 4 | border-radius 4px 5 | padding (10/16)em 6 | color white 7 | font-size 1em 8 | 9 | .alert-error 10 | background red 11 | 12 | .alert-success 13 | background green 14 | -------------------------------------------------------------------------------- /client/app/styles/base/_colors.styl: -------------------------------------------------------------------------------- 1 | /*! 2 | * PALETTE / COLORS 3 | * ================ 4 | * 5 | * This file contains colors declarations and tools. 6 | */ 7 | 8 | // defaults 9 | black = #000 10 | white = #fff 11 | 12 | // 50 (well, in fact, mostly 8) shades of grey 13 | grey-01 = #EAEEF2 14 | grey-02 = #DDE6EF 15 | grey-03 = #C8D5DF 16 | grey-04 = #ACB8C5 17 | grey-05 = #92A0B2 18 | grey-06 = #748192 19 | grey-07 = #4F5B69 20 | grey-08 = #32363F 21 | 22 | // more of cozy UI 23 | blue = #33A6FF 24 | red = #FF3713 25 | green = #16D943 26 | 27 | pink = #FC4C83 28 | gold = #FFC644 29 | turquoise = #4DCEC5 30 | tomato-dry = #FD7461 31 | joker = #A75BCB 32 | 33 | 34 | // brands color 35 | twitter = #55ACEE 36 | 37 | 38 | body 39 | background-color white 40 | color grey-08 41 | -------------------------------------------------------------------------------- /client/app/styles/base/_form.styl: -------------------------------------------------------------------------------- 1 | input 2 | select 3 | textarea 4 | padding 0 (12/18)em 5 | 6 | background grey-01 7 | border 0 8 | border 2px solid grey-01 9 | box-shadow 0 0 0 0 10 | border-radius 3px 11 | 12 | transition all 0.2s 13 | 14 | &:hover 15 | border-color grey-04 16 | 17 | &:focus 18 | background white 19 | border-color blue 20 | box-shadow 0 0 0 0 21 | 22 | textarea 23 | padding 1rem 24 | 25 | input 26 | select 27 | height 48px 28 | 29 | color grey-08 30 | font-size (18/16)em 31 | line-height 1em 32 | 33 | .fied-with-btn 34 | display flex 35 | justify-content flex-end 36 | align-items stretch 37 | 38 | input 39 | border-radius 3px 0 0 3px 40 | border-right none 41 | 42 | .btn 43 | border-radius 0 3px 3px 0 44 | 45 | input[type=checkbox] 46 | margin-top 8px 47 | width 15px 48 | height 15px 49 | -------------------------------------------------------------------------------- /client/app/styles/base/_grid.styl: -------------------------------------------------------------------------------- 1 | .w350 2 | max-width 350px 3 | 4 | .w500 5 | max-width 500px 6 | 7 | .w600 8 | max-width 600px 9 | margin auto 10 | 11 | .w800 12 | max-width 800px 13 | margin auto 14 | 15 | .ma2 16 | margin 20px 17 | 18 | 19 | .pa2 20 | padding 20px 21 | 22 | .par2 23 | padding-right 20px 24 | 25 | .mt6 26 | margin-top 60px 27 | 28 | 29 | // new grid 30 | // -------- 31 | // based on the media queries 32 | // ======================================================== 33 | 34 | .full-20 35 | width 20% 36 | 37 | @media (max-width (640/16)em) 38 | .w640-25 39 | width 25% 40 | 41 | @media (max-width (360/16)em) 42 | .w360-33 43 | width 33% 44 | 45 | -------------------------------------------------------------------------------- /client/app/styles/base/_reset.styl: -------------------------------------------------------------------------------- 1 | * 2 | outline none 3 | 4 | html 5 | height 100% 6 | padding 0 7 | margin 0 8 | 9 | body 10 | box-sizing border-box 11 | height 100% 12 | padding 0 13 | margin 0 14 | 15 | background-color grey-01 16 | 17 | font-family 'Source Sans Pro', sans-serif 18 | font-size 16px 19 | 20 | iframe 21 | width 100% 22 | height 100% 23 | border 0 24 | 25 | a 26 | color blue 27 | text-decoration none 28 | transition color 0.2s ease 29 | 30 | &:hover 31 | color blue - 20% 32 | 33 | hr 34 | margin 1.25em 0 35 | border 0 36 | border-top 1px solid grey-03 37 | 38 | h1 39 | h2 40 | h3 41 | h4 42 | line-height 1em 43 | padding-bottom 0.5em 44 | 45 | h4 46 | margin (60/24)em 0 (12/24)em 0 47 | border-bottom 2px solid grey-03 48 | font-size (24/16)em 49 | font-weight normal 50 | color grey-05 51 | 52 | @media (max-width (800/16)em) 53 | margin (40/24)em 0 (12/24)em 0 54 | 55 | 56 | 57 | .tooltip-inner 58 | a:hover 59 | color blue 60 | text-decoration none 61 | 62 | .spacer 63 | clear both 64 | 65 | .close 66 | float right 67 | 68 | .hidden 69 | display none 70 | 71 | .center 72 | text-align center 73 | 74 | 75 | .green 76 | background green 77 | 78 | .red 79 | background red 80 | 81 | .bold 82 | font-weight bold 83 | 84 | .token 85 | font-family 'Monospace' 86 | word-wrap break-word -------------------------------------------------------------------------------- /client/app/styles/components/_help.styl: -------------------------------------------------------------------------------- 1 | .help-text 2 | text-align center 3 | 4 | .small 5 | font-size (14/16)em 6 | 7 | img 8 | width 24px 9 | 10 | .help-section 11 | border-top: 1px solid grey-02 12 | 13 | .line 14 | margin-top: 1.2em 15 | 16 | a 17 | display: block 18 | margin-bottom: 5px 19 | text-transform: uppercase 20 | color: grey-07 21 | &:hover 22 | color: blue 23 | span 24 | display: inline-block 25 | vertical-align: middle 26 | padding-bottom: 12px 27 | margin-left: 15px 28 | -------------------------------------------------------------------------------- /client/app/styles/components/_settings.styl: -------------------------------------------------------------------------------- 1 | // Account page 2 | 3 | #account-view 4 | p 5 | margin 0 6 | margin-bottom 5px 7 | 8 | input 9 | select 10 | margin-bottom 0.5em 11 | 12 | .account-field 13 | margin-bottom 20px 14 | max-width 550px 15 | 16 | input 17 | margin 0 18 | width 100% 19 | 20 | input[disabled] 21 | border-width 0 22 | color blue 23 | 24 | select 25 | margin 0 26 | width 100% 27 | cursor pointer 28 | 29 | button.full-width 30 | width 100% 31 | padding (12/16)em 32 | 33 | .error 34 | color red 35 | 36 | button 37 | text-align center 38 | 39 | .background-list 40 | margin-top 10px 41 | 42 | .background-button 43 | position relative 44 | text-align center 45 | cursor pointer 46 | 47 | img 48 | transition border 0.2s ease 49 | border 5px solid transparent 50 | margin 0 51 | 52 | button 53 | display none 54 | position absolute 55 | top 0 56 | right 0 57 | 58 | .fa 59 | margin 0 60 | 61 | &:hover 62 | button 63 | display inline 64 | 65 | .background-button:hover 66 | img 67 | border-color blue 68 | 69 | .background-button.selected 70 | img 71 | border-color green 72 | outline 0 73 | -------------------------------------------------------------------------------- /client/app/templates/album_thumb.jade: -------------------------------------------------------------------------------- 1 | .albumLabel 2 | img.cover 3 | div.label 4 | -------------------------------------------------------------------------------- /client/app/templates/application_iframe.jade: -------------------------------------------------------------------------------- 1 | iframe(src="#{source}", id="#{id}") 2 | -------------------------------------------------------------------------------- /client/app/templates/background_list.jade: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/templates/background_list.jade -------------------------------------------------------------------------------- /client/app/templates/background_list_item.jade: -------------------------------------------------------------------------------- 1 | button.delete-background-button.btn.right.ma1 2 | i.fa.fa-trash 3 | img.w100.left(src="#{model.src}") 4 | -------------------------------------------------------------------------------- /client/app/templates/config_application.jade: -------------------------------------------------------------------------------- 1 | .icon-container 2 | img.spinner(src="/img/spinner-white-thin.svg") 3 | img.icon(src="") 4 | .infos 5 | .line 6 | strong 7 | a.app(href="#apps/#{app.slug}")= app.displayName 8 | button.update-app.outline-blue(title="#{t('update')}") 9 | i.fa.fa-refresh 10 | span= t('update') 11 | .line 12 | if app.version 13 | span #{app.version} 14 | span  -  15 | if app.state === 'installed' 16 | span.state-label= t('running') 17 | else 18 | span.state-label 19 | | #{app.state} 20 | .line 21 | .comments 22 | a(href="#{app.websiteUrl}", target="_blank")= app.website 23 | span 24 | | (#{app.branch}) 25 | 26 | .buttons 27 | if app.favorite 28 | button.transparent-grey.favorite(title="#{t('config application unmark favorite')}") 29 | i.fa.fa-star 30 | else 31 | button.transparent-grey.favorite(title="#{t('config application mark favorite')}") 32 | i.fa.fa-star-o 33 | a.transparent-grey.logs(href="/logs/#{app.slug}", target="_blank", title="#{t('show logs')}", role="button") 34 | i.fa.fa-code 35 | if app.state === "stopped" 36 | button.transparent-grey.stopped.start-stop-btn(title="#{t('start this app')}") 37 | i.fa.fa-power-off 38 | else 39 | button.transparent-grey.start-stop-btn(title="#{t('stop this app')}") 40 | i.fa.fa-power-off 41 | button.transparent-grey.remove-app(title="#{t('remove')}") 42 | i.fa.fa-trash 43 | -------------------------------------------------------------------------------- /client/app/templates/config_application_list.jade: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/templates/config_application_list.jade -------------------------------------------------------------------------------- /client/app/templates/config_device.jade: -------------------------------------------------------------------------------- 1 | .mod 2 | strong #{device.login} 3 | 4 | .buttons 5 | button.remove-device.transparent-grey 6 | i.fa.fa-trash.mr1 7 | | 8 | span.label= t('revoke device access') 9 | -------------------------------------------------------------------------------- /client/app/templates/config_device_list.jade: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/client/app/templates/config_device_list.jade -------------------------------------------------------------------------------- /client/app/templates/error_modal.jade: -------------------------------------------------------------------------------- 1 | .md-content 2 | .md-header.clearfix 3 | .line 4 | h3.left= t('app broken title') 5 | .md-body 6 | strong #{t('app broken')} 7 | a(href="#config-applications") #{ t('reinstall broken app')} 8 | br 9 | span #{t('app msg')} 10 | br 11 | br 12 | span #{errortype} 13 | br 14 | br 15 | button.btn#more= t('more details') 16 | br 17 | br 18 | p.details= details 19 | 20 | .md-footer.clearfix 21 | if cancel 22 | button.transparent-grey#cancelbtn= cancel 23 | button.btn.right#ok= ok 24 | -------------------------------------------------------------------------------- /client/app/templates/help.jade: -------------------------------------------------------------------------------- 1 | .mod.pa2.help-section 2 | h2= t('help community title') 3 | .line 4 | a(href="https://forum.cozy.io", target="_blank") 5 | i.icon-small.forum 6 | span= t('help forum title') 7 | a(href="https://webchat.freenode.net/?channels=cozycloud", target="_blank") 8 | i.icon-small.irc 9 | span= t('help IRC title') 10 | a(href="https://github.com/cozy", target="_blank") 11 | i.icon-small.github 12 | span= t('help github title') 13 | 14 | .mod.pa2.help-section 15 | h2= t('help support title') 16 | .line 17 | a(href="mailto:support@cozycloud.cc") 18 | i.icon-small.contact 19 | span= t('help email title') 20 | a(href="https://twitter.com/intent/tweet?text=@mycozycloud%20", target="_blank") 21 | i.icon-small.twitter 22 | span= t('help twitter title') 23 | a(href="https://cozy.io", target="_blank") 24 | i.icon-small.doc 25 | span= t('help documentation title') 26 | 27 | .mod.pa2.help-section 28 | h2= t('help direct title') 29 | textarea#send-message-textarea.mt2.w100 30 | p.help-logs 31 | input#send-message-logs(type='checkbox', checked='checked') 32 | label(for='send-message-logs')= t('help send logs') 33 | button#send-message-button.btn.send-message-btn 34 | .fa.fa-paper-plane 35 | span= t('help send message action') 36 | #send-message-error.alert.main-alert.alert-error.w100= t('send message error') 37 | #send-message-success.alert.main-alert.alert-success.w100= t('send message success') 38 | -------------------------------------------------------------------------------- /client/app/templates/help_url.jade: -------------------------------------------------------------------------------- 1 | .line 2 | p.help-text.mt2= t('The first place to find help is:') 3 | p.help-text 4 | a(href="#{helpUrl}") #{helpUrl} 5 | -------------------------------------------------------------------------------- /client/app/templates/home_application.jade: -------------------------------------------------------------------------------- 1 | div.application-inner 2 | .vertical-aligner 3 | img.icon(src="") 4 | img.spinner(src="/img/spinner-white-thin.svg") 5 | p.app-title #{app.displayName} 6 | 7 | -------------------------------------------------------------------------------- /client/app/templates/layout.jade: -------------------------------------------------------------------------------- 1 | header#header.navbar 2 | 3 | #notifications-menu.right-menu 4 | .top-title 5 | h2= t('notifications') 6 | button#dismiss-all.btn.outline-darkgrey.small 7 | span= t('dismiss all') 8 | 9 | #notifications 10 | ul#notifications-list 11 | li#no-notif-msg 12 | 13 | #help-menu.right-menu 14 | 15 | .home-body 16 | #app-frames 17 | #content 18 | // Preload spinners and hover icons 19 | img.hidden(src="/img/spinner.svg") 20 | img.hidden(src="/img/spinner-white.svg") 21 | #home-content 22 | -------------------------------------------------------------------------------- /client/app/templates/long_list_image.jade: -------------------------------------------------------------------------------- 1 | .viewPort 2 | .thumbs 3 | .index -------------------------------------------------------------------------------- /client/app/templates/market.jade: -------------------------------------------------------------------------------- 1 | .platform-section 2 | //- p.mt2 #{t('introduction market')} 3 | #app-market-list 4 | #market-applications-list 5 | #no-app-message= t('installed everything') 6 | 7 | #your-app.clearfix 8 | h2= t('install your app') 9 | .text 10 | p 11 | = t('market install your app') 12 | p.add-app-field.fied-with-btn 13 | input(type="text", class="span3", id="app-git-field", placeholder="https://github.com/username/repository.git@branch") 14 | button.btn.app-install-button= t('install') 15 | 16 | .error.alert-error 17 | .info.alert 18 | p.more 19 | = t('market install your app tutorial') 20 |   21 | a(href="https://dev.cozy.io/", 22 | target="_blank")= t('market app tutorial') 23 | | . 24 | .md-overlay 25 | -------------------------------------------------------------------------------- /client/app/templates/market_application.jade: -------------------------------------------------------------------------------- 1 | 2 | .app-img 3 | if app.svgSpriteSlug 4 | img(class=app.svgSpriteSlug) 5 | else 6 | img(src="#{app.icon}") 7 | span.installing-label= t("market app install") 8 | 9 | .app-text 10 | h3 #{app.displayName} 11 | if app.beta 12 | span.beta Beta 13 | span.comment= t(app.comment) 14 | p= t(app.description) 15 | .btn-group 16 | button.outline-blue.small= t("install") 17 | a.transparent-grey.small.website(href="#{app.git}", target="_blank", role="button") 18 | .fa.fa-github 19 | span= t("github") 20 | if app.website !== undefined 21 | a.transparent-grey.small.website(href="#{app.website}", target="_blank", role="button") 22 | .fa.fa-link 23 | span= t("website") 24 | -------------------------------------------------------------------------------- /client/app/templates/menu_application.jade: -------------------------------------------------------------------------------- 1 | a(href="#apps/#{model.slug}/") #{model.displayName} 2 | -------------------------------------------------------------------------------- /client/app/templates/menu_applications.jade: -------------------------------------------------------------------------------- 1 | #menu-applications-toggle 2 | span#current-application 3 | -------------------------------------------------------------------------------- /client/app/templates/navbar.jade: -------------------------------------------------------------------------------- 1 | .navbar.clearfix 2 | a#logout-button.btn-navbar.sign-out.right(href="#logout", title="#{t('logout')}") 3 | i.fa.fa-sign-out 4 | a#help-toggle.btn-navbar.right(href="#help", title="#{t('help')}") 5 | i.fa.fa-question-circle 6 | #notifications-container.right 7 | a.back-button.left(href="#home", title="#{t('navbar back button title')}") 8 | .fa.fa-chevron-left 9 | span 10 | = t("navbar back button title") 11 | #menu-applications-container 12 | //- parent should already be window.parent by default 13 | - var qwantMode = parent.urlArguments && parent.urlArguments.modes && parent.urlArguments.modes.indexOf('qwant_search') !== -1; 14 | if ((parent.DEV_ENV || qwantMode || parent.ENABLE_QWANT_SEARCH) && parent.qwantInstalled) || parent.BEN_DEMO 15 | div.search 16 | input#search-bar(type="text") 17 | -------------------------------------------------------------------------------- /client/app/templates/navbar_app_btn.jade: -------------------------------------------------------------------------------- 1 | li.app-button 2 | a(id="#{app.slug}", href="#apps/#{app.slug}") 3 | img(src="/apps/#{app.slug}/favicon.ico") 4 | -------------------------------------------------------------------------------- /client/app/templates/notification.jade: -------------------------------------------------------------------------------- 1 | a.dismiss × 2 | .notification-text #{model.text} 3 | .notification-date #{model.date} 4 | if model.actionText !== undefined && model.actionText !== null 5 | if model.update 6 | a.doaction.btn.outline-blue 7 | i.fa.fa-refresh 8 | = t(model.actionText) 9 | else 10 | a.doaction.btn.grey= t(model.actionText) 11 | -------------------------------------------------------------------------------- /client/app/templates/notifications.jade: -------------------------------------------------------------------------------- 1 | a#notifications-toggle.btn-navbar(title="#{t('navbar notifications')}") 2 | i.fa.fa-bell 3 | span#notifications-counter 4 | 5 | #clickcatcher 6 | 7 | -------------------------------------------------------------------------------- /client/app/templates/object_picker.jade: -------------------------------------------------------------------------------- 1 | // never displayed, just for downloading. 2 | img#img-result 3 | 4 | 5 | .objectPickerCont 6 | nav.fp-nav-tabs(role='tablist', aria-controls='objectPickerCont') 7 | 8 | .croperCont 9 | .frame-to-crop 10 | div#img-to-crop 11 | div#frame-preview 12 | img#img-preview 13 | -------------------------------------------------------------------------------- /client/app/templates/object_picker_photourl.jade: -------------------------------------------------------------------------------- 1 | div.bloc-container 2 | div.img-container 3 | div.url-preview 4 | input.modal-url-input(placeholder="#{t('url of an image')}", value="") 5 | //- for tests small image : value="https://weechat.org/media/images/weechat_logo_small.png" 6 | //- for tests medium image : value="http://upload.wikimedia.org/wikipedia/commons/c/c4/PM5544_with_non-PAL_signals.png" -------------------------------------------------------------------------------- /client/app/templates/object_picker_search.jade: -------------------------------------------------------------------------------- 1 | div.search-tab-container 2 | input.modal-search-input(placeholder="#{t('What are you looking for?')}", value="") 3 | .subsection Powered by 4 | img(src="img/qwant-logo.jpg", alt="Qwant logo") 5 | -------------------------------------------------------------------------------- /client/app/templates/object_picker_upload.jade: -------------------------------------------------------------------------------- 1 | .modal-file-drop-zone 2 | p #{t('drop a file')} 3 | div.drop-zone 4 | div.photoUpload-btn 5 | button.btn #{t('ObjPicker upload btn')} 6 | input.uploader(type='file',style="display:none") 7 | -------------------------------------------------------------------------------- /client/app/templates/popover_description.jade: -------------------------------------------------------------------------------- 1 | .md-content 2 | .md-header.clearfix 3 | .line 4 | h3.left #{model.displayName} 5 | if (model.comment !== 'official application') 6 | .line.noncozy-warning 7 | i.fa.fa-info-circle 8 | span 9 | != t('warning unofficial app') 10 | .md-body 11 | .md-footer 12 | button.btn.transparent-grey#cancelbtn= t('cancel') 13 | button.btn#confirmbtn= t('install') 14 | -------------------------------------------------------------------------------- /client/app/templates/popover_permissions.jade: -------------------------------------------------------------------------------- 1 | .md-header.mt2=t('Once updated, this application will require the following permissions:') 2 | .md-body 3 | div   4 | .md-footer.mt2 5 | a#cancelbtn.btn.transparent-grey= t('cancel') 6 | if model.state === 'broken' 7 | a#confirmbtn.btn= t('confirm install') 8 | else 9 | a#confirmbtn.btn= t('confirm update') 10 | -------------------------------------------------------------------------------- /client/app/templates/tutorial.jade: -------------------------------------------------------------------------------- 1 | //.section-title.darkbg.bigger help 2 | line.w800.lightgrey 3 | h4.help-text.darkbg.pa2=t('tutorial title') 4 | #tuto-files.line.pa2.question 5 | p.help-text.mt2=t('tutorial question files') 6 | p.center 7 | button#files-no.btn=t('tutorial no') 8 | button#files-yes.btn=t('tutorial yes') 9 | 10 | #tuto-emails.line.pa2.question 11 | p.help-text.mt2=t('tutorial question emails') 12 | p.center 13 | button#emails-no.btn=t('tutorial no') 14 | button#emails-yes.btn=t('tutorial yes') 15 | 16 | #tuto-calendar.line.pa2.question 17 | p.help-text.mt2=t('tutorial question calendar') 18 | p.center 19 | button#calendar-no.btn=t('tutorial no') 20 | button#calendar-yes.btn=t('tutorial yes') 21 | 22 | #tuto-contacts.line.pa2.question 23 | p.help-text.mt2=t('tutorial question contacts') 24 | p.center 25 | button#contacts-no.btn=t('tutorial no') 26 | button#contacts-yes.btn=t('tutorial yes') 27 | 28 | #tuto-photos.line.pa2.question 29 | p.help-text.mt2=t('tutorial question photos') 30 | p.center 31 | button#photos-no.btn=t('tutorial no') 32 | button#photos-yes.btn=t('tutorial yes') 33 | 34 | #end-screen.line.pa2.question 35 | p.help-text.mt2=t('tutorial final headline') 36 | ul 37 | li 38 | a(href='https://docs.cozy.io/en/mobile/files.html')=t('tutorial doc files link') 39 | li 40 | a(href='https://docs.cozy.io/en/mobile/contacts.html')=t('tutorial doc contacts link') 41 | li 42 | a(href='https://docs.cozy.io/en/mobile/calendar.html')=t('tutorial doc calendar link') 43 | 44 | p.center 45 | a.btn(href="#home")=t('tutorial final button') 46 | -------------------------------------------------------------------------------- /client/app/templates/update_stack_modal.jade: -------------------------------------------------------------------------------- 1 | .md-content 2 | .md-header.clearfix 3 | .line 4 | h3.left= t('update stack modal title') 5 | .md-body 6 | p.step1= t('update stack modal content') 7 | p.step2= t('update stack waiting message') 8 | p.success= t('update stack success') 9 | .permission-changes 10 | h5= t('update stack warning') 11 | p= t('update stack permission changes') 12 | p.error.stack-error.title= t('update stack error title') 13 | p.error.stack-error= t('update stack error') 14 | p.error.apps-error.title= t('update apps error title') 15 | p.error.apps-error= t('update apps error') 16 | h5.error.apps-error= t('update apps error list title') 17 | 18 | .md-footer.clearfix 19 | button.transparent-grey#cancelbtn= t('cancel') 20 | button.btn#confirmbtn= t('update stack modal confirm') 21 | button#ok= t('ok') 22 | 23 | -------------------------------------------------------------------------------- /client/app/views/background_list.coffee: -------------------------------------------------------------------------------- 1 | ViewCollection = require 'lib/view_collection' 2 | BackgroundListItem = require 'views/background_list_item' 3 | BackgroundCollection = require 'collections/background' 4 | 5 | 6 | 7 | # View to manage the list of available background in the account view. 8 | module.exports = class BackgroundList extends ViewCollection 9 | 10 | itemView: BackgroundListItem 11 | template: require 'templates/background_list' 12 | collection: new BackgroundCollection 13 | events: {} 14 | 15 | 16 | # Init collection with default values. 17 | # Add a change listener to mark the selected background as selected 18 | # and remove the selection from others. 19 | afterRender: -> 20 | @collection.init() 21 | 22 | @collection.on 'change', (changedModel) => 23 | @collection.map (model) => 24 | if changedModel.cid isnt model.cid 25 | model.set {'selected': false}, {silent: true} 26 | @views[model.cid].$el.removeClass 'selected' 27 | 28 | 29 | # Select given background (and fire select events). 30 | select: (background) -> 31 | @views[background.cid].$el.click() 32 | 33 | 34 | # Override to put official background first. 35 | appendView: (view) -> 36 | if view.model.get 'predefined' 37 | @$el.prepend view.el 38 | else 39 | @$el.append view.el 40 | -------------------------------------------------------------------------------- /client/app/views/background_list_item.coffee: -------------------------------------------------------------------------------- 1 | BaseView = require 'lib/base_view' 2 | 3 | 4 | # Row displaying application name and attributes 5 | module.exports = class BackgroundListItem extends BaseView 6 | className: "mod w33 left background-button" 7 | tagName: "div" 8 | template: require 'templates/background_list_item' 9 | events: 10 | 'click .delete-background-button': 'onDeleteClicked' 11 | 'click': 'onClicked' 12 | 13 | 14 | getRenderData: -> 15 | model: 16 | src: @model.getThumbSrc() 17 | 18 | 19 | afterRender: -> 20 | @deleteButton = @$ '.delete-background-button' 21 | @deleteButton.hide() if @model.get 'predefined' 22 | @model.on 'change', => 23 | @$el.addClass 'selected' if @model.get 'selected' 24 | 25 | 26 | # When item is clicked it is marked as selected. 27 | onClicked: -> 28 | @model.set 'selected', true 29 | 30 | 31 | # When delete button is clicked, the model is deleted remotely and the 32 | # current background item is removed from DOM. 33 | onDeleteClicked: -> 34 | @deleteButton.spin true 35 | @model.destroy() 36 | 37 | -------------------------------------------------------------------------------- /client/app/views/config_device.coffee: -------------------------------------------------------------------------------- 1 | BaseView = require 'lib/base_view' 2 | 3 | # Row displaying device name and attributes 4 | module.exports = class DeviceRow extends BaseView 5 | className: "config-device" 6 | tagName: "div" 7 | template: require 'templates/config_device' 8 | 9 | events: 10 | 'click .remove-device': 'onRemoveClicked' 11 | 12 | getRenderData: -> 13 | device: @model.attributes 14 | 15 | constructor: (options) -> 16 | @model = options.model 17 | @id = "device-btn-#{options.model.id}" 18 | super 19 | 20 | onRemoveClicked: (event) -> 21 | if window.confirm t 'revoke device confirmation message' 22 | $(event.currentTarget).spin true 23 | $.ajax("/api/devices/#{@model.get('id')}", 24 | type: "DELETE" 25 | success: => 26 | @$el.fadeOut -> 27 | error: => 28 | @$('.remove-device').html t 'revoke device access' 29 | console.log "error while revoking the device access" 30 | ) 31 | -------------------------------------------------------------------------------- /client/app/views/config_device_list.coffee: -------------------------------------------------------------------------------- 1 | ViewCollection = require 'lib/view_collection' 2 | DeviceRow = require 'views/config_device' 3 | 4 | 5 | module.exports = class DevicesListView extends ViewCollection 6 | id: 'config-device-list' 7 | tagName: 'div' 8 | template: require 'templates/config_device_list' 9 | itemView: require 'views/config_device' 10 | 11 | 12 | constructor: (devices) -> 13 | @devices = devices 14 | super collection: devices 15 | 16 | 17 | afterRender: => 18 | @deviceList = @$ "#device-list" 19 | 20 | -------------------------------------------------------------------------------- /client/app/views/menu_application.coffee: -------------------------------------------------------------------------------- 1 | BaseView = require 'lib/base_view' 2 | 3 | module.exports = class ApplicationView extends BaseView 4 | 5 | tagName: 'div' 6 | className: 'menu-application clearfix' 7 | template: require 'templates/menu_application' 8 | 9 | -------------------------------------------------------------------------------- /client/app/views/menu_applications.coffee: -------------------------------------------------------------------------------- 1 | ViewCollection = require 'lib/view_collection' 2 | 3 | module.exports = class AppsMenu extends ViewCollection 4 | 5 | el:'#menu-applications-container' 6 | itemView: require 'views/menu_application' 7 | template: require 'templates/menu_applications' 8 | 9 | 10 | constructor: (@collection) -> 11 | super 12 | 13 | appendView: (view) -> 14 | 15 | -------------------------------------------------------------------------------- /client/app/views/navbar.coffee: -------------------------------------------------------------------------------- 1 | BaseView = require 'lib/base_view' 2 | appButtonTemplate = require "templates/navbar_app_btn" 3 | NotificationsView = require './notifications_view' 4 | HelpView = require './help' 5 | SearchBarMix = require './search_bar_mix' 6 | AppsMenu = require './menu_applications' 7 | 8 | module.exports = class NavbarView extends BaseView 9 | 10 | el:'.navbar' 11 | template: require 'templates/navbar' 12 | 13 | events: 14 | 'click #help-toggle': 'toggleHelp' 15 | 16 | constructor: (apps, notifications) -> 17 | @apps = apps 18 | @notifications = notifications 19 | super() 20 | 21 | afterRender: => 22 | @notifications = new NotificationsView collection: @notifications 23 | @helpView = new HelpView() 24 | @appMenu = new AppsMenu @apps 25 | @searchBar = new SearchBarMix() 26 | 27 | toggleHelp: (event) -> 28 | event.preventDefault() 29 | @helpView.toggle() 30 | -------------------------------------------------------------------------------- /client/app/views/object_picker_image.coffee: -------------------------------------------------------------------------------- 1 | Photo = require '../models/photo' 2 | LongList = require 'views/image_list' 3 | BaseView = require 'lib/base_view' 4 | 5 | 6 | module.exports = class ObjectPickerImage extends BaseView 7 | 8 | tagName : "section" 9 | 10 | #################### 11 | ## PUBLIC SECTION ## 12 | # 13 | 14 | constructor: (modal) -> 15 | @modal = modal 16 | super() 17 | 18 | 19 | initialize : () -> 20 | #### 21 | # init state 22 | @name = 'thumbPicker' 23 | @tabLabel = 'image' 24 | #### 25 | # get elements (name ends with '$') 26 | @tab = $("
#{@tabLabel}
")[0] 27 | @panel = @el 28 | #### 29 | # construct the long list of images 30 | @longList = new LongList(@panel, @modal) 31 | 32 | 33 | getObject : () -> 34 | file = @longList.getSelectedFile() 35 | if file 36 | return id:file.id, docType: 'file', name:file.name 37 | return false 38 | 39 | 40 | setFocusIfExpected : () -> 41 | # the panel doesn't want the focus because otherwise the arrows keys 42 | # makes thumbs scroll 43 | return false 44 | 45 | setInitialDimensions : (width, heigth) -> 46 | @longList.setInitialDimensions(width, heigth) 47 | 48 | 49 | 50 | keyHandler : (e)-> 51 | @longList.keyHandler(e) 52 | return 53 | 54 | 55 | resizeHandler: () -> 56 | @longList.resizeHandler() 57 | -------------------------------------------------------------------------------- /client/app/widgets/install_button.coffee: -------------------------------------------------------------------------------- 1 | # Small widget used to changed installatio button style easily 2 | module.exports = class ColorButton 3 | 4 | constructor: (@button) -> 5 | @label = @button.find '.label' or @button 6 | 7 | displayGrey: (text) -> 8 | @button.show() 9 | @label.html text 10 | @button.removeClass "btn-red" 11 | @button.removeClass "btn-green" 12 | @button.removeClass "btn-orange" 13 | 14 | 15 | displayOrange: (text) -> 16 | @button.show() 17 | @label.html text 18 | @button.removeClass "btn-red" 19 | @button.removeClass "btn-green" 20 | @button.addClass "btn-orange" 21 | 22 | displayGreen: (text) -> 23 | @button.show() 24 | @label.html text 25 | @button.addClass "btn-green" 26 | @button.removeClass "btn-red" 27 | @button.removeClass "btn-orange" 28 | 29 | displayRed: (text) -> 30 | @button.show() 31 | @label.html text 32 | @button.removeClass "btn-green" 33 | @button.addClass "btn-red" 34 | @button.removeClass "btn-orange" 35 | 36 | hide: -> 37 | @button.hide() 38 | 39 | show: -> 40 | @button.show() 41 | 42 | isGreen: -> 43 | @button.hasClass "btn-green" 44 | 45 | spin: (toggle) -> 46 | @button.spin toggle 47 | 48 | isHidden: -> 49 | return not @button.is(":visible") 50 | 51 | 52 | -------------------------------------------------------------------------------- /client/config.coffee: -------------------------------------------------------------------------------- 1 | exports.config = 2 | # Edit the next line to change default build path. 3 | config: 4 | path: 5 | public:'public' 6 | 7 | files: 8 | javascripts: 9 | # Describes how files will be compiled & joined together. 10 | # Available formatsu 11 | # * 'outputFilePath' 12 | # * map of ('outputFilePath': /regExp that matches input path/) 13 | # * map of ('outputFilePath': function that takes input path) 14 | joinTo: 15 | 'javascripts/app.js': /^app/ 16 | 'javascripts/vendor.js': /^vendor/ 17 | 18 | # Defines compilation order. 19 | # `vendor` files will be compiled before other ones 20 | # even if they are not present here. 21 | order: 22 | before: [ 23 | 'vendor/scripts/console-helper.js' 24 | 'vendor/scripts/jquery-1.7.1.js' 25 | 'vendor/scripts/underscore-1.4.4.js' 26 | 'vendor/scripts/backbone-1.0.0.js' 27 | 'vendor/scripts/jquery-ui-1.10.3.custom.js' 28 | ] 29 | 30 | stylesheets: 31 | defaultExtension: 'styl' 32 | joinTo: 'stylesheets/app.css' 33 | order: 34 | before: ['vendor/styles/bootstrap.css'] 35 | 36 | templates: 37 | defaultExtension: 'jade' 38 | joinTo: 'javascripts/app.js' 39 | 40 | # Change this if you're using something other than backbone (e.g. 'ember'). 41 | # Content of files, generated with `brunch generate` depends on the setting. 42 | # framework: 'backbone' 43 | 44 | # Enable or disable minifying of result js / css files. 45 | minify: no 46 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Your Name", 3 | "name": "package-name", 4 | "description": "Package description", 5 | "version": "0.8.0", 6 | "homepage": "", 7 | "repository": { 8 | "type": "git", 9 | "url": "" 10 | }, 11 | "engines": { 12 | "node": "~0.6.10 || 0.8 || 0.9" 13 | }, 14 | "scripts": { 15 | "start": "brunch watch --server", 16 | "test": "brunch test" 17 | }, 18 | "dependencies": { 19 | "brunch": "1.8.5", 20 | "clean-css-brunch": "1.7.1", 21 | "coffee-script-brunch": "1.7.3", 22 | "css-brunch": "1.7.0", 23 | "jade-brunch": "1.5.1", 24 | "javascript-brunch": "1.7.1", 25 | "json-brunch": "^1.5.4", 26 | "stylus-brunch": "1.8.0", 27 | "uglify-js-brunch": "1.7.6" 28 | }, 29 | "devDependencies": { 30 | "chai": "1.9.0", 31 | "jquery": "2.1.0", 32 | "request": "2.33.0", 33 | "sinon": "1.8.1", 34 | "sinon-chai": "2.5.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /client/test-functional/helpers.coffee: -------------------------------------------------------------------------------- 1 | utils = require "../../lib/passport_utils" 2 | 3 | exports.init = (withUser, callback) -> 4 | app = new Application 5 | name: "Notes" 6 | state: "installed" 7 | index: 0 8 | slug: "notes" 9 | icon: "notes_icon.png" 10 | description: """ 11 | Organize your interests 12 | """ 13 | 14 | hash = utils.cryptPassword "password" 15 | 16 | user = new User 17 | email: "test@mycozycloud.com" 18 | owner: true 19 | password: hash 20 | activated: true 21 | url: "http://localhost:3000/" 22 | 23 | exports.clearAll -> 24 | app.save -> 25 | if withUser 26 | user.save -> callback() 27 | else 28 | callback() 29 | 30 | exports.clearAll = (callback) -> 31 | Application.destroyAll -> 32 | User.destroyAll -> 33 | callback() 34 | 35 | exports.waits = (done, time) -> 36 | func = -> done() 37 | setTimeout(func, time) 38 | -------------------------------------------------------------------------------- /client/test-functional/register.coffee: -------------------------------------------------------------------------------- 1 | should = require("should") 2 | Browser = require("../../common/test/browser").Browser 3 | helpers = require("./helpers") 4 | 5 | app = require("../../server") 6 | 7 | email = "test@mycozycloud.com" 8 | password = "password" 9 | 10 | 11 | describe "Register", -> 12 | 13 | before (done) -> 14 | app.listen 3000 15 | helpers.init false, done 16 | 17 | before (done) -> 18 | @browser = new Browser() 19 | @browser.visit "http://localhost:3000/", => 20 | done() 21 | 22 | it "When I connect the first time on my cozy", -> 23 | 24 | it "Then I expect that register form is displayed", -> 25 | should.exist @browser.query("#register-email") 26 | should.exist @browser.query("#register-password") 27 | @browser.isVisible("#buttons").should.not.be.ok 28 | 29 | it "When I fill form with default credentials", -> 30 | @browser.fill "#register-email", email 31 | @browser.fill "#register-password", password 32 | 33 | it "And submit it", (done) -> 34 | @browser.enterKeyUp "#register-password" 35 | helpers.waits done, 600 36 | 37 | it "Navigation buttons and application list are displayed", -> 38 | @browser.isVisible("#buttons").should.be.ok 39 | @browser.isVisible("#home-view").should.be.ok 40 | 41 | after (done) -> 42 | helpers.clearAll -> 43 | app.close() 44 | done() 45 | 46 | -------------------------------------------------------------------------------- /client/test/application_collection_test.coffee: -------------------------------------------------------------------------------- 1 | {ApplicationCollection} = require "collections/application" 2 | {Application} = require "models/application" 3 | {ApplicationsView} = require "views/applications_view" 4 | 5 | describe 'Application Collection', -> 6 | 7 | before -> 8 | @view = new ApplicationsView() 9 | @view.render() 10 | @view.setListeners() 11 | @apps = new ApplicationCollection @view 12 | 13 | after -> 14 | 15 | 16 | describe "binding reset", -> 17 | 18 | it "When I add 3 apps silently to the collection and fire reset event", -> 19 | @apps.add new Application 20 | name: "app 01" 21 | , silent: true 22 | @apps.add new Application 23 | name: "app 02" 24 | , silent: true 25 | @apps.add new Application 26 | name: "app 03" 27 | , silent: true 28 | @apps.onReset() 29 | 30 | it "Then it displays 3 apps inside app list", -> 31 | expect(@view.$("#app-list .application").length).to.equal 3 32 | 33 | describe "binding add", -> 34 | 35 | it "When I add 1 app to the collection", -> 36 | @view.clearApps() 37 | @apps.reset [] 38 | @apps.add new Application 39 | name: "app 01" 40 | 41 | 42 | it "Then it displays 1 app inside app list", -> 43 | expect(@view.$("#app-list .application").length).to.equal 1 44 | 45 | -------------------------------------------------------------------------------- /client/test/home_view_test.coffee: -------------------------------------------------------------------------------- 1 | {HomeView} = require "views/home_view" 2 | {Application} = require "initialize" 3 | 4 | 5 | describe 'Manage applications', -> 6 | 7 | before -> 8 | 9 | @view = new HomeView() 10 | @view.render() 11 | @view.setListeners() 12 | 13 | describe "unit tests", -> 14 | 15 | it "home", -> 16 | @view.home() 17 | expect(@view.homeButton.parent().hasClass "active").to.be.ok 18 | 19 | it "account", -> 20 | @view.account() 21 | expect(@view.accountButton.parent().hasClass "active").to.be.ok 22 | 23 | it "selectNavButton", -> 24 | @view.selectNavButton @view.homeButton 25 | expect(@view.homeButton.parent().hasClass "active").to.be.ok 26 | @view.selectNavButton @view.accountButton 27 | expect(@view.accountButton.parent().hasClass "active").to.be.ok 28 | 29 | it "addApplication", -> 30 | # Don't know why, it restarts backbone historty... 31 | #@view.addApplication new Application 32 | #name: "app 01" 33 | #slug: "app-01" 34 | #expect(@view.$(".app-button").length).to.equal 1 35 | 36 | it "clearApps", -> 37 | @view.clearApps() 38 | expect(@view.$(".app-button").length).to.equal 0 39 | 40 | it "loadApp", -> 41 | # Don't know why, it restarts backbone historty... 42 | #app1 = new Application 43 | #name: "app 01" 44 | #slug: "app-01" 45 | 46 | 47 | -------------------------------------------------------------------------------- /client/test/test-helpers.coffee: -------------------------------------------------------------------------------- 1 | # This file will be automatically required when using `brunch test` command. 2 | module.exports = 3 | expect: require('chai').expect 4 | sinon: require 'sinon' 5 | $: require('jquery') 6 | 7 | 8 | -------------------------------------------------------------------------------- /client/vendor/scripts/color-hash.js: -------------------------------------------------------------------------------- 1 | var ColorHash = (function () { 2 | 3 | var schemes = { 4 | "base" : [ 5 | "00bb3f", "238c47", "007929", "37dd6f", "63dd8d", 6 | "0f4fa8", "284c7e", "05316d", "4380d3", "6996d3", 7 | "ff9f00", "bf8930", "a66800", "ffb740", "ffca73", 8 | "ff2800", "bf4630", "a61a00", "ff5d40", "ff8973" 9 | ] 10 | }; 11 | 12 | function hashCode(str) { 13 | var h, i, len, max; 14 | 15 | h = 0; 16 | max = Math.pow(2, 32); 17 | 18 | for (i = 0, len = str.length; i < len; i++) { 19 | h = (h * 31 + str.charCodeAt(i)) % max; 20 | } 21 | 22 | return h; 23 | } 24 | 25 | function getColor(str, name) { 26 | var scheme, hash; 27 | 28 | scheme = schemes[name] || schemes.base; 29 | hash = hashCode(str); 30 | 31 | return "#" + scheme[hash % scheme.length]; 32 | } 33 | 34 | function addScheme(name, scheme) { 35 | schemes[name] = scheme; 36 | } 37 | 38 | function getScheme(name) { 39 | return scheme[name]; 40 | } 41 | 42 | function deleteScheme(name) { 43 | if (name !== "base") { 44 | delete schemes[name]; 45 | } 46 | } 47 | 48 | return { 49 | "addScheme" : addScheme, 50 | "getScheme" : getScheme, 51 | "deleteScheme" : deleteScheme, 52 | 53 | "getHash" : hashCode, 54 | "getColor" : getColor 55 | } 56 | 57 | }()); 58 | -------------------------------------------------------------------------------- /client/vendor/scripts/console-helper.js: -------------------------------------------------------------------------------- 1 | (function (con) { 2 | // the dummy function 3 | function dummy() {}; 4 | // console methods that may exist 5 | for(var methods = "assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profileEnd,time,timeEnd,trace,warn".split(','), func; func = methods.pop();) { 6 | con[func] = con[func] || dummy; 7 | } 8 | }(window.console = window.console || {})); 9 | // we do this crazy little dance so that the `console` object 10 | // inside the function is a name that can be shortened to a single 11 | // letter by the compressor to make the compressed script as tiny 12 | // as possible. -------------------------------------------------------------------------------- /client/vendor/scripts/spinner.js: -------------------------------------------------------------------------------- 1 | 2 | (function($,window,undefined){ 3 | 4 | $.fn.spin = function(doSpin) { 5 | if(doSpin){ 6 | this.height(this.outerHeight()); 7 | this.width(this.outerWidth()); 8 | this.data('spinner-content-was', this.contents()); 9 | spinWhite = this.hasClass('btn') && !this.hasClass('spin-black'); 10 | this.html('
' + 11 | '' + 12 | '
'); 13 | }else{ 14 | this.css({width: '', height: ''}); 15 | this.empty().append(this.data('spinner-content-was')); 16 | } 17 | return this; 18 | }; 19 | 20 | })(jQuery,this); 21 | -------------------------------------------------------------------------------- /client/vendor/styles/farbtastic.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Farbtastic Color Picker 1.2 3 | * © 2008 Steven Wittens 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | .farbtastic { 20 | position: relative; 21 | } 22 | .farbtastic * { 23 | position: absolute; 24 | cursor: crosshair; 25 | } 26 | .farbtastic, .farbtastic .wheel { 27 | width: 195px; 28 | height: 195px; 29 | } 30 | .farbtastic .color, .farbtastic .overlay { 31 | top: 47px; 32 | left: 47px; 33 | width: 101px; 34 | height: 101px; 35 | } 36 | .farbtastic .wheel { 37 | background: url(/img/wheel.png) no-repeat; 38 | width: 195px; 39 | height: 195px; 40 | } 41 | .farbtastic .overlay { 42 | background: url(/img/mask.png) no-repeat; 43 | } 44 | .farbtastic .marker { 45 | width: 17px; 46 | height: 17px; 47 | margin: -8px 0 0 -8px; 48 | overflow: hidden; 49 | background: url(/img/marker.png) no-repeat; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /client/vendor/styles/nanoscroller.css: -------------------------------------------------------------------------------- 1 | /** initial setup **/ 2 | .nano { 3 | position : relative; 4 | width : 100%; 5 | height : 100%; 6 | overflow : hidden; 7 | } 8 | .nano .content { 9 | position : absolute; 10 | overflow : scroll; 11 | overflow-x : hidden; 12 | top : 0; 13 | right : 0; 14 | bottom : 0; 15 | left : 0; 16 | } 17 | .nano .content:focus { 18 | outline: thin dotted; 19 | } 20 | .nano .content::-webkit-scrollbar { 21 | visibility: hidden; 22 | } 23 | .has-scrollbar .content::-webkit-scrollbar { 24 | visibility: visible; 25 | } 26 | .nano > .pane { 27 | background : rgba(0,0,0,.25); 28 | position : absolute; 29 | width : 10px; 30 | right : 0; 31 | top : 0; 32 | bottom : 0; 33 | visibility : hidden\9; /* Target only IE7 and IE8 with this hack */ 34 | opacity : .01; 35 | -webkit-transition : .2s; 36 | -moz-transition : .2s; 37 | -o-transition : .2s; 38 | transition : .2s; 39 | -moz-border-radius : 5px; 40 | -webkit-border-radius : 5px; 41 | border-radius : 5px; 42 | } 43 | .nano > .pane > .slider { 44 | background: #444; 45 | background: rgba(0,0,0,.5); 46 | position : relative; 47 | margin : 0 1px; 48 | -moz-border-radius : 3px; 49 | -webkit-border-radius : 3px; 50 | border-radius : 3px; 51 | } 52 | .nano:hover > .pane, .pane.active, .pane.flashed { 53 | visibility : visible\9; /* Target only IE7 and IE8 with this hack */ 54 | opacity : 0.99; 55 | } 56 | -------------------------------------------------------------------------------- /client/vendor/styles/resizable.css: -------------------------------------------------------------------------------- 1 | .ui-widget-overlay { 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | width: 100%; 6 | height: 100%; 7 | } 8 | .ui-resizable { 9 | position: relative; 10 | } 11 | .ui-resizable-handle { 12 | position: absolute; 13 | font-size: 0.1px; 14 | display: block; 15 | } 16 | .ui-resizable-disabled .ui-resizable-handle, 17 | .ui-resizable-autohide .ui-resizable-handle { 18 | display: none; 19 | } 20 | .ui-resizable-n { 21 | cursor: n-resize; 22 | height: 7px; 23 | width: 100%; 24 | top: -5px; 25 | left: 0; 26 | } 27 | .ui-resizable-s { 28 | cursor: s-resize; 29 | height: 7px; 30 | width: 100%; 31 | bottom: -5px; 32 | left: 0; 33 | } 34 | .ui-resizable-e { 35 | cursor: e-resize; 36 | width: 7px; 37 | right: -5px; 38 | top: 0; 39 | height: 100%; 40 | } 41 | .ui-resizable-w { 42 | cursor: w-resize; 43 | width: 7px; 44 | left: -5px; 45 | top: 0; 46 | height: 100%; 47 | } 48 | .ui-resizable-se { 49 | cursor: se-resize; 50 | width: 12px; 51 | height: 12px; 52 | right: 1px; 53 | bottom: 1px; 54 | } 55 | .ui-resizable-sw { 56 | cursor: sw-resize; 57 | width: 9px; 58 | height: 9px; 59 | left: -5px; 60 | bottom: -5px; 61 | } 62 | .ui-resizable-nw { 63 | cursor: nw-resize; 64 | width: 9px; 65 | height: 9px; 66 | left: -5px; 67 | top: -5px; 68 | } 69 | .ui-resizable-ne { 70 | cursor: ne-resize; 71 | width: 9px; 72 | height: 9px; 73 | right: -5px; 74 | top: -5px; 75 | } -------------------------------------------------------------------------------- /coffeelint.json: -------------------------------------------------------------------------------- 1 | { 2 | "indentation" : { 3 | "value" : 4, 4 | "level" : "error" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /init.coffee: -------------------------------------------------------------------------------- 1 | Photo = require './server/models/photo' 2 | File = require './server/models/file' 3 | thumb = require('./server/helpers/thumb').create 4 | async = require 'async' 5 | 6 | onThumbCreation = false 7 | percent = null 8 | total_files = 0 9 | thumb_files = 0 10 | 11 | module.exports.onThumbCreation = () -> 12 | return [thumb_files isnt total_files, (thumb_files / total_files) * 100] 13 | 14 | convertImage = (cb) -> 15 | convert = (doc, callback) -> 16 | if doc._attachments? 17 | try 18 | console.log "Convert #{doc.title} ..." 19 | doc.convertBinary (err, res, body) -> 20 | console.log err if err? 21 | callback err 22 | catch error 23 | console.log "Cannot convert #{doc.title}" 24 | callback() 25 | else 26 | callback() 27 | Photo.all (err, docs) -> 28 | async.eachSeries(docs, convert, cb) 29 | 30 | createThumb = (socket, cb) -> 31 | # Recover all file without thumb 32 | File.withoutThumb (err, files) -> 33 | total_files = files.length 34 | # Create thumb and check progress 35 | async.eachSeries files, (file, callback) -> 36 | thumb file, () -> 37 | thumb_files += 1 38 | percent = Math.floor((thumb_files / total_files) * 100) 39 | # Emit thumb creation progress 40 | socket.emit 'progress', {"percent": percent} 41 | callback() 42 | , cb 43 | 44 | # Create all requests and upload directory 45 | module.exports.convert = (socket, done=->null) -> 46 | #convertImage (err) -> 47 | onThumbCreation = true 48 | createThumb socket, -> 49 | onThumbCreation = false 50 | done() 51 | -------------------------------------------------------------------------------- /log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozy/cozy-home-v2/61a5467d89eadd31469f442ecf4072a7f86ba4db/log/.gitkeep -------------------------------------------------------------------------------- /postinstall.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var spawn = require('child_process').spawn; 4 | var major = process.versions.node.split('.')[0]; 5 | var bcrypt = 'bcrypt@0.8.7'; 6 | 7 | if (major === '0') { 8 | bcrypt = 'bcrypt@0.8.1'; 9 | } 10 | spawn('npm', ['install', bcrypt], { stdio: 'inherit' }); 11 | -------------------------------------------------------------------------------- /server.coffee: -------------------------------------------------------------------------------- 1 | process.on 'uncaughtException', (err) -> 2 | console.error err 3 | console.error err.stack 4 | 5 | 6 | application = module.exports = (callback) -> 7 | americano = require 'americano' 8 | request = require 'request-json' 9 | localization = require './server/helpers/localization_manager' 10 | initProxy = require './server/initializers/proxy' 11 | setupRealtime = require './server/initializers/realtime' 12 | versionChecking = require './server/initializers/updates' 13 | autoStop = require './server/lib/autostop' 14 | 15 | options = 16 | name: 'Cozy Home' 17 | port: process.env.PORT or 9103 18 | host: process.env.HOST or "127.0.0.1" 19 | root: __dirname 20 | 21 | americano.start options, (err, app, server) -> 22 | app.server = server 23 | 24 | if process.env.NODE_ENV isnt "test" 25 | initProxy() 26 | 27 | localization.initialize -> 28 | setupRealtime app, -> 29 | versionChecking() 30 | autoStop.init() 31 | callback app, server if callback? 32 | 33 | if not module.parent 34 | application() 35 | 36 | -------------------------------------------------------------------------------- /server/config.coffee: -------------------------------------------------------------------------------- 1 | americano = require 'americano' 2 | fs = require 'fs' 3 | path = require 'path' 4 | 5 | clientPath = path.resolve(__dirname, '..', 'client', 'public') 6 | useBuildView = fs.existsSync path.resolve(__dirname, 'views', 'index.js') 7 | 8 | config = 9 | 10 | common: 11 | set: 12 | 'view engine': if useBuildView then 'js' else 'jade' 13 | 'views': path.resolve __dirname, 'views' 14 | engine: 15 | js: (path, locales, callback) -> 16 | callback null, require(path)(locales) 17 | use: [ 18 | americano.bodyParser() 19 | americano.methodOverride() 20 | americano.errorHandler 21 | dumpExceptions: true 22 | showStack: true 23 | americano.static clientPath, 24 | maxAge: 86400000 25 | ] 26 | 27 | development: [ 28 | americano.logger 'dev' 29 | ] 30 | 31 | production: [ 32 | americano.logger 'short' 33 | ] 34 | 35 | plugins: [ 36 | 'cozydb' 37 | ] 38 | 39 | module.exports = config 40 | -------------------------------------------------------------------------------- /server/controllers/backgrounds.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | multiparty = require 'multiparty' 3 | localizationManager = require '../helpers/localization_manager' 4 | Background = require '../models/background' 5 | 6 | baseController = new cozydb.SimpleController 7 | model: Background 8 | reqParamID: 'backgroundid' 9 | 10 | 11 | # Controllers to manage CRUD operations on user backgrounds. 12 | module.exports = 13 | 14 | fetch: baseController.fetch 15 | all: baseController.listAll 16 | delete: baseController.destroy 17 | picture: baseController.sendBinary filename: 'file' 18 | thumb: baseController.sendBinary filename: 'thumb' 19 | 20 | # Creation is a little bit special. It requires to uplaod a picture to 21 | # create the background. 22 | create: (req, res, next) -> 23 | res.on 'close', -> req.abort() 24 | 25 | # Extract picture from upload form. 26 | form = new multiparty.Form() 27 | form.parse req, (err, fields, files) -> 28 | 29 | if err 30 | next err 31 | 32 | else if files? and files.picture? and files.picture.length > 0 33 | file = files.picture[0] 34 | 35 | # Create a background and persist its files (thumb and 36 | # picture). 37 | Background.createNew file.path, (err, background) -> 38 | return next err if err 39 | res.send background 40 | 41 | else 42 | next new Error localizationManager.t 'cant change background' 43 | 44 | -------------------------------------------------------------------------------- /server/controllers/devices.coffee: -------------------------------------------------------------------------------- 1 | Client = require("request-json").JsonClient 2 | fs = require('fs') 3 | Device = require '../models/device' 4 | 5 | # we need to access the DS directly because the /device/ api 6 | # is specific therefore not handled by the ODM 7 | ds = new Client "http://localhost:9101/" 8 | 9 | # auth is required only in test and production env 10 | if process.env.NODE_ENV in ['test', 'production'] 11 | ds.setBasicAuth process.env.NAME, process.env.TOKEN 12 | 13 | module.exports = 14 | 15 | devices: (req, res, next) -> 16 | Device.all (err, devices) -> 17 | if err then next err 18 | else res.send rows: devices 19 | 20 | remove: (req, res, next) -> 21 | id = req.params.deviceid 22 | Device.find id, (err, device) -> 23 | if err? then next err 24 | else 25 | # proper removal of the device (device doc and filter) 26 | ds.del "access/#{id}/", (err, response, body) -> 27 | log.error err if err 28 | device.destroy (err) -> 29 | err = err or body.error 30 | if err? then next err 31 | else 32 | res.status(200).send success: true 33 | -------------------------------------------------------------------------------- /server/controllers/logs.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | logs = require '../lib/logs' 3 | log = require('printit') 4 | prefix: 'home:client' 5 | localizationManager = require '../helpers/localization_manager' 6 | 7 | module.exports = 8 | 9 | # This controller pipes the log file corresponding to given app slug. 10 | # It loads them from the folder /usr/local/var/log/cozy. 11 | logs: (req, res, next) -> 12 | filepath = logs.getLogPath req.params.moduleslug 13 | 14 | fs.exists filepath, (exists) -> 15 | if exists 16 | stream = fs.createReadStream("#{filepath}") 17 | # Set text/plain header so that the log can be opened in the 18 | # browser. 19 | res.set 20 | 'Content-Type': 'text/plain' 21 | # We remove color markers during the stream. 22 | stream.on 'data', (data) -> 23 | res.write data.toString().replace logs.colors, '' 24 | stream.on 'end', -> 25 | res.end() 26 | else 27 | res.status(404).send localizationManager.t 'file not found' 28 | # Log client errors 29 | logClient: (req, res) -> 30 | log.error req.body.data 31 | log.error req.body.data.error?.stack 32 | res.send 'ok' 33 | -------------------------------------------------------------------------------- /server/controllers/monitor.coffee: -------------------------------------------------------------------------------- 1 | {MemoryManager} = require('../lib/memory') 2 | 3 | module.exports = 4 | # Return as JSON data about memory and hard disk consumption 5 | sysData: (req, res, next) -> 6 | memoryManager = new MemoryManager() 7 | memoryManager.getDiskInfos (err, diskInfos) -> 8 | 9 | if err then next err 10 | else memoryManager.getMemoryInfos (err, memoryInfos) -> 11 | 12 | if err then next err 13 | else 14 | data = diskInfos 15 | data[prop] = value for prop, value of memoryInfos 16 | res.send data 17 | -------------------------------------------------------------------------------- /server/controllers/proxy.coffee: -------------------------------------------------------------------------------- 1 | request = require('request') 2 | 3 | # a simple proxy... 4 | module.exports.get = (req, res) -> 5 | req.pipe(request(req.query.url)).pipe(res) 6 | -------------------------------------------------------------------------------- /server/controllers/stack_application.coffee: -------------------------------------------------------------------------------- 1 | request = require("request-json") 2 | fs = require('fs') 3 | slugify = require 'cozy-slug' 4 | spawn = require('child_process').spawn 5 | log = require('printit') 6 | prefix: "applications" 7 | 8 | {AppManager} = require '../lib/paas' 9 | StackApplication = require '../models/stack_application' 10 | localizationManager = require '../helpers/localization_manager' 11 | 12 | 13 | sendError = (res, err, code=500) -> 14 | err ?= 15 | stack: null 16 | message: localizationManager.t "server error" 17 | 18 | console.log "Sending error to client:" 19 | console.log err.stack 20 | 21 | res.status(code).send 22 | error: true 23 | success: false 24 | message: err.message 25 | stack: err.stack 26 | 27 | 28 | module.exports = 29 | 30 | 31 | get: (req, res, next) -> 32 | StackApplication.all (err, apps) -> 33 | if err then next err 34 | else res.send rows: apps 35 | 36 | 37 | update: (req, res, next) -> 38 | manager = new AppManager() 39 | manager.updateStack (err, result) -> 40 | if err? 41 | log.error err 42 | sendError res, err 43 | else 44 | res.send success: true 45 | 46 | 47 | reboot: (req, res, next) -> 48 | manager = new AppManager() 49 | manager.restartController (err, result) -> 50 | if err? 51 | log.error err 52 | sendError res, err 53 | else 54 | res.send success: true 55 | 56 | -------------------------------------------------------------------------------- /server/controllers/usetrackers.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | App usage tracking 3 | ### 4 | 5 | moment = require 'moment-timezone' 6 | UseTracker = require '../models/usetracker' 7 | 8 | TIMING = 10 * 1000 # 10s 9 | appTracker = {} 10 | 11 | module.exports = 12 | heartbeat: (req, res, next) -> 13 | appName = req.body.appName 14 | 15 | # Tracking logic 16 | if not appTracker[appName]? 17 | appTracker[appName] = 18 | dateStart: req.body.timestamp 19 | dateEnd: null 20 | timeout: null 21 | 22 | appInfo = appTracker[appName] 23 | appInfo.dateEnd = req.body.timestamp 24 | clearTimeout appInfo.timeout 25 | # When the timeout proc, the session is considered terminated 26 | appInfo.timeout = setTimeout -> 27 | duration = moment(appInfo.dateEnd) - moment(appInfo.dateStart) 28 | # Actually, precision is just up to 1s. 29 | duration = Math.round(duration / 1000) * 1000 30 | 31 | data = 32 | app: appName 33 | dateStart: appInfo.dateStart 34 | dateEnd: appInfo.dateEnd 35 | duration: duration 36 | delete appTracker[appName] 37 | UseTracker.create data, (err, res, body) -> 38 | console.log "Couldn't add app tracking info -- #{err}" if err? 39 | , TIMING 40 | 41 | res.status(201).send('ok') 42 | -------------------------------------------------------------------------------- /server/helpers/downloader.coffee: -------------------------------------------------------------------------------- 1 | http = require 'http' 2 | 3 | # Module to handle file download with the low level http api instead of 4 | # request. This is due to a too high memory consumption while dowloading big 5 | # files with request. 6 | module.exports = 7 | 8 | # Returns the file in a callback as a readable stream of data. 9 | download: (path, callback) -> 10 | id = process.env.NAME 11 | pwd = process.env.TOKEN 12 | 13 | basic = "Basic #{new Buffer("#{id}:#{pwd}").toString('base64')}" 14 | options = 15 | host: 'localhost' 16 | port: 9101 17 | path: path 18 | headers: 19 | Authorization: basic 20 | 21 | http.get options, callback 22 | -------------------------------------------------------------------------------- /server/helpers/errors.coffee: -------------------------------------------------------------------------------- 1 | 2 | module.exports.NotFound = (what) -> 3 | err = new Error what + ': Not Found' 4 | err.status = 404 5 | return err 6 | 7 | 8 | module.exports.NotAllowed = -> 9 | err = new Error 'Not allowed' 10 | err.status = 401 11 | return err 12 | 13 | module.exports.BadUsage = -> 14 | err = new Error 'Bad Usage' 15 | err.status = 400 16 | return err 17 | -------------------------------------------------------------------------------- /server/helpers/localization_manager.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | Polyglot = require 'node-polyglot' 3 | Instance = require '../models/cozyinstance' 4 | 5 | # Seeks the proper locale files, depending if we run from build/ or from sources 6 | path = require 'path' 7 | LOCALE_PATH = path.resolve __dirname, '../locales' 8 | 9 | class LocalizationManager 10 | 11 | polyglot: null 12 | defaultPolyglot: null 13 | 14 | # should be run when app starts 15 | initialize: (callback) -> 16 | @retrieveLocale (err, locale) => 17 | if err? then callback err 18 | else 19 | @polyglot = @getPolyglotByLocale locale 20 | callback null, @polyglot 21 | 22 | retrieveLocale: (callback) -> 23 | Instance.getLocale (err, locale) -> 24 | if err? or not locale then locale = 'en' # default value 25 | callback err, locale 26 | 27 | getPolyglotByLocale: (locale) -> 28 | defaultPhrases = require "#{LOCALE_PATH}/en" 29 | try 30 | phrases = require "#{LOCALE_PATH}/#{locale}" 31 | catch err 32 | phrases = defaultPhrases 33 | @defaultPolyglot = new Polyglot 34 | locale: 'en' 35 | phrases: defaultPhrases 36 | return new Polyglot locale: locale, phrases: phrases 37 | 38 | # execute polyglot.t, for server-side localization 39 | t: (key, params = {}) -> 40 | unless params._? 41 | params._ = @defaultPolyglot?.t key, params 42 | return @polyglot?.t(key, params) or key 43 | 44 | # for template localization 45 | getPolyglot: -> return @polyglot 46 | 47 | module.exports = new LocalizationManager() 48 | -------------------------------------------------------------------------------- /server/helpers/thumb.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | im = require 'imagemagick' 3 | 4 | resize = (raw, file, name, callback) -> 5 | options = 6 | mode: 'crop' 7 | width: 300 8 | height: 300 9 | 10 | options.srcPath = raw 11 | options.dstPath = "/tmp/2-#{file.name}" 12 | 13 | # create files 14 | fs.openSync options.dstPath, 'w' 15 | 16 | # create a resized file and push it to db 17 | im[options.mode] options, (err, stdout, stderr) -> 18 | return callback err if err 19 | file.attachBinary options.dstPath, {name}, (err) -> 20 | fs.unlink options.dstPath, -> 21 | callback err 22 | 23 | 24 | module.exports.create = (file, callback) -> 25 | return callback new Error('no binary') unless file.binary? 26 | if file.binary?.thumb? 27 | console.log "createThumb #{file.id} : already done" 28 | callback() 29 | else 30 | rawFile = "/tmp/#{file.name}" 31 | fs.open rawFile, 'w', (err) -> 32 | stream = file.getBinary 'file', (err) -> 33 | return callback err if err 34 | stream.pipe fs.createWriteStream rawFile 35 | stream.on 'error', callback 36 | stream.on 'end', -> 37 | resize rawFile, file, 'thumb', (err) -> 38 | fs.unlink rawFile, -> 39 | console.log "createThumb #{file.id} : done" 40 | callback(err) 41 | -------------------------------------------------------------------------------- /server/lib/adapter.coffee: -------------------------------------------------------------------------------- 1 | request = require("request-json") 2 | 3 | client = request.createClient "http://localhost:9101/" 4 | 5 | 6 | module.exports = class Adapter 7 | 8 | updateKeys: (pwd, callback) -> 9 | 10 | # Authentication required by the Data System 11 | if process.env.NODE_ENV in ['production', 'test'] 12 | 13 | name = process.env.NAME 14 | token = process.env.TOKEN 15 | client.setBasicAuth name, token 16 | 17 | # Update password 18 | client.put "accounts/password/", password: pwd, (err, res, body) -> 19 | callback err 20 | 21 | initializeKeys: (pwd, callback) -> 22 | 23 | # Authentication required by the Data System 24 | if process.env.NODE_ENV in ['production', 'test'] 25 | 26 | name = process.env.NAME 27 | token = process.env.TOKEN 28 | client.setBasicAuth name, token 29 | 30 | # Update password 31 | client.post "accounts/password/", password: pwd, (err, res, body) -> 32 | callback err 33 | 34 | 35 | updateUser: (user, data, callback) -> 36 | 37 | # Authentication required by the Data System 38 | if process.env.NODE_ENV in ['production', 'test'] 39 | 40 | name = process.env.NAME 41 | token = process.env.TOKEN 42 | client.setBasicAuth name, token 43 | 44 | # Update password 45 | client.put "user/merge/#{user.id}", data, (err, res, body) -> 46 | callback err 47 | 48 | -------------------------------------------------------------------------------- /server/lib/logging.coffee: -------------------------------------------------------------------------------- 1 | fs = require 'fs' 2 | path = require 'path' 3 | 4 | exports.stream = null 5 | 6 | exports.init = (compound, callback) -> 7 | app = compound.app 8 | logDir = path.join compound.root, 'log' 9 | logFile = path.join logDir, app.get('env') + '.log' 10 | 11 | fs.exists logDir, (exists) -> 12 | if exists 13 | options = 14 | flags: 'a', 15 | mode: 0o0666, 16 | encoding: 'utf8' 17 | exports.stream = fs.createWriteStream logFile, options 18 | callback exports.stream 19 | else 20 | callback null 21 | 22 | exports.write = (text) -> 23 | stream = exports.stream || process.stdout 24 | stream.write text + '\n' || console.log text 25 | -------------------------------------------------------------------------------- /server/lib/passport_utils.coffee: -------------------------------------------------------------------------------- 1 | bcrypt = require('bcrypt') 2 | 3 | # Crypt given password with bcrypt algorithm. 4 | exports.cryptPassword = (password) -> 5 | salt = bcrypt.genSaltSync(10) 6 | hash = bcrypt.hashSync(password, salt) 7 | hash 8 | 9 | exports.checkPassword = (password, hash) -> 10 | bcrypt.compareSync password, hash -------------------------------------------------------------------------------- /server/models/alarm.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | 3 | module.exports = Alarm = cozydb.getModel 'Alarm', 4 | action: type: String, default: 'DISPLAY' 5 | trigg: String 6 | rrule: String 7 | timezone: String 8 | description: String 9 | related: type: String, default: null 10 | 11 | Alarm.all = (params, callback) -> 12 | Alarm.request "all", params, callback 13 | -------------------------------------------------------------------------------- /server/models/album.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | async = require 'async' 3 | Photo = require './photo' 4 | 5 | 6 | sanitize = (data) -> 7 | if data.title? 8 | data.title = data.title 9 | .replace /
/g, "" 10 | .replace /
/g, "" 11 | .replace /<\/div>/g, "" 12 | 13 | # Set default date if not set. 14 | data.date ?= new Date() 15 | 16 | 17 | module.exports = class Album extends cozydb.CozyModel 18 | @schema: 19 | id : String 20 | title : String 21 | description : String 22 | date : Date 23 | orientation : Number 24 | coverPicture : String 25 | clearance : cozydb.NoSchema 26 | folderid : String 27 | 28 | updateAttributes: (data) -> 29 | sanitize data 30 | super 31 | 32 | @create: (data) -> 33 | sanitize data 34 | super 35 | 36 | @listWithThumbs: (callback) -> 37 | async.parallel [ 38 | (cb) -> Album.request 'byTitle', cb 39 | (cb) -> Photo.albumsThumbs cb 40 | ], (err, results) -> 41 | return callback err if err 42 | [albums, defaultCovers] = results 43 | for album in albums 44 | defaultCover = defaultCovers[album.id] 45 | if defaultCover and not album.coverPicture 46 | [album.coverPicture, album.orientation] = defaultCover 47 | 48 | callback null, albums 49 | 50 | getPublicURL: (callback) -> 51 | cozydb.api.getCozyDomain (err, domain) => 52 | return callback err if err 53 | url = "#{domain}public/photos/#albums/#{@id}" 54 | callback null, url 55 | 56 | -------------------------------------------------------------------------------- /server/models/binary.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | 3 | module.exports = Binary = cozydb.getModel 'Binary', {} 4 | -------------------------------------------------------------------------------- /server/models/cozyinstance.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | 3 | module.exports = CozyInstance = cozydb.getModel 'CozyInstance', 4 | domain: String 5 | locale: String 6 | helpUrl: String 7 | background: String 8 | connectedOnce: Boolean 9 | 10 | CozyInstance.first = (callback) -> 11 | CozyInstance.request 'all', (err, instances) -> 12 | if err then callback err 13 | else if not instances or instances.length is 0 then callback null, null 14 | else callback null, instances[0] 15 | 16 | CozyInstance.getLocale = (callback) -> 17 | CozyInstance.first (err, instance) -> 18 | callback err, instance?.locale or null 19 | 20 | CozyInstance.all = (callback) -> 21 | CozyInstance.request 'all', callback 22 | 23 | CozyInstance.destroyAll = (callback) -> 24 | CozyInstance.requestDestroy 'all', callback 25 | -------------------------------------------------------------------------------- /server/models/device.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | 3 | module.exports = Device = cozydb.getModel 'Device', 4 | login: String 5 | configuration: Object 6 | 7 | Device.all = (params, callback) -> 8 | Device.request "all", params, callback 9 | -------------------------------------------------------------------------------- /server/models/file.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | 3 | module.exports = File = cozydb.getModel 'File', 4 | id : String 5 | name : String 6 | path : String 7 | lastModification : String 8 | binary : cozydb.NoSchema 9 | class : String 10 | 11 | File.imageByMonth = (options, callback) -> 12 | File.rawRequest 'imageByMonth', options, callback 13 | 14 | File.imageByDate = (options, callback) -> 15 | File.request 'imageByDate', options, callback 16 | 17 | File.withoutThumb = (callback) -> 18 | File.request 'withoutThumb', {}, callback 19 | -------------------------------------------------------------------------------- /server/models/notification.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | 3 | module.exports = Notification = cozydb.getModel 'Notification', 4 | text: String 5 | type: String 6 | resource: {type: cozydb.NoSchema, default: null} 7 | publishDate: {type: String, default: Date.now} 8 | 9 | app: String # the app that created that notif 10 | ref: String # for apps with multiple notifs to manage 11 | 12 | Notification.all = (callback) -> 13 | Notification.request "byDate", callback 14 | -------------------------------------------------------------------------------- /server/models/photo.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | async = require 'async' 3 | 4 | Binary = require './binary' 5 | 6 | module.exports = Photo = cozydb.getModel 'Photo', 7 | id : String 8 | title : String 9 | description : String 10 | orientation : Number 11 | binary : (x) -> x 12 | albumid : String 13 | date : String 14 | 15 | # Get all photo linked to given album 16 | Photo.fromAlbum = (album, callback) -> 17 | if album.folderid is "all" 18 | Photo.request 'all', {}, callback 19 | else 20 | params = 21 | startkey: [album.id] 22 | endkey: [album.id + "0"] 23 | Photo.request 'byalbum', params, callback 24 | 25 | # Get all thumbnails of a given photo album. 26 | Photo.albumsThumbs = (callback) -> 27 | params = 28 | reduce: true 29 | group: true 30 | 31 | Photo.rawRequest 'albumphotos', params, (err, results) -> 32 | return callback(err) if err 33 | 34 | out = {} 35 | for result in results 36 | out[result.key] = result.value 37 | 38 | callback null, out 39 | 40 | Photo::destroyWithBinary = (callback) -> 41 | if @binary? and typeof(@binary) is 'object' 42 | async.eachSeries Object.keys(@binary), (bin, cb) => 43 | @removeBinary bin, (err) => 44 | if err 45 | console.log "Cannot destroy binary linked to photo #{@id}" 46 | cb() 47 | , (err) => 48 | @destroy callback 49 | else 50 | @destroy callback 51 | -------------------------------------------------------------------------------- /server/models/requests.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | 3 | byApps = -> emit [doc.app, doc.ref], doc if doc.type is 'persistent' 4 | 5 | allSlug = -> emit doc.slug, doc 6 | 7 | imageByDate = (doc) -> 8 | if doc.class is "image" and doc.binary?.file? 9 | emit doc.lastModification, doc 10 | 11 | module.exports = 12 | 13 | user: 14 | all: cozydb.defaultRequests.all 15 | 16 | alarm: 17 | all: cozydb.defaultRequests.all 18 | 19 | event: 20 | all: cozydb.defaultRequests.all 21 | 22 | cozyinstance: 23 | all: cozydb.defaultRequests.all 24 | 25 | notification: 26 | all: cozydb.defaultRequests.all 27 | byDate: (doc) -> 28 | emit doc.publishDate, doc 29 | byApps: byApps 30 | 31 | application: 32 | all: cozydb.defaultRequests.all 33 | bySlug: allSlug 34 | 35 | stack_application: 36 | all: cozydb.defaultRequests.all 37 | 38 | background: 39 | all: cozydb.defaultRequests.all 40 | 41 | file: 42 | imageByDate : imageByDate 43 | imageByMonth: 44 | map: (doc) -> 45 | if doc.class is "image" and doc.binary?.file? 46 | d = new Date(doc.lastModification) 47 | emit([d.getFullYear(),d.getMonth()+1,d.getDate()], doc._id) 48 | reduce: '_count' 49 | 50 | sharing: 51 | all: cozydb.defaultRequests.all 52 | -------------------------------------------------------------------------------- /server/models/sharing.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | 3 | module.exports = Sharing = cozydb.getModel 'Sharing', 4 | sharerUrl: String 5 | sharerName: String 6 | desc: String 7 | rules: [Object] 8 | targets: [Object] 9 | 10 | Sharing.all = (params, callback) -> 11 | Sharing.request "all", params, callback -------------------------------------------------------------------------------- /server/models/user.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | 3 | module.exports = User = cozydb.getModel 'User', 4 | email: String 5 | public_name: String 6 | timezone: {type: String, default: "Europe/Paris"} 7 | password: String 8 | owner: {type: Boolean, default: false} 9 | activated: {type: Boolean, default: false} 10 | authType: String 11 | encryptedOtpKey: String 12 | hotpCounter: Number 13 | encryptedRecoveryCodes: String 14 | mesinfosUseTracker: {type: Boolean, default: false} 15 | 16 | 17 | # Request methods 18 | 19 | User.all = (callback) -> 20 | User.request "all", callback 21 | 22 | User.first = (callback) -> 23 | User.all (err, users) -> callback err, users?[0] 24 | 25 | User.destroyAll = (callback) -> 26 | User.requestDestroy "all", callback 27 | -------------------------------------------------------------------------------- /server/models/usetracker.coffee: -------------------------------------------------------------------------------- 1 | cozydb = require 'cozydb' 2 | request = require 'request' 3 | async = require 'async' 4 | 5 | module.exports = UseTracker = cozydb.getModel 'UseTracker', 6 | app: String 7 | dateStart: Date 8 | dateEnd: Date 9 | duration: Number 10 | sent: { type: Boolean, default: false } 11 | -------------------------------------------------------------------------------- /server/views/index.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | meta(charset='utf-8') 5 | title Cozy - Home 6 | meta(name='viewport', content='width=device-width, initial-scale=1') 7 | link(rel='stylesheet', href='app-icons/sprite-svg-data.css') 8 | link(rel='stylesheet', href='/fonts/fonts.css') 9 | link(rel='stylesheet', href='stylesheets/app.css') 10 | 11 | script. 12 | var argsFromLocationHash = #{argsFromLocationHash} 13 | window.urlArguments = argsFromLocationHash(window.location.hash) 14 | script!= imports 15 | script(src='javascripts/vendor.js' defer=true) 16 | script(src='javascripts/app.js' onload="require('initialize')" defer=true) 17 | body 18 | -------------------------------------------------------------------------------- /test/fixtures/notifications.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "text": "N'oubliez pas de vous inscrire sur Privowny !", 4 | "resource": { 5 | "app": "pouet", 6 | "url": "/" 7 | }, 8 | "app": "pouet", 9 | "type": "persistent", 10 | "docType": "Notification", 11 | "publishDate": 1402040379881 12 | }, 13 | { 14 | "text": "Blabla", 15 | "resource": { 16 | "app": "pouet", 17 | "url": "/" 18 | }, 19 | "app": "pouet", 20 | "type": "persistent", 21 | "docType": "Notification", 22 | "publishDate": 1402040379881 23 | } 24 | ] -------------------------------------------------------------------------------- /test/lib/icon_tests.coffee: -------------------------------------------------------------------------------- 1 | should = require('chai').Should() 2 | 3 | helpers = require '../helpers' 4 | icons = require "../#{helpers.prefix}server/lib/icon" 5 | 6 | describe "Icon helpers", -> 7 | 8 | describe.skip 'getPath', -> 9 | describe.skip 'getIconInfos', -> 10 | describe.skip 'save', -> 11 | 12 | -------------------------------------------------------------------------------- /test/lib/market_tests.coffee: -------------------------------------------------------------------------------- 1 | should = require('chai').Should() 2 | 3 | helpers = require '../helpers' 4 | market = require "../#{helpers.prefix}server/lib/market" 5 | 6 | 7 | describe "Market helpers", -> 8 | 9 | describe.skip 'download', -> 10 | describe.skip 'getApps', -> 11 | describe.skip 'getApp', -> 12 | 13 | -------------------------------------------------------------------------------- /test/monitor.coffee: -------------------------------------------------------------------------------- 1 | should = require('chai').Should() 2 | helpers = require './helpers' 3 | 4 | TESTPORT = 8889 5 | 6 | describe "Get sys data", -> 7 | 8 | before helpers.setup TESTPORT 9 | before -> @client = helpers.getClient TESTPORT, @ 10 | after helpers.takeDown 11 | 12 | it "When I load sys data", (done) -> 13 | @client.get "api/sys-data", done 14 | 15 | it "Then I have no error", -> 16 | @response.statusCode.should.equal 200 17 | 18 | it "And body should contain disk and ram infos", -> 19 | should.exist @body.freeMem 20 | should.exist @body.totalMem 21 | should.exist @body.freeDiskSpace 22 | should.exist @body.totalDiskSpace 23 | -------------------------------------------------------------------------------- /test/photo-set/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "numeral": "*" 4 | } 5 | } 6 | --------------------------------------------------------------------------------