From a7c881008f2c1779644c288a170182fa10febcf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gre=CC=81gory=20Le=20Garec?= Date: Thu, 27 Sep 2018 01:22:34 +0200 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20New=20init=20parameter=20ssl=20?= =?UTF-8?q?=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This parameter should indicate if the bar must initialize with secure protocols --- src/index.jsx | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/index.jsx b/src/index.jsx index 7a3267c87..0a0372455 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -144,6 +144,26 @@ const getUserActionRequired = () => { return undefined } +const determineSSL = (ssl, cozyURL) => { + if (typeof ssl !== 'undefined') return ssl + + let parsedURL + try { + parsedURL = new URL(cozyURL) + console.warn('Cozy-bar will soon need `ssl` and `domain` parameters to be properly configured, and will not rely on cozyURL.') + return parsedURL.protocol === 'https:' + } catch (error) { + console.warn(`cozyURL parameter passed to Cozy-bar is not a valid URL (${error.message}). Cozy-bar will rely on window.location to detect SSL.`) + } + + if (window && window.location && window.location.protocol) { + return window.location.protocol === 'https:' + } + + console.warn('Cozy-bar cannot detect SSL and will use default value (true)') + return true +} + const init = async ({ appName, appNamePrefix = getAppNamePrefix(), @@ -155,7 +175,8 @@ const init = async ({ replaceTitleOnMobile = false, displayOnMobile, isPublic = false, - onLogOut + onLogOut, + ssl } = {}) => { // Force public mode in `/public` URLs if (/^\/public/.test(window.location.pathname)) { @@ -168,7 +189,13 @@ const init = async ({ } reduxStore.dispatch(setInfos(appName, appNamePrefix, appSlug)) - stack.init({cozyURL, token}) + stack.init({ + cozyURL, + token, + onCreateApp: app => reduxStore.dispatch(receiveApp(app)), + onDeleteApp: app => reduxStore.dispatch(deleteApp(app)), + ssl: determineSSL(ssl, cozyURL) + }) if (lang) { reduxStore.dispatch(setLocale(lang)) } From 3a0e39600f3ca2a2756c03816bec5ae25acf2bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gre=CC=81gory=20Le=20Garec?= Date: Thu, 27 Sep 2018 01:26:24 +0200 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20Move=20realtime=20to=20stack=20lib?= =?UTF-8?q?=20and=20parse=20cozyURL=20=F0=9F=9B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mobile apps are passing a full cozyURL with protocol to the cozy-bar, but by default it's just the cozyDomain --- src/index.jsx | 29 --------------------- src/lib/stack.js | 66 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/src/index.jsx b/src/index.jsx index 0a0372455..7c6ae81a1 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -6,7 +6,6 @@ import React from 'react' import { render } from 'react-dom' import I18n from 'cozy-ui/react/I18n' -import realtime from 'cozy-realtime' import stack from './lib/stack' import { deleteApp, @@ -200,34 +199,6 @@ const init = async ({ reduxStore.dispatch(setLocale(lang)) } - const realtimeConfig = { - // It's too weid to generate a fake URL here. We should just pass - // domain, token and a secure boolean to initialize realtime. - url: `${window.location.protocol}//${cozyURL}`, - token: token - } - - try { - const realtimeApps = await realtime.subscribeAll( - realtimeConfig, - 'io.cozy.apps' - ) - - realtimeApps.onCreate(async app => { - // Fetch direclty the app to get attributes `related` as well. - let fullApp - try { - fullApp = await stack.get.app(app.slug) - } catch (error) { - throw new Error(`Cannont fetch app ${app.slug}: ${error.message}`) - } - reduxStore.dispatch(receiveApp(fullApp)) - }) - realtimeApps.onDelete(app => reduxStore.dispatch(deleteApp(app))) - } catch (error) { - console.warn(`Cannot initialize realtime in Cozy-bar: ${error.message}`) - } - return injectBarInDOM({ appName, appNamePrefix, diff --git a/src/lib/stack.js b/src/lib/stack.js index f244cafb0..47b0d7742 100644 --- a/src/lib/stack.js +++ b/src/lib/stack.js @@ -1,6 +1,8 @@ /* global __TARGET__ */ /* eslint-env browser */ +import realtime from 'cozy-realtime' + import { ForbiddenException, ServerErrorException, @@ -140,12 +142,74 @@ async function getIcon (url, useCache = true) { return iconUrl } +async function initializeRealtime ({ + onCreateApp, + onDeleteApp, + ssl, + url, + token +}) { + // Let's check the url. By default it's just the domain, but some apps are + // passing a full URL with protocol. + let parsedURL + try { + parsedURL = new URL(url) + } catch (error) { + console.warn( + `Cannot parse URL for realtime, using ${url} as domain (${error.message})` + ) + } + + const realtimeConfig = { token } + if (parsedURL) { + realtimeConfig.url = url + } else { + realtimeConfig.url = `${ssl ? 'https:' : 'http:'}${url}` + } + + try { + const realtimeApps = await realtime.subscribeAll( + realtimeConfig, + 'io.cozy.apps' + ) + + realtimeApps.onCreate(async app => { + // Fetch direclty the app to get attributes `related` as well. + let fullApp + try { + fullApp = await getApp(app.slug) + } catch (error) { + throw new Error(`Cannont fetch app ${app.slug}: ${error.message}`) + } + + if (typeof onCreateApp === 'function') { + onCreateApp(fullApp) + } + }) + + realtimeApps.onDelete(app => { + if (typeof onDeleteApp === 'function') { + onDeleteApp(app) + } + }) + } catch (error) { + console.warn(`Cannot initialize realtime in Cozy-bar: ${error.message}`) + } +} + const cache = {} module.exports = { - init ({cozyURL, token}) { + async init ({ cozyURL, token, onCreateApp, onDeleteApp, ssl }) { COZY_URL = `${__TARGET__ === 'mobile' ? '' : '//'}${cozyURL}` COZY_TOKEN = token + await initializeRealtime({ + onCreateApp, + onDeleteApp, + token: COZY_TOKEN, + url: COZY_URL, + ssl + }) }, updateAccessToken (token) { COZY_TOKEN = token