Revert broken speedup idea for language and theme.

RainLoop removes AUTH_SPEC_TOKEN_KEY cookie, which kills browser refresh/F5
So had to put back the LangLink and NewThemeLink, for now
This commit is contained in:
djmaze 2021-04-26 21:56:11 +02:00
parent dbf9755700
commit 6c370abac3
8 changed files with 111 additions and 114 deletions

View file

@ -144,7 +144,12 @@ win.rl = {
rl.hash.set(); rl.hash.set();
if (appData) { if (appData) {
if (appData.NewThemeLink) {
eId('app-theme-link').href = appData.NewThemeLink;
}
loadScript(appData.StaticLibJsLink) loadScript(appData.StaticLibJsLink)
.then(() => loadScript(appData.LangLink))
.then(() => loadScript(appData.StaticAppJsLink)) .then(() => loadScript(appData.StaticAppJsLink))
.then(() => appData.PluginsLink ? loadScript(appData.PluginsLink) : Promise.resolve()) .then(() => appData.PluginsLink ? loadScript(appData.PluginsLink) : Promise.resolve())
.then(() => win.__APP_BOOT ? win.__APP_BOOT(showError) : showError()) .then(() => win.__APP_BOOT ? win.__APP_BOOT(showError) : showError())

10
dev/bootstrap.js vendored
View file

@ -3,7 +3,7 @@ import { i18n } from 'Common/Translator';
import { root } from 'Common/Links'; import { root } from 'Common/Links';
export default (App) => { export default App => {
addEventListener('keydown', event => { addEventListener('keydown', event => {
event = event || window.event; event = event || window.event;
@ -136,10 +136,10 @@ export default (App) => {
}; };
window.__APP_BOOT = () => { window.__APP_BOOT = () => {
const cb = () => setTimeout(() => { const cb = () => {
setTimeout(() => App.bootstart(), 10); window.__APP_BOOT = null;
window.__APP_BOOT = null; App.bootstart();
}, 10); };
('loading' !== doc.readyState) ? cb() : doc.addEventListener('DOMContentLoaded', cb); ('loading' !== doc.readyState) ? cb() : doc.addEventListener('DOMContentLoaded', cb);
}; };
}; };

View file

@ -15,7 +15,6 @@ class Actions
use Actions\Localization; use Actions\Localization;
use Actions\Themes; use Actions\Themes;
const AUTH_TFA_SIGN_ME_TOKEN_KEY = 'rltfasmauth';
const AUTH_SIGN_ME_TOKEN_KEY = 'rlsmauth'; const AUTH_SIGN_ME_TOKEN_KEY = 'rlsmauth';
const AUTH_MAILTO_TOKEN_KEY = 'rlmailtoauth'; const AUTH_MAILTO_TOKEN_KEY = 'rlmailtoauth';
const AUTH_SPEC_TOKEN_KEY = 'rlspecauth'; const AUTH_SPEC_TOKEN_KEY = 'rlspecauth';
@ -511,9 +510,9 @@ class Actions
{ {
$sResult = Utils::GetCookie(self::AUTH_SPEC_TOKEN_KEY, ''); $sResult = Utils::GetCookie(self::AUTH_SPEC_TOKEN_KEY, '');
if (0 < strlen($sResult)) { if (0 < strlen($sResult)) {
// TODO: Browser F5 issue
Utils::ClearCookie(self::AUTH_SPEC_TOKEN_KEY); Utils::ClearCookie(self::AUTH_SPEC_TOKEN_KEY);
} }
return $sResult; return $sResult;
} }
@ -1015,12 +1014,8 @@ class Actions
) : array()); ) : array());
} }
public function AppData(bool $bAdmin, string $sAuthAccountHash = ''): array public function AppData(bool $bAdmin, string $sAuthAccountHash): array
{ {
if (0 < \strlen($sAuthAccountHash) && \preg_match('/[^_\-\.a-zA-Z0-9]/', $sAuthAccountHash)) {
$sAuthAccountHash = '';
}
$oAccount = null; $oAccount = null;
$oConfig = $this->Config(); $oConfig = $this->Config();
@ -1088,7 +1083,7 @@ class Actions
'UserBackgroundHash' => '' 'UserBackgroundHash' => ''
); );
if (0 < \strlen($sAuthAccountHash)) { if (\strlen($sAuthAccountHash) && !\preg_match('/[^_\-\.a-zA-Z0-9]/', $sAuthAccountHash)) {
$aResult['AuthAccountHash'] = $sAuthAccountHash; $aResult['AuthAccountHash'] = $sAuthAccountHash;
} }
@ -1105,7 +1100,6 @@ class Actions
} }
$sLanguage = $oConfig->Get('webmail', 'language', 'en'); $sLanguage = $oConfig->Get('webmail', 'language', 'en');
$sLanguageAdmin = $oConfig->Get('webmail', 'language_admin', 'en');
$UserLanguageRaw = $this->detectUserLanguage($bAdmin); $UserLanguageRaw = $this->detectUserLanguage($bAdmin);
if (!$bAdmin) { if (!$bAdmin) {
@ -1258,24 +1252,22 @@ class Actions
$sStaticCache = $this->StaticCache(); $sStaticCache = $this->StaticCache();
$aResult['Theme'] = $this->GetTheme($bAdmin); $aResult['Theme'] = $this->GetTheme($bAdmin);
$aResult['NewThemeLink'] = $this->ThemeLink($bAdmin);
$aResult['Language'] = $this->ValidateLanguage($sLanguage, '', false); $aResult['Language'] = $this->ValidateLanguage($sLanguage, '', false);
$aResult['UserLanguage'] = $this->ValidateLanguage($UserLanguageRaw, '', false, true); $aResult['UserLanguage'] = $this->ValidateLanguage($UserLanguageRaw, '', false, true);
if ($bAdmin) { if ($bAdmin) {
$aResult['LanguageAdmin'] = $this->ValidateLanguage($sLanguageAdmin, '', true); $aResult['LanguageAdmin'] = $this->ValidateLanguage($oConfig->Get('webmail', 'language_admin', 'en'), '', true);
$aResult['UserLanguageAdmin'] = $this->ValidateLanguage($UserLanguageRaw, '', true, true); $aResult['UserLanguageAdmin'] = $this->ValidateLanguage($UserLanguageRaw, '', true, true);
} }
$aResult['LangLink'] = './?/Lang/0/' . ($bAdmin ? 'Admin' : 'App') . '/' .
($bAdmin ? $aResult['LanguageAdmin'] : $aResult['Language']) . '/' . $sStaticCache . '/';
$aResult['PluginsLink'] = ''; $aResult['PluginsLink'] = '';
if (0 < $this->Plugins()->Count() && $this->Plugins()->HaveJs($bAdmin)) { if (0 < $this->Plugins()->Count() && $this->Plugins()->HaveJs($bAdmin)) {
$aResult['PluginsLink'] = './?/Plugins/0/' . ($bAdmin ? 'Admin' : 'User') . '/' . $sStaticCache . '/'; $aResult['PluginsLink'] = './?/Plugins/0/' . ($bAdmin ? 'Admin' : 'User') . '/' . $sStaticCache . '/';
} }
// $aResult['LangLink'] = './?/Lang/0/' . ($bAdmin ? 'Admin' : 'App') . '/' .
// ($bAdmin ? $aResult['LanguageAdmin'] : $aResult['Language']) . '/' . $sStaticCache . '/';
// $aResult['TemplatesLink'] = './?/Templates/0/' . ($bAdmin ? 'Admin' : 'App') . '/' . $sStaticCache . '/';
$bAppJsDebug = !!$this->Config()->Get('labs', 'use_app_debug_js', false); $bAppJsDebug = !!$this->Config()->Get('labs', 'use_app_debug_js', false);
$aResult['StaticLibJsLink'] = $this->StaticPath('js/' . ($bAppJsDebug ? '' : 'min/') . $aResult['StaticLibJsLink'] = $this->StaticPath('js/' . ($bAppJsDebug ? '' : 'min/') .

View file

@ -114,4 +114,35 @@ trait Localization
return $aLang[$aKey] ?? $sKey; return $aLang[$aKey] ?? $sKey;
} }
public function compileLanguage(string $sLanguage, bool $bAdmin = false) : string
{
$sLanguage = \strtr($sLanguage, '_', '-');
$aResultLang = \json_decode(\file_get_contents(APP_VERSION_ROOT_PATH.'app/localization/langs.json'), true);
$langs = \array_flip(\SnappyMail\L10n::getLanguages($bAdmin));
$aResultLang['LANGS_NAMES'] = \array_intersect_key($aResultLang['LANGS_NAMES'], $langs);
$aResultLang['LANGS_NAMES_EN'] = \array_intersect_key($aResultLang['LANGS_NAMES_EN'], $langs);
$aResultLang = \array_replace_recursive(
$aResultLang,
\SnappyMail\L10n::load($sLanguage, ($bAdmin ? 'admin' : 'user'))
);
$this->Plugins()->ReadLang($sLanguage, $aResultLang);
$sResult = \json_encode($aResultLang, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
$sTimeFormat = '';
$options = [$sLanguage, \substr($sLanguage, 0, 2), 'en'];
foreach ($options as $lang) {
$sFileName = APP_VERSION_ROOT_PATH.'app/localization/'.$lang.'/relativetimeformat.js';
if (\is_file($sFileName)) {
$sTimeFormat = \preg_replace('/^\\s+/', '', \file_get_contents($sFileName));
break;
}
}
return "document.documentElement.lang = '{$sLanguage}';\nwindow.snappymailI18N={$sResult};\nDate.defineRelativeTimeFormat({$sTimeFormat});";
}
} }

View file

@ -89,7 +89,33 @@ trait Themes
public function ValidateTheme(string $sTheme): string public function ValidateTheme(string $sTheme): string
{ {
return \in_array($sTheme, $this->GetThemes()) ? return \in_array($sTheme, $this->GetThemes()) ? $sTheme : $this->Config()->Get('themes', 'default', 'Default');
$sTheme : $this->Config()->Get('themes', 'default', 'Default'); }
public function compileCss(string $sTheme, bool $bAdmin) : string
{
$bCustomTheme = '@custom' === \substr($sTheme, -7);
if ($bCustomTheme) {
$sTheme = \substr($sTheme, 0, -7);
}
$oLess = new \LessPHP\lessc();
$oLess->setFormatter('compressed');
$aResult = array();
$sThemeFile = ($bCustomTheme ? APP_INDEX_ROOT_PATH : APP_VERSION_ROOT_PATH).'themes/'.$sTheme.'/styles.less';
if (\is_file($sThemeFile)) {
$aResult[] = '@base: "'
. ($bCustomTheme ? Utils::WebPath() : Utils::WebVersionPath())
. 'themes/'.$sTheme.'/";';
$aResult[] = \file_get_contents($sThemeFile);
}
$aResult[] = $this->Plugins()->CompileCss($bAdmin);
return $oLess->compile(\implode("\n", $aResult));
} }
} }

View file

@ -159,19 +159,25 @@ class Service
} }
$aTemplateParameters = $this->indexTemplateParameters($bAdmin); $aTemplateParameters = $this->indexTemplateParameters($bAdmin);
$sLanguage = $this->oActions->GetLanguage($bAdmin);
// TODO: Browser F5 issue
// $this->oServiceActions->getAuthAccountHash($bAdmin);
// $sLanguage = $this->oActions->GetLanguage($bAdmin);
$sCacheFileName = ''; $sCacheFileName = '';
if ($this->oActions->Config()->Get('labs', 'cache_system_data', true) && !empty($aTemplateParameters['{{BaseHash}}'])) if ($this->oActions->Config()->Get('labs', 'cache_system_data', true) && !empty($aTemplateParameters['{{BaseHash}}']))
{ {
$sCacheFileName = 'TMPL:'.$sLanguage.$aTemplateParameters['{{BaseHash}}']; // TODO: Browser F5 issue
// $sCacheFileName = 'TMPL:'.$sLanguage.$aTemplateParameters['{{BaseHash}}'];
$sCacheFileName = 'TMPL:'.$aTemplateParameters['{{BaseHash}}'];
$sResult = $this->oActions->Cacher()->Get($sCacheFileName); $sResult = $this->oActions->Cacher()->Get($sCacheFileName);
} }
if (0 === \strlen($sResult)) if (0 === \strlen($sResult))
{ {
// $aTemplateParameters['{{BaseAppThemeCss}}'] = $this->oServiceActions->compileCss($this->oActions->GetTheme($bAdmin)); // $aTemplateParameters['{{BaseAppThemeCss}}'] = $this->oServiceActions->compileCss($this->oActions->GetTheme($bAdmin));
$aTemplateParameters['{{BaseLanguage}}'] = $this->oServiceActions->compileLanguage($sLanguage, $bAdmin); // TODO: Browser F5 issue
// $aTemplateParameters['{{BaseLanguage}}'] = $this->oServiceActions->compileLanguage($sLanguage, $bAdmin);
$aTemplateParameters['{{BaseTemplates}}'] = $this->oServiceActions->compileTemplates($bAdmin, false); $aTemplateParameters['{{BaseTemplates}}'] = $this->oServiceActions->compileTemplates($bAdmin, false);
$sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Index.html'), $aTemplateParameters); $sResult = \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Index.html'), $aTemplateParameters);
@ -231,7 +237,6 @@ class Service
'{{BaseAppMainCssLink}}' => $this->staticPath('css/'.($bAdmin ? 'admin' : 'app').($bAppCssDebug ? '' : '.min').'.css'), '{{BaseAppMainCssLink}}' => $this->staticPath('css/'.($bAdmin ? 'admin' : 'app').($bAppCssDebug ? '' : '.min').'.css'),
'{{BaseAppThemeCssLink}}' => $this->oActions->ThemeLink($bAdmin), '{{BaseAppThemeCssLink}}' => $this->oActions->ThemeLink($bAdmin),
'{{BaseAppBootScript}}' => \file_get_contents(APP_VERSION_ROOT_PATH.'static/js/min/boot.min.js'), '{{BaseAppBootScript}}' => \file_get_contents(APP_VERSION_ROOT_PATH.'static/js/min/boot.min.js'),
// '{{BaseDir}}' => false && \in_array($sLanguage, array('ar', 'he', 'ur')) ? 'rtl' : 'ltr',
'{{BaseAppManifestLink}}' => $this->staticPath('manifest.json'), '{{BaseAppManifestLink}}' => $this->staticPath('manifest.json'),
'{{BaseAppBootCss}}' => \file_get_contents(APP_VERSION_ROOT_PATH.'static/css/boot.min.css'), '{{BaseAppBootCss}}' => \file_get_contents(APP_VERSION_ROOT_PATH.'static/css/boot.min.css'),
'{{LoadingDescriptionEsc}}' => \htmlspecialchars($LoadingDescription, ENT_QUOTES|ENT_IGNORE, 'UTF-8'), '{{LoadingDescriptionEsc}}' => \htmlspecialchars($LoadingDescription, ENT_QUOTES|ENT_IGNORE, 'UTF-8'),

View file

@ -489,7 +489,7 @@ class ServiceActions
if (0 === \strlen($sResult)) if (0 === \strlen($sResult))
{ {
$sResult = $this->compileLanguage($sLanguage, $bAdmin); $sResult = $this->oActions->compileLanguage($sLanguage, $bAdmin);
if ($bCacheEnabled && 0 < \strlen($sCacheFileName)) if ($bCacheEnabled && 0 < \strlen($sCacheFileName))
{ {
$this->Cacher()->Set($sCacheFileName, $sResult); $this->Cacher()->Set($sCacheFileName, $sResult);
@ -580,7 +580,7 @@ class ServiceActions
{ {
try try
{ {
$sResult = $this->compileCss($sTheme); $sResult = $this->oActions->compileCss($sTheme, $bAdmin);
if ($bCacheEnabled) if ($bCacheEnabled)
{ {
@ -883,26 +883,31 @@ class ServiceActions
\header('Content-Type: application/javascript; charset=utf-8'); \header('Content-Type: application/javascript; charset=utf-8');
$this->oHttp->ServerNoCache(); $this->oHttp->ServerNoCache();
$sAuthAccountHash = ''; $sResult = 'rl.initData('
if (!$bAdmin && 0 === \strlen($this->oActions->GetSpecAuthLogoutTokenWithDeletion())) .\json_encode($this->oActions->AppData($bAdmin, $this->getAuthAccountHash($bAdmin)))
{ .');';
$sAuthAccountHash = $this->oActions->GetSpecAuthTokenWithDeletion();
if (empty($sAuthAccountHash))
{
$sAuthAccountHash = $this->oActions->GetSpecAuthToken();
}
if (empty($sAuthAccountHash)) $this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'APPDATA');
{
$oAccount = $this->oActions->GetAccountFromSignMeToken(); return $sResult;
if ($oAccount) }
{
try public function getAuthAccountHash(bool $bAdmin) : string
{
static $sAuthAccountHash = null;
if (null === $sAuthAccountHash) {
$sAuthAccountHash = '';
if (!$bAdmin && 0 === \strlen($this->oActions->GetSpecAuthLogoutTokenWithDeletion())) {
$sAuthAccountHash = $this->oActions->GetSpecAuthTokenWithDeletion();
if (empty($sAuthAccountHash)) {
$sAuthAccountHash = $this->oActions->GetSpecAuthToken();
}
if (empty($sAuthAccountHash)) {
$oAccount = $this->oActions->GetAccountFromSignMeToken();
if ($oAccount) try
{ {
$this->oActions->CheckMailConnection($oAccount); $this->oActions->CheckMailConnection($oAccount);
$this->oActions->AuthToken($oAccount); $this->oActions->AuthToken($oAccount);
$sAuthAccountHash = $this->oActions->GetSpecAuthToken(); $sAuthAccountHash = $this->oActions->GetSpecAuthToken();
} }
catch (\Throwable $oException) catch (\Throwable $oException)
@ -911,46 +916,10 @@ class ServiceActions
$this->oActions->ClearSignMeData($oAccount); $this->oActions->ClearSignMeData($oAccount);
} }
} }
$this->oActions->SetSpecAuthToken($sAuthAccountHash);
} }
$this->oActions->SetSpecAuthToken($sAuthAccountHash);
} }
return $sAuthAccountHash;
$sResult = 'rl.initData('
.\json_encode($this->oActions->AppData($bAdmin, $sAuthAccountHash))
.');';
$this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'APPDATA');
return $sResult;
}
public function compileCss(string $sTheme) : string
{
$bCustomTheme = '@custom' === \substr($sTheme, -7);
if ($bCustomTheme) {
$sTheme = \substr($sTheme, 0, -7);
}
$oLess = new \LessPHP\lessc();
$oLess->setFormatter('compressed');
$aResult = array();
$sThemeFile = ($bCustomTheme ? APP_INDEX_ROOT_PATH : APP_VERSION_ROOT_PATH).'themes/'.$sTheme.'/styles.less';
if (\is_file($sThemeFile))
{
$aResult[] = '@base: "'
. ($bCustomTheme ? Utils::WebPath() : Utils::WebVersionPath())
. 'themes/'.$sTheme.'/";';
$aResult[] = \file_get_contents($sThemeFile);
}
$aResult[] = $this->Plugins()->CompileCss($bAdmin);
return $oLess->compile(\implode("\n", $aResult));
} }
public function compileTemplates(bool $bAdmin = false, bool $bJsOutput = true) : string public function compileTemplates(bool $bAdmin = false, bool $bJsOutput = true) : string
@ -975,35 +944,4 @@ class ServiceActions
return $bJsOutput ? 'rl.TEMPLATES='.\MailSo\Base\Utils::Php2js($sHtml, $this->Logger()).';' : $sHtml; return $bJsOutput ? 'rl.TEMPLATES='.\MailSo\Base\Utils::Php2js($sHtml, $this->Logger()).';' : $sHtml;
} }
public function compileLanguage(string $sLanguage, bool $bAdmin = false) : string
{
$sLanguage = \strtr($sLanguage, '_', '-');
$aResultLang = \json_decode(\file_get_contents(APP_VERSION_ROOT_PATH.'app/localization/langs.json'), true);
$langs = \array_flip(\SnappyMail\L10n::getLanguages($bAdmin));
$aResultLang['LANGS_NAMES'] = \array_intersect_key($aResultLang['LANGS_NAMES'], $langs);
$aResultLang['LANGS_NAMES_EN'] = \array_intersect_key($aResultLang['LANGS_NAMES_EN'], $langs);
$aResultLang = \array_replace_recursive(
$aResultLang,
\SnappyMail\L10n::load($sLanguage, ($bAdmin ? 'admin' : 'user'))
);
$this->Plugins()->ReadLang($sLanguage, $aResultLang);
$sResult = \json_encode($aResultLang, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
$sTimeFormat = '';
$options = [$sLanguage, \substr($sLanguage, 0, 2), 'en'];
foreach ($options as $lang) {
$sFileName = APP_VERSION_ROOT_PATH.'app/localization/'.$lang.'/relativetimeformat.js';
if (\is_file($sFileName)) {
$sTimeFormat = \preg_replace('/^\\s+/', '', \file_get_contents($sFileName));
break;
}
}
return "document.documentElement.lang = '{$sLanguage}';\nwindow.snappymailI18N={$sResult};\nDate.defineRelativeTimeFormat({$sTimeFormat});";
}
} }

View file

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="rl-started-trigger" dir="{{BaseDir}}"> <html class="rl-started-trigger">
<head> <head>
<noscript> <noscript>