diff options
44 files changed, 376 insertions, 281 deletions
| @@ -2,7 +2,7 @@ VIRTUALENV=~/.venvs/pixua  .PHONY: setup requirements install requirements_py install_py requirements_js install_js create_virtualenv  .PHONY: test test_py test_js test_all linters linters_py linters_js coverage unit_tests_py unit_tests_js -.PHONY: integration_tests_py functional_tests ensure_phantomjs_installed ensure_virtualenv_installed clean +.PHONY: integration_tests_py functional_tests functional_tests_ci ensure_virtualenv_installed clean  .PHONY: clean_all clean_py clean_js clean_cache remove_virtualenv remove_javascript_packages  setup: install @@ -73,16 +73,16 @@ integration_tests:  	cd service;\  	trial -j`grep -c "^processor" /proc/cpuinfo || sysctl -n hw.logicalcpu` --reporter=text test.integration -functional_tests: clean requirements install ensure_phantomjs_installed +functional_tests: clean requirements install  	@. $(VIRTUALENV)/bin/activate;\ +	export PATH=$(PATH):/usr/lib/chromium/;\  	cd service;\ -	behave --tags ~@wip --tags ~@smoke test/functional/features +	xvfb-run --server-args="-screen 0 1280x1024x24" behave --tags ~@wip --tags ~@smoke test/functional/features -ensure_phantomjs_installed: -	@if [ ! `which phantomjs` ]; then\ -		echo "You need phantomJS to run these tests";\ -		exit 1;\ -	fi +functional_tests_ci: clean requirements install +	@. $(VIRTUALENV)/bin/activate;\ +	cd service;\ +	behave --tags ~@wip --tags ~@smoke test/functional/features  ensure_virtualenv_installed:  	@if [ ! `which virtualenv` ]; then\ diff --git a/provisioning/modules/pixelated/manifests/source.pp b/provisioning/modules/pixelated/manifests/source.pp index 7dc3358f..4da0669f 100644 --- a/provisioning/modules/pixelated/manifests/source.pp +++ b/provisioning/modules/pixelated/manifests/source.pp @@ -13,7 +13,10 @@ class pixelated::source {      'libsqlcipher-dev',      'libfontconfig1',      'build-essential', -    'ruby-compass']: +    'ruby-compass', +    'xvfb', +    'xauth', +    'chromedriver']:        ensure => latest    } diff --git a/service/pixelated/assets/favicon.png b/service/pixelated/assets/favicon.pngBinary files differ deleted file mode 100644 index e14841c7..00000000 --- a/service/pixelated/assets/favicon.png +++ /dev/null diff --git a/service/pixelated/assets/index.html b/service/pixelated/assets/index.html deleted file mode 100644 index c095577e..00000000 --- a/service/pixelated/assets/index.html +++ /dev/null @@ -1,9 +0,0 @@ -<html> -    <head> -        <meta http-equiv="refresh" content="0;URL=/login"> -    </head> -    <body bgcolor="#FFFFFF" text="#000000\"> -    <a href="/login">click here</a> -    </body> -</html> - diff --git a/service/pixelated/assets/login.html b/service/pixelated/assets/login.html deleted file mode 100644 index ff103f03..00000000 --- a/service/pixelated/assets/login.html +++ /dev/null @@ -1,36 +0,0 @@ -<!DOCTYPE html> -<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"> -<head> -    <title>Pixelated - Login</title> -    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -    <link rel="icon" type="image/png" href="/startup-assets/favicon.png" /> -    <link rel="stylesheet" type="text/css" href="/startup-assets/normalize.min.css" /> -    <link rel="stylesheet" type="text/css" href="/startup-assets/pixelated.css" /> -    <link rel="stylesheet" type="text/css" href="/startup-assets/opensans.css" /> -</head> -<body> -<div class="content"> -    <div class="login"> - -        <img class="logo" src="/startup-assets/pixelated-logo-orange.svg" alt="Pixelated logo"/> - -        <p t:render="error_msg" class="error" ></p> - - -        <form class="standard" id="login_form" action="/login" method="post"> -            <input type="text" name="username" id="email" class="text-field" placeholder="username" tabindex="1" -                   autofocus="" /> -            <input type="password" name="password" id="password" class="text-field" placeholder="password" -                   tabindex="2" autocomplete="off" /> - -            <input type="submit" name="login" value="Login" class="button" tabindex="3" /> - -        </form> -    </div> -    <div class="disclaimer"> -        <div t:render="disclaimer"></div> -    </div> -</div> -</body> - -</html> diff --git a/service/pixelated/resources/__init__.py b/service/pixelated/resources/__init__.py index 6bac2f59..f5512644 100644 --- a/service/pixelated/resources/__init__.py +++ b/service/pixelated/resources/__init__.py @@ -57,12 +57,15 @@ def handle_error_deferred(e, request):      request.finish() -def get_startup_folder(): -    path = os.path.dirname(os.path.abspath(__file__)) -    return os.path.join(path, '..', 'assets') +def get_protected_static_folder(): +    return os.path.join(_get_static_folder(), 'protected') -def get_static_folder(): +def get_public_static_folder(): +    return os.path.join(_get_static_folder(), 'public') + + +def _get_static_folder():      static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "..", "web-ui", "dist"))      if not os.path.exists(static_folder):          static_folder = os.path.join('/', 'usr', 'share', 'pixelated-user-agent') diff --git a/service/pixelated/resources/backup_account_resource.py b/service/pixelated/resources/backup_account_resource.py index 5d9cb032..f1eeee53 100644 --- a/service/pixelated/resources/backup_account_resource.py +++ b/service/pixelated/resources/backup_account_resource.py @@ -19,13 +19,13 @@ from xml.sax import SAXParseException  from pixelated.resources import BaseResource  from twisted.python.filepath import FilePath -from pixelated.resources import get_static_folder +from pixelated.resources import get_protected_static_folder  from twisted.web.http import OK  from twisted.web.template import Element, XMLFile, renderElement  class BackupAccountPage(Element): -    loader = XMLFile(FilePath(os.path.join(get_static_folder(), 'backup_account.html'))) +    loader = XMLFile(FilePath(os.path.join(get_protected_static_folder(), 'backup_account.html')))      def __init__(self):          super(BackupAccountPage, self).__init__() diff --git a/service/pixelated/resources/login_resource.py b/service/pixelated/resources/login_resource.py index 4bbceb89..bb05489e 100644 --- a/service/pixelated/resources/login_resource.py +++ b/service/pixelated/resources/login_resource.py @@ -20,7 +20,7 @@ from xml.sax import SAXParseException  from pixelated.authentication import Authenticator  from pixelated.config.leap import BootstrapUserServices  from pixelated.resources import BaseResource, UnAuthorizedResource, IPixelatedSession -from pixelated.resources import get_startup_folder, respond_json +from pixelated.resources import get_public_static_folder, respond_json  from twisted.cred.error import UnauthorizedLogin  from twisted.internet import defer  from twisted.logger import Logger @@ -45,7 +45,7 @@ def parse_accept_language(all_headers):  class DisclaimerElement(Element): -    loader = XMLFile(FilePath(os.path.join(get_startup_folder(), '_login_disclaimer_banner.html'))) +    loader = XMLFile(FilePath(os.path.join(get_public_static_folder(), '_login_disclaimer_banner.html')))      def __init__(self, banner):          super(DisclaimerElement, self).__init__() @@ -68,7 +68,7 @@ class DisclaimerElement(Element):  class LoginWebSite(Element): -    loader = XMLFile(FilePath(os.path.join(get_startup_folder(), 'login.html'))) +    loader = XMLFile(FilePath(os.path.join(get_public_static_folder(), 'login.html')))      def __init__(self, error_msg=None, disclaimer_banner_file=None):          super(LoginWebSite, self).__init__() @@ -91,14 +91,14 @@ class LoginResource(BaseResource):      def __init__(self, services_factory, provider=None, disclaimer_banner=None, authenticator=None):          BaseResource.__init__(self, services_factory) -        self._startup_folder = get_startup_folder()          self._disclaimer_banner = disclaimer_banner          self._provider = provider          self._authenticator = authenticator or Authenticator(provider)          self._bootstrap_user_services = BootstrapUserServices(services_factory, provider) -        self.putChild('startup-assets', File(self._startup_folder)) -        with open(os.path.join(self._startup_folder, 'Interstitial.html')) as f: +        static_folder = get_public_static_folder() +        self.putChild('public', File(static_folder)) +        with open(os.path.join(static_folder, 'interstitial.html')) as f:              self.interstitial = f.read()      def getChild(self, path, request): @@ -176,5 +176,7 @@ class LoginStatusResource(BaseResource):      def render_GET(self, request):          session = IPixelatedSession(request.getSession()) -        response = {'status': str(session.check_login_status())} +        status = 'completed' if self._services_factory.mode.is_single_user else str(session.check_login_status()) + +        response = {'status': status}          return respond_json(response, request) diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index 206cb3be..320a1204 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -20,14 +20,14 @@ from string import Template  from pixelated.resources.users import UsersResource  from pixelated.resources import BaseResource, UnAuthorizedResource, UnavailableResource -from pixelated.resources import get_startup_folder, get_static_folder +from pixelated.resources import get_public_static_folder, get_protected_static_folder  from pixelated.resources.attachments_resource import AttachmentsResource  from pixelated.resources.sandbox_resource import SandboxResource  from pixelated.resources.backup_account_resource import BackupAccountResource  from pixelated.resources.contacts_resource import ContactsResource  from pixelated.resources.features_resource import FeaturesResource  from pixelated.resources.feedback_resource import FeedbackResource -from pixelated.resources.login_resource import LoginResource +from pixelated.resources.login_resource import LoginResource, LoginStatusResource  from pixelated.resources.logout_resource import LogoutResource  from pixelated.resources.user_settings_resource import UserSettingsResource  from pixelated.resources.mail_resource import MailResource @@ -51,17 +51,18 @@ MODE_RUNNING = 2  class RootResource(BaseResource):      def __init__(self, services_factory):          BaseResource.__init__(self, services_factory) -        self._startup_assets_folder = get_startup_folder() -        self._static_folder = get_static_folder() -        self._html_template = open(os.path.join(self._static_folder, 'index.html')).read() +        self._public_static_folder = get_public_static_folder() +        self._protected_static_folder = get_protected_static_folder() +        self._html_template = open(os.path.join(self._protected_static_folder, 'index.html')).read()          self._services_factory = services_factory          self._child_resources = ChildResourcesMap() -        with open(os.path.join(self._startup_assets_folder, 'Interstitial.html')) as f: +        with open(os.path.join(self._public_static_folder, 'interstitial.html')) as f:              self.interstitial = f.read()          self._startup_mode()      def _startup_mode(self): -        self.putChild('startup-assets', File(self._startup_assets_folder)) +        self.putChild('public', File(self._public_static_folder)) +        self.putChild('status', LoginStatusResource(self._services_factory))          self._mode = MODE_STARTUP      def getChild(self, path, request): @@ -89,9 +90,9 @@ class RootResource(BaseResource):          return csrf_input and csrf_input == xsrf_token      def initialize(self, provider=None, disclaimer_banner=None, authenticator=None): +        self._child_resources.add('assets', File(self._protected_static_folder))          self._child_resources.add('backup-account', BackupAccountResource(self._services_factory)) -        self._child_resources.add('sandbox', SandboxResource(self._static_folder)) -        self._child_resources.add('assets', File(self._static_folder)) +        self._child_resources.add('sandbox', SandboxResource(self._protected_static_folder))          self._child_resources.add('keys', KeysResource(self._services_factory))          self._child_resources.add(AttachmentsResource.BASE_URL, AttachmentsResource(self._services_factory))          self._child_resources.add('contacts', ContactsResource(self._services_factory)) diff --git a/service/test/functional/features/environment.py b/service/test/functional/features/environment.py index d49016b6..821a762b 100644 --- a/service/test/functional/features/environment.py +++ b/service/test/functional/features/environment.py @@ -63,7 +63,7 @@ def before_all(context):  def _setup_webdriver(context): -    browser = context.config.userdata.get('webdriver', 'phantomjs') +    browser = context.config.userdata.get('webdriver', 'chrome')      supported_webdrivers = {          'phantomjs': webdriver.PhantomJS,          'firefox': webdriver.Firefox, diff --git a/service/test/functional/features/steps/attachments.py b/service/test/functional/features/steps/attachments.py index 8852b787..37fabb6a 100644 --- a/service/test/functional/features/steps/attachments.py +++ b/service/test/functional/features/steps/attachments.py @@ -13,6 +13,8 @@  #  # You should have received a copy of the GNU Affero General Public License  # along with Pixelated. If not, see <http://www.gnu.org/licenses/>. +import os +  from email.MIMEMultipart import MIMEMultipart  from email.mime.application import MIMEApplication  from email.mime.text import MIMEText @@ -67,8 +69,10 @@ def find_icon(context):  def upload_big_file(context):      base_dir = "test/functional/features/files/"      fname = "over_5mb.data" +    path = os.path.abspath(os.path.join(base_dir, fname)) +      context.browser.execute_script("$('#fileupload').removeAttr('hidden');") -    fill_by_css_selector(context, '#fileupload', base_dir + fname) +    fill_by_css_selector(context, '#fileupload', path)      find_element_by_css_selector(context, '#upload-error-message') @@ -97,7 +101,9 @@ def should_not_show_upload_error_message(context):  def upload_attachment(context):      base_dir = "test/functional/features/files/"      fname = "5mb.data" -    fill_by_css_selector(context, '#fileupload', base_dir + fname) +    path = os.path.abspath(os.path.join(base_dir, fname)) + +    fill_by_css_selector(context, '#fileupload', path)      attachment_list_item = find_element_by_css_selector(context, '#attachment-list-item li a')      assert attachment_list_item.text == "%s (5.00 Mb)" % fname diff --git a/service/test/functional/features/steps/common.py b/service/test/functional/features/steps/common.py index edfe2a50..3e1e995e 100644 --- a/service/test/functional/features/steps/common.py +++ b/service/test/functional/features/steps/common.py @@ -61,7 +61,7 @@ def _wait_until_elements_are_visible_by_locator(context, locator_tuple, timeout=  def _wait_until_element_is_visible_by_locator(context, locator_tuple, timeout=TIMEOUT_IN_S):      wait = WebDriverWait(context.browser, timeout) -    wait.until(EC.presence_of_element_located(locator_tuple)) +    wait.until(EC.visibility_of_element_located(locator_tuple))      return context.browser.find_element(locator_tuple[0], locator_tuple[1]) diff --git a/service/test/functional/features/steps/tag_list.py b/service/test/functional/features/steps/tag_list.py index daea416d..e3382a61 100644 --- a/service/test/functional/features/steps/tag_list.py +++ b/service/test/functional/features/steps/tag_list.py @@ -14,11 +14,10 @@  # You should have received a copy of the GNU Affero General Public License  # along with Pixelated. If not, see <http://www.gnu.org/licenses/>.  from behave import when -from selenium.common.exceptions import TimeoutException +from selenium.common.exceptions import TimeoutException, StaleElementReferenceException  from common import (      find_element_by_class_name, -    find_element_by_id,      find_element_by_css_selector,      wait_for_user_alert_to_disapear) @@ -37,12 +36,11 @@ def expand_side_nav(context):      if is_side_nav_expanded(context):          return -    toggle = find_element_by_class_name(context, 'side-nav-toggle') -    toggle.click() +    find_element_by_css_selector(context, '.side-nav-toggle-icon i').click()  @when('I select the tag \'{tag}\'') -def impl(context, tag): +def select_tag(context, tag):      wait_for_user_alert_to_disapear(context)      expand_side_nav(context) @@ -53,23 +51,14 @@ def impl(context, tag):          try:              find_element_by_css_selector(context, '#tag-%s' % tag) -            e = find_element_by_id(context, 'tag-%s' % tag) +            e = find_element_by_css_selector(context, '#tag-%s .tag-label' % tag)              e.click()              find_element_by_css_selector(context, ".mail-list-entry__item[href*='%s']" % tag)              success = True -        except TimeoutException: +        except (TimeoutException, StaleElementReferenceException):              pass          finally:              try_again -= 1      assert success - - -@when('I am in  \'{tag}\'') -def impl(context, tag): -    expand_side_nav(context) - -    find_element_by_css_selector(context, '#tag-%s' % tag) -    e = find_element_by_id(context, 'tag-%s' % tag) -    assert "selected" in e.get_attribute("class") diff --git a/service/test/unit/resources/test_helpers.py b/service/test/unit/resources/test_helpers.py index e21c5373..6c456f51 100644 --- a/service/test/unit/resources/test_helpers.py +++ b/service/test/unit/resources/test_helpers.py @@ -18,6 +18,7 @@ from twisted.trial import unittest  import re  from pixelated.resources import respond_json, respond_json_deferred +from pixelated.resources import get_public_static_folder, get_protected_static_folder  from test.unit.resources import DummySite  from twisted.web.test.requesthelper import DummyRequest @@ -44,3 +45,9 @@ class TestHelpers(unittest.TestCase):          self.assertEqual(b"{\"test\": \"yep\"}", request.written[0])          self.assertEqual([b"application/json"],                           request.responseHeaders.getRawHeaders("Content-Type")) + +    def test_getting_public_folder_returns_path(self): +        self.assertIn('web-ui/dist/public', get_public_static_folder()) + +    def test_getting_protected_folder_returns_path(self): +        self.assertIn('web-ui/dist/protected', get_protected_static_folder()) diff --git a/service/test/unit/resources/test_login_resource.py b/service/test/unit/resources/test_login_resource.py index 834b9710..bd0f9122 100644 --- a/service/test/unit/resources/test_login_resource.py +++ b/service/test/unit/resources/test_login_resource.py @@ -23,7 +23,7 @@ from twisted.internet import defer  from twisted.trial import unittest  from twisted.web.test.requesthelper import DummyRequest -from pixelated.resources.login_resource import LoginResource +from pixelated.resources.login_resource import LoginResource, LoginStatusResource  from pixelated.resources.login_resource import parse_accept_language  from test.unit.resources import DummySite @@ -87,23 +87,15 @@ class TestLoginResource(unittest.TestCase):          d = self.web.get(request) -        def assert_form_rendered(_): +        def assert_login_page_rendered(_):              self.assertEqual(200, request.responseCode) -            form_action = 'action="/login"' -            form_method = 'method="post"' -            input_username = 'name="username"' -            input_password = 'name="password"' -            input_submit = 'name="login"' +            title = 'Pixelated - Login'              default_disclaimer = 'Some disclaimer'              written_response = ''.join(request.written) -            self.assertIn(form_action, written_response) -            self.assertIn(form_method, written_response) -            self.assertIn(input_password, written_response) -            self.assertIn(input_submit, written_response) -            self.assertIn(input_username, written_response) +            self.assertIn(title, written_response)              self.assertIn(default_disclaimer, written_response) -        d.addCallback(assert_form_rendered) +        d.addCallback(assert_login_page_rendered)          return d      def _write(self, filename, content): @@ -238,7 +230,7 @@ class TestLoginPOST(unittest.TestCase):          def assert_interstitial_in_response(_):              mock_authenticate.assert_called_once_with(self.username, self.password) -            interstitial_js_in_template = '<script src="startup-assets/Interstitial.js"></script>' +            interstitial_js_in_template = '<script src="/public/interstitial.js"></script>'              self.assertIn(interstitial_js_in_template, self.request.written[0])          d.addCallback(assert_interstitial_in_response) @@ -314,3 +306,36 @@ class TestLoginPOST(unittest.TestCase):          d.addCallback(assert_login_error_called)          return d + + +class TestLoginStatus(unittest.TestCase): +    def setUp(self): +        self.services_factory = mock() +        self.resource = LoginStatusResource(self.services_factory) +        self.web = DummySite(self.resource) + +        self.request = DummyRequest(['/status']) + +    def test_login_status_completed_when_single_user(self): +        self.services_factory.mode = mock() +        self.services_factory.mode.is_single_user = True +        d = self.web.get(self.request) + +        def assert_login_completed(_): +            self.assertIn('completed', self.request.written[0]) + +        d.addCallback(assert_login_completed) +        return d + +    @patch('pixelated.resources.session.PixelatedSession.check_login_status') +    def test_login_status_when_multi_user_returns_check_login_status(self, mock_login_status): +        self.services_factory.mode = mock() +        self.services_factory.mode.is_single_user = False +        mock_login_status.return_value = 'started' +        d = self.web.get(self.request) + +        def assert_login_completed(_): +            self.assertIn('started', self.request.written[0]) + +        d.addCallback(assert_login_completed) +        return d diff --git a/web-ui/.eslintignore b/web-ui/.eslintignore new file mode 100644 index 00000000..8cccef3c --- /dev/null +++ b/web-ui/.eslintignore @@ -0,0 +1 @@ +src/interstitial diff --git a/service/pixelated/assets/hive-bg.png b/web-ui/app/images/hive-bg.pngBinary files differ index 77316967..77316967 100644 --- a/service/pixelated/assets/hive-bg.png +++ b/web-ui/app/images/hive-bg.png diff --git a/service/pixelated/assets/pixelated-logo-orange.svg b/web-ui/app/images/logo-orange.svg index 7e0ef43d..7e0ef43d 100644 --- a/service/pixelated/assets/pixelated-logo-orange.svg +++ b/web-ui/app/images/logo-orange.svg diff --git a/web-ui/app/index.html b/web-ui/app/index.html index b40aecdf..72b04c83 100644 --- a/web-ui/app/index.html +++ b/web-ui/app/index.html @@ -1,15 +1,15 @@  <!DOCTYPE html>  <html>  <head> -<link rel="icon" type="image/png" href="assets/images/Favicon.png"> +<link rel="icon" type="image/png" href="public/images/Favicon.png">  <meta charset="utf-8">  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  <title>$account_email - Pixelated Mail</title>  <meta name="description" content="">  <meta name="viewport" content="width=device-width"> -<link href="assets/bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"> -<link href="assets/bower_components/jquery-file-upload/css/jquery.fileupload.css" rel="stylesheet" type="text/css"> -<link rel="stylesheet" href="assets/css/style.css"> +<link href="/assets/css/font-awesome.min.css" rel="stylesheet" type="text/css"> +<link href="/assets/css/jquery.fileupload.css" rel="stylesheet" type="text/css"> +<link rel="stylesheet" href="/assets/css/style.css">  </head>  <body> @@ -92,19 +92,19 @@    </div>  </div> -<script src="assets/bower_components/modernizr/modernizr.js"></script> -<script src="assets/bower_components/lodash/dist/lodash.min.js"></script> -<script src="assets/bower_components/jquery/dist/jquery.min.js"></script> -<script src="assets/bower_components/jquery-ui/jquery-ui.min.js"></script> -<script src="assets/bower_components/jquery-file-upload/js/jquery.fileupload.js"></script> -<script src="assets/bower_components/handlebars/handlebars.min.js"></script> -<script src="assets/bower_components/typeahead.js/dist/typeahead.bundle.min.js"></script> -<script src="assets/bower_components/iframe-resizer/js/iframeResizer.min.js"></script> -<script src="assets/bower_components/foundation/js/foundation.js" ></script> -<script src="assets/bower_components/foundation/js/foundation/foundation.reveal.js" ></script> -<script src="assets/bower_components/foundation/js/foundation/foundation.offcanvas.js"></script> -<script src="assets/js/foundation/initialize_foundation.js"></script> -<script src="assets/app.js"></script> +<script src="/assets/modernizr.js"></script> +<script src="/assets/lodash.min.js"></script> +<script src="/assets/jquery.min.js"></script> +<script src="/assets/jquery-ui.min.js"></script> +<script src="/assets/jquery.fileupload.js"></script> +<script src="/assets/handlebars.min.js"></script> +<script src="/assets/typeahead.bundle.min.js"></script> +<script src="/assets/iframeResizer.min.js"></script> +<script src="/assets/foundation.js" ></script> +<script src="/assets/foundation.reveal.js" ></script> +<script src="/assets/foundation.offcanvas.js"></script> +<script src="/assets/initialize_foundation.js"></script> +<script src="/assets/app.js"></script>  </body>  </html> diff --git a/web-ui/app/js/page/default.js b/web-ui/app/js/page/default.js index ecaedfd8..541bb4b7 100644 --- a/web-ui/app/js/page/default.js +++ b/web-ui/app/js/page/default.js @@ -96,7 +96,7 @@ define(      'use strict';      function initialize(path) { -      viewI18n.init(path + '/assets/'); +      viewI18n.init(path + '/public/');        viewI18n.loaded(function() {          paneContractExpand.attachTo(document); diff --git a/web-ui/app/sandbox.html b/web-ui/app/sandbox.html index 3e110977..52da1f5b 100644 --- a/web-ui/app/sandbox.html +++ b/web-ui/app/sandbox.html @@ -6,7 +6,7 @@    <link href="css/sandbox.css" rel="stylesheet" type="text/css">    <script src="sandbox.js"></script> -  <script src="bower_components/iframe-resizer/js/iframeResizer.contentWindow.min.js"></script> +  <script src="/assets/iframeResizer.contentWindow.min.js"></script>  </head>  <body></body> diff --git a/web-ui/app/scss/base/_fonts.scss b/web-ui/app/scss/base/_fonts.scss index dfc56dd8..9a47b5ed 100644 --- a/web-ui/app/scss/base/_fonts.scss +++ b/web-ui/app/scss/base/_fonts.scss @@ -2,67 +2,66 @@    font-family: 'Open Sans';    font-style: normal;    font-weight: 300; -  src: local('Open Sans Light'), local('OpenSans-Light'), url('/assets/fonts/OpenSans-Light.woff') format('woff'); +  src: local('Open Sans Light'), local('OpenSans-Light'), url('/public/fonts/OpenSans-Light.woff') format('woff');  }  @font-face {    font-family: 'Open Sans';    font-style: normal;    font-weight: 400; -  src: local('Open Sans'), local('OpenSans'), url('/assets/fonts/OpenSans.woff') format('woff'); +  src: local('Open Sans'), local('OpenSans'), url('/public/fonts/OpenSans.woff') format('woff');  }  @font-face {    font-family: 'Open Sans';    font-style: normal;    font-weight: 600; -  src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url('/assets/fonts/OpenSans-Semibold.woff') format('woff'); +  src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url('/public/fonts/OpenSans-Semibold.woff') format('woff');  }  @font-face {    font-family: 'Open Sans';    font-style: normal;    font-weight: 700; -  src: local('Open Sans Bold'), local('OpenSans-Bold'), url('/assets/fonts/OpenSans-Bold.woff') format('woff'); +  src: local('Open Sans Bold'), local('OpenSans-Bold'), url('/public/fonts/OpenSans-Bold.woff') format('woff');  }  @font-face {    font-family: 'Open Sans';    font-style: normal;    font-weight: 800; -  src: local('Open Sans Extrabold'), local('OpenSans-Extrabold'), url('/assets/fonts/OpenSans-Extrabold.woff') format('woff'); +  src: local('Open Sans Extrabold'), local('OpenSans-Extrabold'), url('/public/fonts/OpenSans-Extrabold.woff') format('woff');  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 300; -  src: local('Open Sans Light Italic'), local('OpenSansLight-Italic'), url('/assets/fonts/OpenSansLight-Italic.woff') format('woff'); +  src: local('Open Sans Light Italic'), local('OpenSansLight-Italic'), url('/public/fonts/OpenSansLight-Italic.woff') format('woff');  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 400; -  src: local('Open Sans Italic'), local('OpenSans-Italic'), url('/assets/fonts/OpenSans-Italic.woff') format('woff'); +  src: local('Open Sans Italic'), local('OpenSans-Italic'), url('/public/fonts/OpenSans-Italic.woff') format('woff');  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 600; -  src: local('Open Sans Semibold Italic'), local('OpenSans-SemiboldItalic'), url('/assets/fonts/OpenSans-SemiboldItalic.woff') format('woff'); +  src: local('Open Sans Semibold Italic'), local('OpenSans-SemiboldItalic'), url('/public/fonts/OpenSans-SemiboldItalic.woff') format('woff');  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 700; -  src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), url('/assets/fonts/OpenSans-BoldItalic.woff') format('woff'); +  src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), url('/public/fonts/OpenSans-BoldItalic.woff') format('woff');  }  @font-face {    font-family: 'Open Sans';    font-style: italic;    font-weight: 800; -  src: local('Open Sans Extrabold Italic'), local('OpenSans-ExtraboldItalic'), url('/assets/fonts/OpenSans-ExtraboldItalic.woff') format('woff'); +  src: local('Open Sans Extrabold Italic'), local('OpenSans-ExtraboldItalic'), url('/public/fonts/OpenSans-ExtraboldItalic.woff') format('woff');  }  @font-face {    font-family: 'icomoon';    font-style: normal;    font-weight: 400; -  src: url('/assets/fonts/icomoon.woff') format('woff'),  url('/assets/fonts/icomoon.ttf') format('truetype'), ; +  src: url('/public/fonts/icomoon.woff') format('woff'),  url('/public/fonts/icomoon.ttf') format('truetype'), ;  } - diff --git a/web-ui/config/copy-webpack.js b/web-ui/config/copy-webpack.js deleted file mode 100644 index 1f7f743a..00000000 --- a/web-ui/config/copy-webpack.js +++ /dev/null @@ -1,88 +0,0 @@ -var CopyWebpackPlugin = require('copy-webpack-plugin'); - -module.exports = new CopyWebpackPlugin([ -  { context: 'app/', from: '404.html' }, -  { context: 'app/', from: 'index.html' }, -  { context: 'app/', from: 'sandbox.html' }, -  { context: 'src/backup_account/', from: 'backup_account.html' }, -  { context: 'app/', from: 'css/*' }, -  { context: 'app/', from: 'fonts/*' }, -  { context: 'app/', from: 'locales/**/*' }, -  { context: 'app/', from: 'images/**/*' }, -  { context: 'app/', from: 'bower_components/font-awesome/fonts/*' }, -  { -    context: 'app/', -    from: 'bower_components/font-awesome/css/font-awesome.min.css', -    to: 'bower_components/font-awesome/css' -  }, -  { -    context: 'app/', -    from: 'bower_components/jquery-file-upload/css/jquery.fileupload.css', -    to: 'bower_components/jquery-file-upload/css' -  }, -  { -    context: 'app/', -    from: 'bower_components/modernizr/modernizr.js', -    to: 'bower_components/modernizr' -  }, -  { -    context: 'app/', -    from: 'bower_components/lodash/dist/lodash.min.js', -    to: 'bower_components/lodash/dist' -  }, -  { -    context: 'app/', -    from: 'bower_components/jquery/dist/jquery.min.js', -    to: 'bower_components/jquery/dist' -  }, -  { -    context: 'app/', -    from: 'bower_components/jquery-ui/jquery-ui.min.js', -    to: 'bower_components/jquery-ui' -  }, -  { -    context: 'app/', -    from: 'bower_components/jquery-file-upload/js/jquery.fileupload.js', -    to: 'bower_components/jquery-file-upload/js' -  }, -  { -    context: 'app/', -    from: 'bower_components/handlebars/handlebars.min.js', -    to: 'bower_components/handlebars' -  }, -  { -    context: 'app/', -    from: 'bower_components/typeahead.js/dist/typeahead.bundle.min.js', -    to: 'bower_components/typeahead.js/dist' -  }, -  { -    context: 'app/', -    from: 'bower_components/iframe-resizer/js/iframeResizer.min.js', -    to: 'bower_components/iframe-resizer/js' -  }, -  { -    context: 'app/', -    from: 'bower_components/iframe-resizer/js/iframeResizer.contentWindow.min.js', -    to: 'bower_components/iframe-resizer/js' -  }, -  { -    context: 'app/', -    from: 'bower_components/foundation/js/foundation.js', -    to: 'bower_components/foundation/js' -  }, -  { -    context: 'app/', -    from: 'bower_components/foundation/js/foundation/foundation.reveal.js', -    to: 'bower_components/foundation/js/foundation' -  }, -  { -    context: 'app/', -    from: 'bower_components/foundation/js/foundation/foundation.offcanvas.js', -    to: 'bower_components/foundation/js/foundation' -  }, -  { -    context: 'app/', -    from: 'js/foundation/initialize_foundation.js', -    to: 'js/foundation' -  } -]) diff --git a/web-ui/config/protected-assets-webpack.js b/web-ui/config/protected-assets-webpack.js new file mode 100644 index 00000000..85654cf0 --- /dev/null +++ b/web-ui/config/protected-assets-webpack.js @@ -0,0 +1,25 @@ +var CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = new CopyWebpackPlugin([ +  { context: 'app/', from: '404.html' }, +  { context: 'app/', from: 'index.html' }, +  { context: 'app/', from: 'sandbox.html' }, +  { context: 'app/', from: 'css/*' }, +  { context: 'src/backup_account/', from: 'backup_account.html' }, +  { context: 'app/bower_components/font-awesome/', from: 'fonts/*' }, +  { context: 'app/bower_components/font-awesome/', from: 'css/font-awesome.min.css', to: 'css' }, +  { context: 'app/bower_components/jquery-file-upload/', from: 'css/jquery.fileupload.css', to: 'css' }, +  { context: 'app/bower_components/modernizr/', from: 'modernizr.js' }, +  { context: 'app/bower_components/lodash/dist/', from: 'lodash.min.js' }, +  { context: 'app/bower_components/jquery/dist/', from: 'jquery.min.js' }, +  { context: 'app/bower_components/jquery-ui/', from: 'jquery-ui.min.js' }, +  { context: 'app/bower_components/jquery-file-upload/js/', from: 'jquery.fileupload.js' }, +  { context: 'app/bower_components/handlebars/', from: 'handlebars.min.js' }, +  { context: 'app/bower_components/typeahead.js/dist/', from: 'typeahead.bundle.min.js' }, +  { context: 'app/bower_components/iframe-resizer/js/', from: 'iframeResizer.min.js' }, +  { context: 'app/bower_components/iframe-resizer/js/', from: 'iframeResizer.contentWindow.min.js' }, +  { context: 'app/bower_components/foundation/js/', from: 'foundation.js' }, +  { context: 'app/bower_components/foundation/js/foundation/', from: 'foundation.reveal.js' }, +  { context: 'app/bower_components/foundation/js/foundation/', from: 'foundation.offcanvas.js' }, +  { context: 'app/js/foundation/', from: 'initialize_foundation.js' } +]) diff --git a/web-ui/config/public-assets-webpack.js b/web-ui/config/public-assets-webpack.js new file mode 100644 index 00000000..28dff566 --- /dev/null +++ b/web-ui/config/public-assets-webpack.js @@ -0,0 +1,10 @@ +var CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = new CopyWebpackPlugin([ +  { context: 'src/login/', from: '*.html' }, +  { context: 'src/login/', from: '*.css' }, +  { context: 'src/interstitial/', from: '*' }, +  { context: 'app/', from: 'fonts/*' }, +  { context: 'app/', from: 'locales/**/*' }, +  { context: 'app/', from: 'images/**/*' } +]); diff --git a/web-ui/src/backup_account/backup_account.html b/web-ui/src/backup_account/backup_account.html index fa026e7a..55881444 100644 --- a/web-ui/src/backup_account/backup_account.html +++ b/web-ui/src/backup_account/backup_account.html @@ -1,7 +1,7 @@  <!DOCTYPE html>  <html>    <head> -    <link rel="icon" type="image/png" href="assets/images/Favicon.png" /> +    <link rel="icon" type="image/png" href="public/images/Favicon.png" />      <meta charset="utf-8"/>      <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />      <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/> diff --git a/web-ui/src/backup_account/page.js b/web-ui/src/backup_account/page.js index c39394e2..cc93a560 100644 --- a/web-ui/src/backup_account/page.js +++ b/web-ui/src/backup_account/page.js @@ -34,7 +34,7 @@ export const Page = ({ t }) => (          <div className='container'>            <img              className='backup-account-image' -            src='assets/images/forgot-my-password.svg' +            src='/public/images/forgot-my-password.svg'              alt={t('backup-account.image-description')}            />            <form> diff --git a/web-ui/src/common/footer/footer.js b/web-ui/src/common/footer/footer.js index 254a19f7..c2138c21 100644 --- a/web-ui/src/common/footer/footer.js +++ b/web-ui/src/common/footer/footer.js @@ -22,7 +22,7 @@ import './footer.scss';  export const Footer = ({ t }) => (    <footer className='footer-wrapper'>      <div className='footer-content'> -      <img className='footer-image' src='/assets/images/lab.svg' alt='' /> +      <img className='footer-image' src='/public/images/lab.svg' alt='' />        <div>          {t('footer-text')}          <a className='footer-link' href='mailto:team@pixelated-project.org'> diff --git a/web-ui/src/common/header/header.js b/web-ui/src/common/header/header.js index 9e5f6bc7..50c863b5 100644 --- a/web-ui/src/common/header/header.js +++ b/web-ui/src/common/header/header.js @@ -25,7 +25,7 @@ export const Header = ({ t }) => (        <a href='/'>          <img            className='header-logo' -          src='/startup-assets/pixelated-logo-orange.svg' +          src='/public/images/logo-orange.svg'            alt='Pixelated'          />        </a> diff --git a/web-ui/src/i18n.js b/web-ui/src/i18n.js index bbbe2dcd..64c7b8a1 100644 --- a/web-ui/src/i18n.js +++ b/web-ui/src/i18n.js @@ -32,7 +32,7 @@ i18n    .init({      fallbackLng: 'en_US',      backend: { -      loadPath: 'assets/locales/{{lng}}/{{ns}}.json' +      loadPath: 'public/locales/{{lng}}/{{ns}}.json'      }    }); diff --git a/service/pixelated/assets/Interstitial.html b/web-ui/src/interstitial/interstitial.html index bc6cc738..727883fe 100644 --- a/service/pixelated/assets/Interstitial.html +++ b/web-ui/src/interstitial/interstitial.html @@ -4,15 +4,15 @@    <head>      <meta charset="utf-8">      <meta http-equiv="X-UA-Compatible" content="IE=edge"> -    <script src="startup-assets/snap.svg-min.js"></script> -    <script src="startup-assets/jquery-2.1.3.min.js"></script> +    <script src="/public/snap.svg-min.js"></script> +    <script src="/public/jquery-2.1.3.min.js"></script>    </head>    <body style="border: 0px; padding: 0px; margin: 0px;background-color: #808181">      <section id="hive-section" style="background-color: #808181;" name="hive-section">        <svg id="hive" style="width: 100%; height: 100%;"></svg>      </section> -    <script src="startup-assets/Interstitial.js"></script> +    <script src="/public/interstitial.js"></script>    </body>  </html> diff --git a/service/pixelated/assets/Interstitial.js b/web-ui/src/interstitial/interstitial.js index 2eaa7a1c..78a17190 100644 --- a/service/pixelated/assets/Interstitial.js +++ b/web-ui/src/interstitial/interstitial.js @@ -42,7 +42,7 @@ $(function () {    var handler = setInterval(function () {      $.ajax({        method: 'GET', -      url: '/login/status' +      url: '/status'      }).success(function (data) {        if (data.status === 'completed' || data.status === 'error') {          window.location="/"; diff --git a/service/pixelated/assets/jquery-2.1.3.min.js b/web-ui/src/interstitial/jquery-2.1.3.min.js index 25714ed2..25714ed2 100644 --- a/service/pixelated/assets/jquery-2.1.3.min.js +++ b/web-ui/src/interstitial/jquery-2.1.3.min.js diff --git a/service/pixelated/assets/snap.svg-min.js b/web-ui/src/interstitial/snap.svg-min.js index ca9601ab..ca9601ab 100644 --- a/service/pixelated/assets/snap.svg-min.js +++ b/web-ui/src/interstitial/snap.svg-min.js diff --git a/service/pixelated/assets/_login_disclaimer_banner.html b/web-ui/src/login/_login_disclaimer_banner.html index dfc63030..dfc63030 100644 --- a/service/pixelated/assets/_login_disclaimer_banner.html +++ b/web-ui/src/login/_login_disclaimer_banner.html diff --git a/web-ui/src/login/app.js b/web-ui/src/login/app.js new file mode 100644 index 00000000..e6ac3192 --- /dev/null +++ b/web-ui/src/login/app.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 ThoughtWorks, Inc. + * + * Pixelated is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Pixelated is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Pixelated. If not, see <http://www.gnu.org/licenses/>. + */ + +import React from 'react'; +import { translate } from 'react-i18next'; + +const App = () => ( +  <form className='standard' id='login_form' action='/login' method='post'> +    <input +      type='text' name='username' id='email' className='text-field' +      placeholder='username' autoFocus='' +    /> +    <input +      type='password' name='password' id='password' className='text-field' +      placeholder='password' autoComplete='off' +    /> +    <input type='submit' name='login' value='Login' className='button' /> +  </form> +); + +export default translate('', { wait: true })(App); diff --git a/service/pixelated/assets/pixelated.css b/web-ui/src/login/login.css index b3e1d16e..51ab2046 100644 --- a/service/pixelated/assets/pixelated.css +++ b/web-ui/src/login/login.css @@ -1,10 +1,27 @@ +/* + * Copyright (c) 2017 ThoughtWorks, Inc. + * + * Pixelated is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Pixelated is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Pixelated. If not, see <http://www.gnu.org/licenses/>. + */ +  body {      font-family: "Open Sans", "Microsoft YaHei", "Hiragino Sans GB", "Hiragino Sans GB W3", "微软雅黑", "Helvetica Neue", Arial, sans-serif;      background-color: #EAEAEA;      height: 100vh;      color: #3E3A37; -    background-image: url("hive-bg.png"); +    background-image: url("/public/images/hive-bg.png");      background-repeat: repeat;  } diff --git a/web-ui/src/login/login.html b/web-ui/src/login/login.html new file mode 100644 index 00000000..b8c45180 --- /dev/null +++ b/web-ui/src/login/login.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html xmlns:t="http://twistedmatrix.com/ns/twisted.web.template/0.1"> +  <head> +    <link rel="icon" type="image/png" href="/public/images/Favicon.png" /> +    <meta charset="utf-8"/> +    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> +    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/> +    <title>Pixelated - Login</title> +    <link rel="stylesheet" type="text/css" href="/public/normalize.min.css" /> +    <link rel="stylesheet" type="text/css" href="/public/login.css" /> +    <link rel="stylesheet" type="text/css" href="/public/opensans.css" /> +  </head> +  <body> +    <div class="content"> +      <div class="login"> +        <img class="logo" src="/public/images/logo-orange.svg" alt="Pixelated logo"/> +        <p t:render="error_msg" class="error"></p> +        <div id="root"/> +      </div> +      <div class="disclaimer"> +        <div t:render="disclaimer"></div> +      </div> +    </div> +    <script type="text/javascript" src="/public/login.js"></script> +  </body> +</html> diff --git a/web-ui/src/login/login.js b/web-ui/src/login/login.js new file mode 100644 index 00000000..ddbe1943 --- /dev/null +++ b/web-ui/src/login/login.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017 ThoughtWorks, Inc. + * + * Pixelated is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Pixelated is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Pixelated. If not, see <http://www.gnu.org/licenses/>. + */ + +import React from 'react'; +import { render } from 'react-dom'; +import a11y from 'react-a11y'; +import { I18nextProvider } from 'react-i18next'; + +import App from './app'; +import i18n from '../i18n'; + +if (process.env.NODE_ENV === 'development') a11y(React); + +render( +  <I18nextProvider i18n={i18n}> +    <App /> +  </I18nextProvider>, +  document.getElementById('root') +); diff --git a/service/pixelated/assets/normalize.min.css b/web-ui/src/login/normalize.min.css index d3c7f4d5..d3c7f4d5 100644 --- a/service/pixelated/assets/normalize.min.css +++ b/web-ui/src/login/normalize.min.css diff --git a/service/pixelated/assets/opensans.css b/web-ui/src/login/opensans.css index a42f346c..a42f346c 100644 --- a/service/pixelated/assets/opensans.css +++ b/web-ui/src/login/opensans.css diff --git a/web-ui/webpack.config.js b/web-ui/webpack.config.js index 52188879..6a44e4a1 100644 --- a/web-ui/webpack.config.js +++ b/web-ui/webpack.config.js @@ -1,21 +1,12 @@  var path = require('path');  var webpack = require('webpack'); -var copyWebpack = require('./config/copy-webpack'); +var publicAssetsWebpack = require('./config/public-assets-webpack'); +var protectedAssetsWebpack = require('./config/protected-assets-webpack');  var loaders = require('./config/loaders-webpack');  var aliases = require('./config/alias-webpack'); -module.exports = { -  entry: { -    app: './app/js/index.js', -    backup_account: './src/backup_account/backup_account.js', -    sandbox: './app/js/sandbox.js' -  }, +var commonConfiguration = {    node: { fs: 'empty' }, -  output: { -    path: path.join(__dirname, 'dist'), -    filename: '[name].js', -    publicPath: '/assets/' -  },    devtool: 'source-map',    resolve: {      alias: aliases, @@ -24,10 +15,45 @@ module.exports = {    module: {      loaders: loaders    }, -  plugins: [copyWebpack, new webpack.DefinePlugin({ -    'process.env': { -      NODE_ENV: JSON.stringify('development') -    } -  })],    postcss: {} -} +}; + +var publicAssets = Object.assign({}, commonConfiguration, { +  entry: { +    'login': './src/login/login.js', +  }, +  output: { +    path: path.join(__dirname, 'dist/public'), +    filename: '[name].js', +    publicPath: '/assets/' +  }, +  plugins: [ +    publicAssetsWebpack, +    new webpack.DefinePlugin({ +      'process.env': { +        NODE_ENV: JSON.stringify('development') +      } +  })] +}); + +var protectedAssets = Object.assign({}, commonConfiguration, { +  entry: { +    'app': './app/js/index.js', +    'backup_account': './src/backup_account/backup_account.js', +    'sandbox': './app/js/sandbox.js' +  }, +  output: { +    path: path.join(__dirname, 'dist/protected'), +    filename: '[name].js', +    publicPath: '/assets/' +  }, +  plugins: [ +    protectedAssetsWebpack, +    new webpack.DefinePlugin({ +      'process.env': { +        NODE_ENV: JSON.stringify('development') +      } +  })] +}); + +module.exports = [publicAssets, protectedAssets]; diff --git a/web-ui/webpack.production.config.js b/web-ui/webpack.production.config.js index 6ee08cac..92a4f12b 100644 --- a/web-ui/webpack.production.config.js +++ b/web-ui/webpack.production.config.js @@ -1,21 +1,13 @@  var path = require('path');  var webpack = require('webpack'); -var copyWebpack = require('./config/copy-webpack'); +var publicAssetsWebpack = require('./config/public-assets-webpack'); +var protectedAssetsWebpack = require('./config/protected-assets-webpack');  var loaders = require('./config/loaders-webpack');  var aliases = require('./config/alias-webpack'); -module.exports = { -  entry: { -    app: './app/js/index.js', -    backup_account: './src/backup_account/backup_account.js', -    sandbox: './app/js/sandbox.js' -  }, +var commonConfiguration = {    node: { fs: 'empty' }, -  output: { -    path: path.join(__dirname, 'dist'), -    filename: '[name].js', -    publicPath: '/assets/' -  }, +  devtool: 'source-map',    resolve: {      alias: aliases,      extensions: ['', '.js'] @@ -23,14 +15,43 @@ module.exports = {    module: {      loaders: loaders    }, -  plugins: [ -    new webpack.optimize.UglifyJsPlugin(), -    new webpack.optimize.DedupePlugin(), -    new webpack.DefinePlugin({ -      'process.env': { -        NODE_ENV: JSON.stringify('production') -      } -    }), -    copyWebpack -  ] -} +  postcss: {} +}; + +var commonPlugins = [ +  new webpack.optimize.UglifyJsPlugin(), +  new webpack.optimize.DedupePlugin(), +  new webpack.DefinePlugin({ +    'process.env': { +      NODE_ENV: JSON.stringify('production') +    } +  }) +]; + +var publicAssets = Object.assign({}, commonConfiguration, { +  entry: { +    'login': './src/login/login.js', +  }, +  output: { +    path: path.join(__dirname, 'dist/public'), +    filename: '[name].js', +    publicPath: '/assets/' +  }, +  plugins: commonPlugins.concat([ publicAssetsWebpack ]) +}); + +var protectedAssets = Object.assign({}, commonConfiguration, { +  entry: { +    'app': './app/js/index.js', +    'backup_account': './src/backup_account/backup_account.js', +    'sandbox': './app/js/sandbox.js' +  }, +  output: { +    path: path.join(__dirname, 'dist/protected'), +    filename: '[name].js', +    publicPath: '/assets/' +  }, +  plugins: commonPlugins.concat([ protectedAssetsWebpack ]) +}); + +module.exports = [publicAssets, protectedAssets]; diff --git a/web-ui/webpack.test.config.js b/web-ui/webpack.test.config.js index 395c3949..e24e4540 100644 --- a/web-ui/webpack.test.config.js +++ b/web-ui/webpack.test.config.js @@ -1,6 +1,5 @@  var path = require('path');  var webpack = require('webpack'); -var copyWebpack = require('./config/copy-webpack');  var aliases = require('./config/alias-webpack');  module.exports = { | 
