github.com/iDevoid/mattermost-server@v5.11.1+incompatible/utils/subpath_test.go (about)

     1  package utils_test
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/mattermost/mattermost-server/model"
    14  	"github.com/mattermost/mattermost-server/utils"
    15  )
    16  
    17  func TestUpdateAssetsSubpath(t *testing.T) {
    18  	t.Run("no client dir", func(t *testing.T) {
    19  		tempDir, err := ioutil.TempDir("", "test_update_assets_subpath")
    20  		require.NoError(t, err)
    21  		defer os.RemoveAll(tempDir)
    22  		os.Chdir(tempDir)
    23  
    24  		err = utils.UpdateAssetsSubpath("/")
    25  		require.Error(t, err)
    26  	})
    27  
    28  	t.Run("valid", func(t *testing.T) {
    29  		tempDir, err := ioutil.TempDir("", "test_update_assets_subpath")
    30  		require.NoError(t, err)
    31  		defer os.RemoveAll(tempDir)
    32  		os.Chdir(tempDir)
    33  
    34  		err = os.Mkdir(model.CLIENT_DIR, 0700)
    35  		require.NoError(t, err)
    36  
    37  		testCases := []struct {
    38  			Description          string
    39  			RootHTML             string
    40  			MainCSS              string
    41  			ManifestJSON         string
    42  			Subpath              string
    43  			ExpectedError        error
    44  			ExpectedRootHTML     string
    45  			ExpectedMainCSS      string
    46  			ExpectedManifestJSON string
    47  		}{
    48  			{
    49  				"no changes required, empty subpath provided",
    50  				baseRootHtml,
    51  				baseCss,
    52  				baseManifestJson,
    53  				"",
    54  				nil,
    55  				baseRootHtml,
    56  				baseCss,
    57  				baseManifestJson,
    58  			},
    59  			{
    60  				"no changes required",
    61  				baseRootHtml,
    62  				baseCss,
    63  				baseManifestJson,
    64  				"/",
    65  				nil,
    66  				baseRootHtml,
    67  				baseCss,
    68  				baseManifestJson,
    69  			},
    70  			{
    71  				"content security policy not found (missing quotes)",
    72  				contentSecurityPolicyNotFoundHtml,
    73  				baseCss,
    74  				baseManifestJson,
    75  				"/subpath",
    76  				fmt.Errorf("failed to find 'Content-Security-Policy' meta tag to rewrite"),
    77  				contentSecurityPolicyNotFoundHtml,
    78  				baseCss,
    79  				baseManifestJson,
    80  			},
    81  			{
    82  				"content security policy not found (missing unsafe-eval)",
    83  				contentSecurityPolicyNotFound2Html,
    84  				baseCss,
    85  				baseManifestJson,
    86  				"/subpath",
    87  				fmt.Errorf("failed to find 'Content-Security-Policy' meta tag to rewrite"),
    88  				contentSecurityPolicyNotFound2Html,
    89  				baseCss,
    90  				baseManifestJson,
    91  			},
    92  			{
    93  				"subpath",
    94  				baseRootHtml,
    95  				baseCss,
    96  				baseManifestJson,
    97  				"/subpath",
    98  				nil,
    99  				subpathRootHtml,
   100  				subpathCss,
   101  				subpathManifestJson,
   102  			},
   103  			{
   104  				"new subpath from old",
   105  				subpathRootHtml,
   106  				subpathCss,
   107  				subpathManifestJson,
   108  				"/nested/subpath",
   109  				nil,
   110  				newSubpathRootHtml,
   111  				newSubpathCss,
   112  				newSubpathManifestJson,
   113  			},
   114  			{
   115  				"resetting to /",
   116  				subpathRootHtml,
   117  				subpathCss,
   118  				baseManifestJson,
   119  				"/",
   120  				nil,
   121  				baseRootHtml,
   122  				baseCss,
   123  				baseManifestJson,
   124  			},
   125  		}
   126  
   127  		for _, testCase := range testCases {
   128  			t.Run(testCase.Description, func(t *testing.T) {
   129  				ioutil.WriteFile(filepath.Join(tempDir, model.CLIENT_DIR, "root.html"), []byte(testCase.RootHTML), 0700)
   130  				ioutil.WriteFile(filepath.Join(tempDir, model.CLIENT_DIR, "main.css"), []byte(testCase.MainCSS), 0700)
   131  				ioutil.WriteFile(filepath.Join(tempDir, model.CLIENT_DIR, "manifest.json"), []byte(testCase.ManifestJSON), 0700)
   132  				err := utils.UpdateAssetsSubpath(testCase.Subpath)
   133  				if testCase.ExpectedError != nil {
   134  					require.Equal(t, testCase.ExpectedError, err)
   135  				} else {
   136  					require.NoError(t, err)
   137  				}
   138  
   139  				contents, err := ioutil.ReadFile(filepath.Join(tempDir, model.CLIENT_DIR, "root.html"))
   140  				require.NoError(t, err)
   141  
   142  				// Rewrite the expected and contents for simpler diffs when failed.
   143  				expectedRootHTML := strings.Replace(testCase.ExpectedRootHTML, ">", ">\n", -1)
   144  				contentsStr := strings.Replace(string(contents), ">", ">\n", -1)
   145  				require.Equal(t, expectedRootHTML, contentsStr)
   146  
   147  				contents, err = ioutil.ReadFile(filepath.Join(tempDir, model.CLIENT_DIR, "main.css"))
   148  				require.NoError(t, err)
   149  				require.Equal(t, testCase.ExpectedMainCSS, string(contents))
   150  
   151  				contents, err = ioutil.ReadFile(filepath.Join(tempDir, model.CLIENT_DIR, "manifest.json"))
   152  				require.NoError(t, err)
   153  				require.Equal(t, testCase.ExpectedManifestJSON, string(contents))
   154  			})
   155  		}
   156  	})
   157  }
   158  
   159  func TestGetSubpathFromConfig(t *testing.T) {
   160  	sToP := func(s string) *string {
   161  		return &s
   162  	}
   163  
   164  	testCases := []struct {
   165  		Description     string
   166  		SiteURL         *string
   167  		ExpectedError   bool
   168  		ExpectedSubpath string
   169  	}{
   170  		{
   171  			"empty SiteURL",
   172  			sToP(""),
   173  			false,
   174  			"/",
   175  		},
   176  		{
   177  			"invalid SiteURL",
   178  			sToP("cache_object:foo/bar"),
   179  			true,
   180  			"",
   181  		},
   182  		{
   183  			"nil SiteURL",
   184  			nil,
   185  			false,
   186  			"/",
   187  		},
   188  		{
   189  			"no trailing slash",
   190  			sToP("http://localhost:8065"),
   191  			false,
   192  			"/",
   193  		},
   194  		{
   195  			"trailing slash",
   196  			sToP("http://localhost:8065/"),
   197  			false,
   198  			"/",
   199  		},
   200  		{
   201  			"subpath, no trailing slash",
   202  			sToP("http://localhost:8065/subpath"),
   203  			false,
   204  			"/subpath",
   205  		},
   206  		{
   207  			"trailing slash",
   208  			sToP("http://localhost:8065/subpath/"),
   209  			false,
   210  			"/subpath",
   211  		},
   212  	}
   213  
   214  	for _, testCase := range testCases {
   215  		t.Run(testCase.Description, func(t *testing.T) {
   216  			config := &model.Config{
   217  				ServiceSettings: model.ServiceSettings{
   218  					SiteURL: testCase.SiteURL,
   219  				},
   220  			}
   221  
   222  			subpath, err := utils.GetSubpathFromConfig(config)
   223  			if testCase.ExpectedError {
   224  				require.Error(t, err)
   225  			} else {
   226  				require.NoError(t, err)
   227  			}
   228  
   229  			require.Equal(t, testCase.ExpectedSubpath, subpath)
   230  		})
   231  	}
   232  }
   233  
   234  const contentSecurityPolicyNotFoundHtml = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv=Content-Security-Policy content="script-src 'self' cdn.segment.com/analytics.js/"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style> <link href="/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>`
   235  
   236  const contentSecurityPolicyNotFound2Html = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv=Content-Security-Policy content="script-src 'self' cdn.segment.com/analytics.js/ 'unsafe-eval'"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style> <link href="/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>`
   237  
   238  const baseRootHtml = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv="Content-Security-Policy" content="script-src 'self' cdn.segment.com/analytics.js/"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style> <link href="/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>`
   239  
   240  const baseCss = `@font-face{font-family:FontAwesome;src:url(/static/files/674f50d287a8c48dc19ba404d20fe713.eot);src:url(/static/files/674f50d287a8c48dc19ba404d20fe713.eot?#iefix&v=4.7.0) format("embedded-opentype"),url(/static/files/af7ae505a9eed503f8b8e6982036873e.woff2) format("woff2"),url(/static/files/fee66e712a8a08eef5805a46892932ad.woff) format("woff"),url(/static/files/b06871f281fee6b241d60582ae9369b9.ttf) format("truetype"),url(/static/files/677433a0892aaed7b7d2628c313c9775.svg#fontawesomeregular) format("svg");font-weight:400;font-style:normal}`
   241  
   242  const subpathRootHtml = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv="Content-Security-Policy" content="script-src 'self' cdn.segment.com/analytics.js/ 'sha256-tPOjw+tkVs9axL78ZwGtYl975dtyPHB6LYKAO2R3gR4='"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/subpath/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/subpath/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/subpath/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/subpath/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/subpath/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/subpath/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/subpath/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/subpath/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/subpath/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/subpath/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/subpath/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/subpath/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style><script>window.publicPath='/subpath/static/'</script> <link href="/subpath/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/subpath/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>`
   243  
   244  const subpathCss = `@font-face{font-family:FontAwesome;src:url(/subpath/static/files/674f50d287a8c48dc19ba404d20fe713.eot);src:url(/subpath/static/files/674f50d287a8c48dc19ba404d20fe713.eot?#iefix&v=4.7.0) format("embedded-opentype"),url(/subpath/static/files/af7ae505a9eed503f8b8e6982036873e.woff2) format("woff2"),url(/subpath/static/files/fee66e712a8a08eef5805a46892932ad.woff) format("woff"),url(/subpath/static/files/b06871f281fee6b241d60582ae9369b9.ttf) format("truetype"),url(/subpath/static/files/677433a0892aaed7b7d2628c313c9775.svg#fontawesomeregular) format("svg");font-weight:400;font-style:normal}`
   245  
   246  const newSubpathRootHtml = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv="Content-Security-Policy" content="script-src 'self' cdn.segment.com/analytics.js/ 'sha256-mbRaPRRpWz6MNkX9SyXWMJ8XnWV4w/DoqK2M0ryUAvc='"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/nested/subpath/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/nested/subpath/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/nested/subpath/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/nested/subpath/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/nested/subpath/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/nested/subpath/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/nested/subpath/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/nested/subpath/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/nested/subpath/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/nested/subpath/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/nested/subpath/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/nested/subpath/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style><script>window.publicPath='/nested/subpath/static/'</script> <link href="/nested/subpath/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/nested/subpath/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>`
   247  
   248  const newSubpathCss = `@font-face{font-family:FontAwesome;src:url(/nested/subpath/static/files/674f50d287a8c48dc19ba404d20fe713.eot);src:url(/nested/subpath/static/files/674f50d287a8c48dc19ba404d20fe713.eot?#iefix&v=4.7.0) format("embedded-opentype"),url(/nested/subpath/static/files/af7ae505a9eed503f8b8e6982036873e.woff2) format("woff2"),url(/nested/subpath/static/files/fee66e712a8a08eef5805a46892932ad.woff) format("woff"),url(/nested/subpath/static/files/b06871f281fee6b241d60582ae9369b9.ttf) format("truetype"),url(/nested/subpath/static/files/677433a0892aaed7b7d2628c313c9775.svg#fontawesomeregular) format("svg");font-weight:400;font-style:normal}`
   249  
   250  const resetRootHtml = `<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta http-equiv="Content-Security-Policy" content="script-src 'self' cdn.segment.com/analytics.js/ 'sha256-VFw7U/t/OI+I9YMja3c2GDwEQbnlOq/L5+GealgesK8='"> <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"> <meta name=robots content="noindex, nofollow"> <meta name=referrer content=no-referrer> <title>Mattermost</title> <meta name=apple-mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-status-bar-style content=default> <meta name=mobile-web-app-capable content=yes> <meta name=apple-mobile-web-app-title content=Mattermost> <meta name=application-name content=Mattermost> <meta name=format-detection content="telephone=no"> <link rel=apple-touch-icon sizes=57x57 href=/static/files/78b7e73b41b8731ce2c41c870ecc8886.png> <link rel=apple-touch-icon sizes=60x60 href=/static/files/51d00ffd13afb6d74fd8f6dfdeef768a.png> <link rel=apple-touch-icon sizes=72x72 href=/static/files/23645596f8f78f017bd4d457abb855c4.png> <link rel=apple-touch-icon sizes=76x76 href=/static/files/26e9d72f472663a00b4b206149459fab.png> <link rel=apple-touch-icon sizes=144x144 href=/static/files/7bd91659bf3fc8c68fcd45fc1db9c630.png> <link rel=apple-touch-icon sizes=120x120 href=/static/files/fa69ffe11eb334aaef5aece8d848ca62.png> <link rel=apple-touch-icon sizes=152x152 href=/static/files/f046777feb6ab12fc43b8f9908b1db35.png> <link rel=icon type=image/png sizes=16x16 href=/static/files/02b96247d275680adaaabf01c71c571d.png> <link rel=icon type=image/png sizes=32x32 href=/static/files/1d9020f201a6762421cab8d30624fdd8.png> <link rel=icon type=image/png sizes=96x96 href=/static/files/fe23af39ae98d77dc26ae8586565970f.png> <link rel=icon type=image/png sizes=192x192 href=/static/files/d7ff68a7675f84337cc154c3d4abe713.png> <link rel=manifest href=/static/files/a985ad72552ad069537d6eea81e719c7.json> <link rel=stylesheet class=code_theme> <style>.error-screen{font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding-top:50px;max-width:750px;font-size:14px;color:#333;margin:auto;display:none;line-height:1.5}.error-screen h2{font-size:30px;font-weight:400;line-height:1.2}.error-screen ul{padding-left:15px;line-height:1.7;margin-top:0;margin-bottom:10px}.error-screen hr{color:#ddd;margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.error-screen-visible{display:block}</style><script>window.publicPath='/static/'</script> <link href="/static/main.364fd054d7a6d741efc6.css" rel="stylesheet"><script type="text/javascript" src="/static/main.e49599ac425584ffead5.js"></script></head> <body class=font--open_sans> <div id=root> <div class=error-screen> <h2>Cannot connect to Mattermost</h2> <hr/> <p>We're having trouble connecting to Mattermost. If refreshing this page (Ctrl+R or Command+R) does not work, please verify that your computer is connected to the internet.</p> <br/> </div> <div class=loading-screen style=position:relative> <div class=loading__content> <div class="round round-1"></div> <div class="round round-2"></div> <div class="round round-3"></div> </div> </div> </div> <noscript> To use Mattermost, please enable JavaScript. </noscript> </body> </html>`
   251  
   252  const baseManifestJson = `{
   253    "icons": [
   254      {
   255        "src": "/static/icon_96x96.png",
   256        "sizes": "96x96",
   257        "type": "image/png"
   258      },
   259      {
   260        "src": "/static/icon_32x32.png",
   261        "sizes": "32x32",
   262        "type": "image/png"
   263      },
   264      {
   265        "src": "/static/icon_16x16.png",
   266        "sizes": "16x16",
   267        "type": "image/png"
   268      },
   269      {
   270        "src": "/static/icon_76x76.png",
   271        "sizes": "76x76",
   272        "type": "image/png"
   273      },
   274      {
   275        "src": "/static/icon_72x72.png",
   276        "sizes": "72x72",
   277        "type": "image/png"
   278      },
   279      {
   280        "src": "/static/icon_60x60.png",
   281        "sizes": "60x60",
   282        "type": "image/png"
   283      },
   284      {
   285        "src": "/static/icon_57x57.png",
   286        "sizes": "57x57",
   287        "type": "image/png"
   288      },
   289      {
   290        "src": "/static/icon_152x152.png",
   291        "sizes": "152x152",
   292        "type": "image/png"
   293      },
   294      {
   295        "src": "/static/icon_144x144.png",
   296        "sizes": "144x144",
   297        "type": "image/png"
   298      },
   299      {
   300        "src": "/static/icon_120x120.png",
   301        "sizes": "120x120",
   302        "type": "image/png"
   303      },
   304      {
   305        "src": "/static/icon_192x192.png",
   306        "sizes": "192x192",
   307        "type": "image/png"
   308      }
   309    ],
   310    "name": "Mattermost",
   311    "short_name": "Mattermost",
   312    "orientation": "any",
   313    "display": "standalone",
   314    "start_url": ".",
   315    "description": "Mattermost is an open source, self-hosted Slack-alternative",
   316    "background_color": "#ffffff"
   317  }
   318  `
   319  
   320  const subpathManifestJson = `{
   321    "icons": [
   322      {
   323        "src": "/subpath/static/icon_96x96.png",
   324        "sizes": "96x96",
   325        "type": "image/png"
   326      },
   327      {
   328        "src": "/subpath/static/icon_32x32.png",
   329        "sizes": "32x32",
   330        "type": "image/png"
   331      },
   332      {
   333        "src": "/subpath/static/icon_16x16.png",
   334        "sizes": "16x16",
   335        "type": "image/png"
   336      },
   337      {
   338        "src": "/subpath/static/icon_76x76.png",
   339        "sizes": "76x76",
   340        "type": "image/png"
   341      },
   342      {
   343        "src": "/subpath/static/icon_72x72.png",
   344        "sizes": "72x72",
   345        "type": "image/png"
   346      },
   347      {
   348        "src": "/subpath/static/icon_60x60.png",
   349        "sizes": "60x60",
   350        "type": "image/png"
   351      },
   352      {
   353        "src": "/subpath/static/icon_57x57.png",
   354        "sizes": "57x57",
   355        "type": "image/png"
   356      },
   357      {
   358        "src": "/subpath/static/icon_152x152.png",
   359        "sizes": "152x152",
   360        "type": "image/png"
   361      },
   362      {
   363        "src": "/subpath/static/icon_144x144.png",
   364        "sizes": "144x144",
   365        "type": "image/png"
   366      },
   367      {
   368        "src": "/subpath/static/icon_120x120.png",
   369        "sizes": "120x120",
   370        "type": "image/png"
   371      },
   372      {
   373        "src": "/subpath/static/icon_192x192.png",
   374        "sizes": "192x192",
   375        "type": "image/png"
   376      }
   377    ],
   378    "name": "Mattermost",
   379    "short_name": "Mattermost",
   380    "orientation": "any",
   381    "display": "standalone",
   382    "start_url": ".",
   383    "description": "Mattermost is an open source, self-hosted Slack-alternative",
   384    "background_color": "#ffffff"
   385  }
   386  `
   387  
   388  const newSubpathManifestJson = `{
   389    "icons": [
   390      {
   391        "src": "/nested/subpath/static/icon_96x96.png",
   392        "sizes": "96x96",
   393        "type": "image/png"
   394      },
   395      {
   396        "src": "/nested/subpath/static/icon_32x32.png",
   397        "sizes": "32x32",
   398        "type": "image/png"
   399      },
   400      {
   401        "src": "/nested/subpath/static/icon_16x16.png",
   402        "sizes": "16x16",
   403        "type": "image/png"
   404      },
   405      {
   406        "src": "/nested/subpath/static/icon_76x76.png",
   407        "sizes": "76x76",
   408        "type": "image/png"
   409      },
   410      {
   411        "src": "/nested/subpath/static/icon_72x72.png",
   412        "sizes": "72x72",
   413        "type": "image/png"
   414      },
   415      {
   416        "src": "/nested/subpath/static/icon_60x60.png",
   417        "sizes": "60x60",
   418        "type": "image/png"
   419      },
   420      {
   421        "src": "/nested/subpath/static/icon_57x57.png",
   422        "sizes": "57x57",
   423        "type": "image/png"
   424      },
   425      {
   426        "src": "/nested/subpath/static/icon_152x152.png",
   427        "sizes": "152x152",
   428        "type": "image/png"
   429      },
   430      {
   431        "src": "/nested/subpath/static/icon_144x144.png",
   432        "sizes": "144x144",
   433        "type": "image/png"
   434      },
   435      {
   436        "src": "/nested/subpath/static/icon_120x120.png",
   437        "sizes": "120x120",
   438        "type": "image/png"
   439      },
   440      {
   441        "src": "/nested/subpath/static/icon_192x192.png",
   442        "sizes": "192x192",
   443        "type": "image/png"
   444      }
   445    ],
   446    "name": "Mattermost",
   447    "short_name": "Mattermost",
   448    "orientation": "any",
   449    "display": "standalone",
   450    "start_url": ".",
   451    "description": "Mattermost is an open source, self-hosted Slack-alternative",
   452    "background_color": "#ffffff"
   453  }
   454  `