diff options
author | Kim <1877318+kimsible@users.noreply.github.com> | 2020-07-10 10:20:11 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-10 10:20:11 +0200 |
commit | caf2aaf4f9d38ad441a5562c3b8720f8779d6f78 (patch) | |
tree | 2a93cbfd2aee6089fd334f28dcb47c18a368a6fd /server/controllers | |
parent | 27647da17fe53ff24ed27ef8618bc244c0be6b26 (diff) | |
download | PeerTube-caf2aaf4f9d38ad441a5562c3b8720f8779d6f78.tar.gz PeerTube-caf2aaf4f9d38ad441a5562c3b8720f8779d6f78.tar.zst PeerTube-caf2aaf4f9d38ad441a5562c3b8720f8779d6f78.zip |
Add ability to override client assets : logo - favicon - PWA icons - PWA manifest name and description (#2897)
* Add client-overrides storage to config
* Add static-serve for client overrides
* Move backgroun-image logo from bundle to css tag for runtime content hash
* Add dynamic JSON manifest
* Add content hash for manifest, favicon and logo
Co-authored-by: kimsible <kimsible@users.noreply.github.com>
Diffstat (limited to 'server/controllers')
-rw-r--r-- | server/controllers/client.ts | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/server/controllers/client.ts b/server/controllers/client.ts index 65b5a053c..88f51907b 100644 --- a/server/controllers/client.ts +++ b/server/controllers/client.ts | |||
@@ -1,3 +1,4 @@ | |||
1 | import { constants, promises as fs } from 'fs' | ||
1 | import * as express from 'express' | 2 | import * as express from 'express' |
2 | import { join } from 'path' | 3 | import { join } from 'path' |
3 | import { root } from '../helpers/core-utils' | 4 | import { root } from '../helpers/core-utils' |
@@ -39,20 +40,40 @@ clientsRouter.use( | |||
39 | ) | 40 | ) |
40 | 41 | ||
41 | // Static HTML/CSS/JS client files | 42 | // Static HTML/CSS/JS client files |
42 | |||
43 | const staticClientFiles = [ | 43 | const staticClientFiles = [ |
44 | 'manifest.webmanifest', | ||
45 | 'ngsw-worker.js', | 44 | 'ngsw-worker.js', |
46 | 'ngsw.json' | 45 | 'ngsw.json' |
47 | ] | 46 | ] |
47 | |||
48 | for (const staticClientFile of staticClientFiles) { | 48 | for (const staticClientFile of staticClientFiles) { |
49 | const path = join(root(), 'client', 'dist', staticClientFile) | 49 | const path = join(root(), 'client', 'dist', staticClientFile) |
50 | 50 | ||
51 | clientsRouter.get('/' + staticClientFile, (req: express.Request, res: express.Response) => { | 51 | clientsRouter.get(`/${staticClientFile}`, (req: express.Request, res: express.Response) => { |
52 | res.sendFile(path, { maxAge: STATIC_MAX_AGE.SERVER }) | 52 | res.sendFile(path, { maxAge: STATIC_MAX_AGE.SERVER }) |
53 | }) | 53 | }) |
54 | } | 54 | } |
55 | 55 | ||
56 | // Dynamic PWA manifest | ||
57 | clientsRouter.get('/manifest.webmanifest', asyncMiddleware(generateManifest)) | ||
58 | |||
59 | // Static client overrides | ||
60 | const staticClientOverrides = [ | ||
61 | 'assets/images/logo.svg', | ||
62 | 'assets/images/favicon.png', | ||
63 | 'assets/images/icons/icon-36x36.png', | ||
64 | 'assets/images/icons/icon-48x48.png', | ||
65 | 'assets/images/icons/icon-72x72.png', | ||
66 | 'assets/images/icons/icon-96x96.png', | ||
67 | 'assets/images/icons/icon-144x144.png', | ||
68 | 'assets/images/icons/icon-192x192.png', | ||
69 | 'assets/images/icons/icon-512x512.png' | ||
70 | ] | ||
71 | |||
72 | for (const staticClientOverride of staticClientOverrides) { | ||
73 | const overridePhysicalPath = join(CONFIG.STORAGE.CLIENT_OVERRIDES_DIR, staticClientOverride) | ||
74 | clientsRouter.use(`/client/${staticClientOverride}`, asyncMiddleware(serveClientOverride(overridePhysicalPath))) | ||
75 | } | ||
76 | |||
56 | clientsRouter.use('/client/locales/:locale/:file.json', serveServerTranslations) | 77 | clientsRouter.use('/client/locales/:locale/:file.json', serveServerTranslations) |
57 | clientsRouter.use('/client', express.static(distPath, { maxAge: STATIC_MAX_AGE.CLIENT })) | 78 | clientsRouter.use('/client', express.static(distPath, { maxAge: STATIC_MAX_AGE.CLIENT })) |
58 | 79 | ||
@@ -130,3 +151,28 @@ function sendHTML (html: string, res: express.Response) { | |||
130 | 151 | ||
131 | return res.send(html) | 152 | return res.send(html) |
132 | } | 153 | } |
154 | |||
155 | async function generateManifest (req: express.Request, res: express.Response) { | ||
156 | const manifestPhysicalPath = join(root(), 'client', 'dist', 'manifest.webmanifest') | ||
157 | const manifestJson = await fs.readFile(manifestPhysicalPath, 'utf8') | ||
158 | const manifest = JSON.parse(manifestJson) | ||
159 | |||
160 | manifest.name = CONFIG.INSTANCE.NAME | ||
161 | manifest.short_name = CONFIG.INSTANCE.NAME | ||
162 | manifest.description = CONFIG.INSTANCE.SHORT_DESCRIPTION | ||
163 | |||
164 | res.json(manifest) | ||
165 | } | ||
166 | |||
167 | function serveClientOverride (path: string) { | ||
168 | return async (req: express.Request, res: express.Response, next: express.NextFunction) => { | ||
169 | try { | ||
170 | await fs.access(path, constants.F_OK) | ||
171 | // Serve override client | ||
172 | res.sendFile(path, { maxAge: STATIC_MAX_AGE.SERVER }) | ||
173 | } catch { | ||
174 | // Serve dist client | ||
175 | next() | ||
176 | } | ||
177 | } | ||
178 | } | ||