diff options
-rw-r--r-- | i18n/en.json | 56 | ||||
-rw-r--r-- | templates/unsupported_browser.html | 178 | ||||
-rw-r--r-- | web/web.go | 36 | ||||
-rw-r--r-- | web/web_test.go | 29 | ||||
-rwxr-xr-x | webapp/i18n/en.json | 5 | ||||
-rw-r--r-- | webapp/images/warning.png | bin | 0 -> 1046 bytes | |||
-rw-r--r-- | webapp/webpack.config.js | 3 |
7 files changed, 265 insertions, 42 deletions
diff --git a/i18n/en.json b/i18n/en.json index ef839b4fd..7503ca8e8 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -3972,30 +3972,6 @@ "translation": "Unable to update existing SAML user. Allowing login anyway. err=%v" }, { - "id": "error.generic.link_message", - "translation": "Back to Mattermost" - }, - { - "id": "error.generic.message", - "translation": "An error has occurred." - }, - { - "id": "error.generic.title", - "translation": "Error" - }, - { - "id": "error.not_found.link_message", - "translation": "Back to Mattermost" - }, - { - "id": "error.not_found.message", - "translation": "The page you were trying to reach does not exist." - }, - { - "id": "error.not_found.title", - "translation": "Page not found" - }, - { "id": "jobs.request_cancellation.status.error", "translation": "Could not request cancellation for job that is not in a cancelable state." }, @@ -6668,10 +6644,6 @@ "translation": "Authorize Application" }, { - "id": "web.check_browser_compatibility.app_error", - "translation": "Your current browser is not supported, please upgrade to one of the following browsers: Google Chrome 21 or higher, Internet Explorer 11 or higher, Firefox 14 or higher, Safari 9 or higher" - }, - { "id": "web.claim_account.team.error", "translation": "Couldn't find team name=%v, err=%v" }, @@ -6716,6 +6688,34 @@ "translation": "Email Verified" }, { + "id": "web.error.unsupported_browser.title", + "translation": "Unsupported Browser" + }, + { + "id": "web.error.unsupported_browser.message", + "translation": "Your current browser is not supported. Please upgrade to one of the following browsers:" + }, + { + "id": "web.error.unsupported_browser.help1", + "translation": "Google Chrome 43+" + }, + { + "id": "web.error.unsupported_browser.help2", + "translation": "Mozzilla Firefox 52+" + }, + { + "id": "web.error.unsupported_browser.help3", + "translation": "Microsoft Internet Explorer 11+" + }, + { + "id": "web.error.unsupported_browser.help4", + "translation": "Microsoft Edge 40+" + }, + { + "id": "web.error.unsupported_browser.help5", + "translation": "Apple Safari 9+" + }, + { "id": "web.find_team.title", "translation": "Find Team" }, diff --git a/templates/unsupported_browser.html b/templates/unsupported_browser.html new file mode 100644 index 000000000..79656e10c --- /dev/null +++ b/templates/unsupported_browser.html @@ -0,0 +1,178 @@ +{{define "unsupported_browser"}} + <head> + <style> + body { + margin-top: 0px; + margin-right: 0px; + margin-bottom: 0px; + margin-left: 0px; + font-family: "Open Sans", sans-serif; + font-size: 14px; + line-height: 1.42857; + color: rgb(51, 51, 51); + background-color: whitesmoke; + -webkit-font-smoothing: antialiased; + background-image: initial; + background-position-x: initial; + background-position-y: initial; + background-size: initial; + background-repeat-x: initial; + background-repeat-y: initial; + background-attachment: initial; + background-origin: initial; + background-clip: initial; + height: 100%; + position: relative; + width: 100%; + } + * { + box-sizing: border-box; + } + html, body { + height: 100%; + } + .sticky { + background-image: initial; + background-position-x: initial; + background-position-y: initial; + background-size: initial; + background-repeat-x: initial; + background-repeat-y: initial; + background-attachment: initial; + background-origin: initial; + background-clip: initial; + background-color: white; + } + .container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; + height: 100%; + position: relative; + } + .container-fluid::after { + content: " "; + display: block; + height: 0px; + clear: both; + overflow-x: hidden; + overflow-y: hidden; + visibility: hidden; + } + .exclamation-triangle { + width: 22px; + opacity: 0.6; + } + body.error .container-fluid { + display: table; + height: 90%; + } + body.error .error__container { + color: rgb(85, 85, 85); + display: table-cell; + margin-top: 0px; + margin-right: auto; + margin-bottom: 0px; + margin-left: auto; + max-width: 800px; + padding-top: 5em; + padding-right: 0px; + padding-bottom: 5em; + padding-left: 0px; + text-align: left; + vertical-align: top; + } + body.error .error__icon { + color: rgb(204, 204, 204); + font-size: 4em; + } + h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; + } + h1, .h1, h2, .h2, h3, .h3 { + margin-top: 20px; + margin-bottom: 10px; + } + h2, .h2 { + font-size: 30px; + } + body.error h2 { + font-size: 1.5em; + font-weight: 600; + margin-top: 0.8em; + margin-right: 0px; + margin-bottom: 0.5em; + margin-left: 0px; + } + h2 { + font-size: 25px; + } + ul, ol { + margin-top: 0px; + margin-bottom: 10px; + } + a { + background-color: transparent; + color: rgb(35, 137, 215); + text-decoration-line: none; + text-decoration-style: initial; + text-decoration-color: initial; + cursor: pointer; + word-break: break-word; + } + a:focus { + outline-color: -webkit-focus-ring-color; + outline-style: auto; + outline-width: 5px; + outline-offset: -2px; + } + </style> +</head> + <body class="sticky error"> + <div data-reactroot="" class="container-fluid" > + <div class="error__container" > + <div class="error__icon" > + <img src="/static/images/warning.png" alt="warning" class="exclamation-triangle" ></img> + </div> + <h2 > + <span>{{.Props.Title}}</span> + </h2> + <div> + <span>{{.Props.Message}}</span> + <ul> + <li> + <a href="https://www.google.com/chrome/browser/desktop/index.html" target="_blank" rel="noopener noreferrer"> + <span>Google Chrome 43+</span> + </a> + </li> + <li> + <a href="https://www.mozilla.org/en-US/firefox/new/" target="_blank" rel="noopener noreferrer"> + <span>Mozzilla Firefox 52+</span> + </a> + </li> + <li> + <a href="https://www.microsoft.com/en-ca/download/internet-explorer.aspx" target="_blank" rel="noopener noreferrer"> + <span>Microsoft Internet Explorer 11+</span> + </a> + </li> + <li> + <a href="https://www.microsoft.com/en-ca/download/details.aspx?id=48126" target="_blank" rel="noopener noreferrer"> + <span>Microsoft Edge 40+</span> + </a> + </li> + <li> + <a href="https://support.apple.com/en-us/HT204416" target="_blank" rel="noopener noreferrer"> + <span>Apple Safari 9+</span> + </a> + </li> + </ul> + </div> + </div> + </div> +</body> + +{{end}} diff --git a/web/web.go b/web/web.go index e70129221..221e1dc1c 100644 --- a/web/web.go +++ b/web/web.go @@ -5,6 +5,7 @@ package web import ( "net/http" + "strconv" "strings" "github.com/NYTimes/gziphandler" @@ -46,19 +47,28 @@ func staticHandler(handler http.Handler) http.Handler { }) } -var browsersNotSupported string = "MSIE/8;MSIE/9;MSIE/10;Internet Explorer/8;Internet Explorer/9;Internet Explorer/10;Safari/7;Safari/8" +//map should be of minimum required browser version. +//var browsersNotSupported string = "MSIE/11;Internet Explorer/11;Safari/9;Chrome/43;Edge/15;Firefox/52" +//var browserMinimumSupported = [6]string{"MSIE/11", "Internet Explorer/11", "Safari/9", "Chrome/43", "Edge/15", "Firefox/52"} +var browserMinimumSupported = map[string]int{ + "MSIE": 11, + "Internet Explorer": 11, + "Safari": 9, + "Chrome": 43, + "Edge": 15, + "Firefox": 52, +} -func CheckBrowserCompatability(c *api.Context, r *http.Request) bool { - ua := user_agent.New(r.UserAgent()) +func CheckBrowserCompatability(ua *user_agent.UserAgent) bool { bname, bversion := ua.Browser() - browsers := strings.Split(browsersNotSupported, ";") - for _, browser := range browsers { - version := strings.Split(browser, "/") + l4g.Debug("Detected Browser: %v %v", bname, bversion) - if strings.HasPrefix(bname, version[0]) && strings.HasPrefix(bversion, version[1]) { - return false - } + curVersion := strings.Split(bversion, ".") + intCurVersion, _ := strconv.Atoi(curVersion[0]) + + if version, exist := browserMinimumSupported[bname]; exist && intCurVersion < version { + return false } return true @@ -66,10 +76,12 @@ func CheckBrowserCompatability(c *api.Context, r *http.Request) bool { } func root(c *api.Context, w http.ResponseWriter, r *http.Request) { - if !CheckBrowserCompatability(c, r) { + if !CheckBrowserCompatability(user_agent.New(r.UserAgent())) { w.Header().Set("Cache-Control", "no-store") - w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(c.T("web.check_browser_compatibility.app_error"))) + page := utils.NewHTMLTemplate("unsupported_browser", c.Locale) + page.Props["Title"] = c.T("web.error.unsupported_browser.title") + page.Props["Message"] = c.T("web.error.unsupported_browser.message") + page.RenderToWriter(w) return } diff --git a/web/web_test.go b/web/web_test.go index e1cdb0714..4ea7cd8ee 100644 --- a/web/web_test.go +++ b/web/web_test.go @@ -13,6 +13,7 @@ import ( "github.com/mattermost/platform/model" "github.com/mattermost/platform/store" "github.com/mattermost/platform/utils" + "github.com/mssola/user_agent" ) var ApiClient *model.Client @@ -120,3 +121,31 @@ func TestZZWebTearDown(t *testing.T) { time.Sleep(2 * time.Second) TearDown() } + +func TestCheckBrowserCompatability(t *testing.T) { + + //test should fail browser compatibility check with Mozilla FF 40.1 + ua := "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1" + t.Logf("Checking Mozzila 40.1 with U.A. String: \n%v", ua) + if result := CheckBrowserCompatability(user_agent.New(ua)); result == true { + t.Error("Fail: should have failed browser compatibility") + } else { + t.Log("Pass: User Agent correctly failed!") + } + + ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36" + t.Logf("Checking Chrome 60 with U.A. String: \n%v", ua) + if result := CheckBrowserCompatability(user_agent.New(ua)); result == false { + t.Error("Fail: should have passed browser compatibility") + } else { + t.Log("Pass: User Agent correctly passed!") + } + + ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393" + t.Logf("Checking Edge 14.14393 with U.A. String: \n%v", ua) + if result := CheckBrowserCompatability(user_agent.New(ua)); result == true { + t.Log("Warning: Edge should have failed browser compatibility. It is probably still detecting as Chrome.") + } else { + t.Log("Pass: User Agent correctly failed!") + } +} diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json index 91ebd13c6..62f50e39f 100755 --- a/webapp/i18n/en.json +++ b/webapp/i18n/en.json @@ -1455,11 +1455,14 @@ "emoji_picker.recent": "Recently Used", "emoji_picker.search": "Search", "emoji_picker.symbols": "Symbols", + "error.generic.title": "Error", + "error.generic.message": "An error has occurred.", + "error.generic.link_message": "Back to Mattermost", "error.generic.link": "Back to Mattermost", "error.generic.message": "An error has occurred.", "error.local_storage.help1": "Enable cookies", "error.local_storage.help2": "Turn off private browsing", - "error.local_storage.help3": "Use a supported browser (IE 11, Chrome 43+, Firefox 38+, Safari 9, Edge)", + "error.local_storage.help3": "Use a supported browser (IE 11, Chrome 43+, Firefox 52+, Safari 9, Edge 40+)", "error.local_storage.message": "Mattermost was unable to load because a setting in your browser prevents the use of its local storage features. To allow Mattermost to load, try the following actions:", "error.not_found.link_message": "Back to Mattermost", "error.not_found.message": "The page you were trying to reach does not exist", diff --git a/webapp/images/warning.png b/webapp/images/warning.png Binary files differnew file mode 100644 index 000000000..19e13399b --- /dev/null +++ b/webapp/images/warning.png diff --git a/webapp/webpack.config.js b/webapp/webpack.config.js index e9de8dd82..b779e5d85 100644 --- a/webapp/webpack.config.js +++ b/webapp/webpack.config.js @@ -322,7 +322,8 @@ if (TEST) { {from: 'images/logo-email.png', to: 'images'}, {from: 'images/circles.png', to: 'images'}, {from: 'images/favicon', to: 'images/favicon'}, - {from: 'images/appIcons.png', to: 'images'} + {from: 'images/appIcons.png', to: 'images'}, + {from: 'images/warning.png', to: 'images'} ]) ); } |