diff options
author | Chocobozzz <chocobozzz@cpy.re> | 2021-05-27 15:59:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-27 15:59:55 +0200 |
commit | 2539932e16129992a2c0889b4ff527c265a8e2c7 (patch) | |
tree | fb5048e63e02a2485eb96d27455f43e4b22e8ae0 /shared | |
parent | eb34ec30e0b57286fc6f85160490d2e973a3b0b1 (diff) | |
download | PeerTube-2539932e16129992a2c0889b4ff527c265a8e2c7.tar.gz PeerTube-2539932e16129992a2c0889b4ff527c265a8e2c7.tar.zst PeerTube-2539932e16129992a2c0889b4ff527c265a8e2c7.zip |
Instance homepage support (#4007)
* Prepare homepage parsers
* Add ability to update instance hompage
* Add ability to set homepage as landing page
* Add homepage preview in admin
* Dynamically update left menu for homepage
* Inject home content in homepage
* Add videos list and channel miniature custom markup
* Remove unused elements in markup service
Diffstat (limited to 'shared')
-rw-r--r-- | shared/core-utils/miscs/miscs.ts | 17 | ||||
-rw-r--r-- | shared/core-utils/renderer/html.ts | 52 | ||||
-rw-r--r-- | shared/extra-utils/custom-pages/custom-pages.ts | 31 | ||||
-rw-r--r-- | shared/extra-utils/index.ts | 2 | ||||
-rw-r--r-- | shared/models/actors/custom-page.model.ts | 3 | ||||
-rw-r--r-- | shared/models/actors/index.ts | 1 | ||||
-rw-r--r-- | shared/models/custom-markup/custom-markup-data.model.ts | 28 | ||||
-rw-r--r-- | shared/models/custom-markup/index.ts | 1 | ||||
-rw-r--r-- | shared/models/index.ts | 1 | ||||
-rw-r--r-- | shared/models/server/server-config.model.ts | 4 | ||||
-rw-r--r-- | shared/models/users/user-right.enum.ts | 1 |
11 files changed, 124 insertions, 17 deletions
diff --git a/shared/core-utils/miscs/miscs.ts b/shared/core-utils/miscs/miscs.ts index 71703faac..4780ca922 100644 --- a/shared/core-utils/miscs/miscs.ts +++ b/shared/core-utils/miscs/miscs.ts | |||
@@ -28,9 +28,24 @@ function isCatchable (value: any) { | |||
28 | return value && typeof value.catch === 'function' | 28 | return value && typeof value.catch === 'function' |
29 | } | 29 | } |
30 | 30 | ||
31 | function sortObjectComparator (key: string, order: 'asc' | 'desc') { | ||
32 | return (a: any, b: any) => { | ||
33 | if (a[key] < b[key]) { | ||
34 | return order === 'asc' ? -1 : 1 | ||
35 | } | ||
36 | |||
37 | if (a[key] > b[key]) { | ||
38 | return order === 'asc' ? 1 : -1 | ||
39 | } | ||
40 | |||
41 | return 0 | ||
42 | } | ||
43 | } | ||
44 | |||
31 | export { | 45 | export { |
32 | randomInt, | 46 | randomInt, |
33 | compareSemVer, | 47 | compareSemVer, |
34 | isPromise, | 48 | isPromise, |
35 | isCatchable | 49 | isCatchable, |
50 | sortObjectComparator | ||
36 | } | 51 | } |
diff --git a/shared/core-utils/renderer/html.ts b/shared/core-utils/renderer/html.ts index de4ad47ac..bbf8b3fbd 100644 --- a/shared/core-utils/renderer/html.ts +++ b/shared/core-utils/renderer/html.ts | |||
@@ -1,25 +1,45 @@ | |||
1 | export const SANITIZE_OPTIONS = { | 1 | export function getSanitizeOptions () { |
2 | allowedTags: [ 'a', 'p', 'span', 'br', 'strong', 'em', 'ul', 'ol', 'li' ], | 2 | return { |
3 | allowedSchemes: [ 'http', 'https' ], | 3 | allowedTags: [ 'a', 'p', 'span', 'br', 'strong', 'em', 'ul', 'ol', 'li' ], |
4 | allowedAttributes: { | 4 | allowedSchemes: [ 'http', 'https' ], |
5 | a: [ 'href', 'class', 'target', 'rel' ] | 5 | allowedAttributes: { |
6 | }, | 6 | 'a': [ 'href', 'class', 'target', 'rel' ], |
7 | transformTags: { | 7 | '*': [ 'data-*' ] |
8 | a: (tagName: string, attribs: any) => { | 8 | }, |
9 | let rel = 'noopener noreferrer' | 9 | transformTags: { |
10 | if (attribs.rel === 'me') rel += ' me' | 10 | a: (tagName: string, attribs: any) => { |
11 | let rel = 'noopener noreferrer' | ||
12 | if (attribs.rel === 'me') rel += ' me' | ||
11 | 13 | ||
12 | return { | 14 | return { |
13 | tagName, | 15 | tagName, |
14 | attribs: Object.assign(attribs, { | 16 | attribs: Object.assign(attribs, { |
15 | target: '_blank', | 17 | target: '_blank', |
16 | rel | 18 | rel |
17 | }) | 19 | }) |
20 | } | ||
18 | } | 21 | } |
19 | } | 22 | } |
20 | } | 23 | } |
21 | } | 24 | } |
22 | 25 | ||
26 | export function getCustomMarkupSanitizeOptions (additionalAllowedTags: string[] = []) { | ||
27 | const base = getSanitizeOptions() | ||
28 | |||
29 | return { | ||
30 | allowedTags: [ | ||
31 | ...base.allowedTags, | ||
32 | ...additionalAllowedTags, | ||
33 | 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' | ||
34 | ], | ||
35 | allowedSchemes: base.allowedSchemes, | ||
36 | allowedAttributes: { | ||
37 | ...base.allowedAttributes, | ||
38 | '*': [ 'data-*', 'style' ] | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | |||
23 | // Thanks: https://stackoverflow.com/a/12034334 | 43 | // Thanks: https://stackoverflow.com/a/12034334 |
24 | export function escapeHTML (stringParam: string) { | 44 | export function escapeHTML (stringParam: string) { |
25 | if (!stringParam) return '' | 45 | if (!stringParam) return '' |
diff --git a/shared/extra-utils/custom-pages/custom-pages.ts b/shared/extra-utils/custom-pages/custom-pages.ts new file mode 100644 index 000000000..bf2d16c70 --- /dev/null +++ b/shared/extra-utils/custom-pages/custom-pages.ts | |||
@@ -0,0 +1,31 @@ | |||
1 | import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' | ||
2 | import { makeGetRequest, makePutBodyRequest } from '../requests/requests' | ||
3 | |||
4 | function getInstanceHomepage (url: string, statusCodeExpected = HttpStatusCode.OK_200) { | ||
5 | const path = '/api/v1/custom-pages/homepage/instance' | ||
6 | |||
7 | return makeGetRequest({ | ||
8 | url, | ||
9 | path, | ||
10 | statusCodeExpected | ||
11 | }) | ||
12 | } | ||
13 | |||
14 | function updateInstanceHomepage (url: string, token: string, content: string) { | ||
15 | const path = '/api/v1/custom-pages/homepage/instance' | ||
16 | |||
17 | return makePutBodyRequest({ | ||
18 | url, | ||
19 | path, | ||
20 | token, | ||
21 | fields: { content }, | ||
22 | statusCodeExpected: HttpStatusCode.NO_CONTENT_204 | ||
23 | }) | ||
24 | } | ||
25 | |||
26 | // --------------------------------------------------------------------------- | ||
27 | |||
28 | export { | ||
29 | getInstanceHomepage, | ||
30 | updateInstanceHomepage | ||
31 | } | ||
diff --git a/shared/extra-utils/index.ts b/shared/extra-utils/index.ts index 720db19cb..3bc09ead5 100644 --- a/shared/extra-utils/index.ts +++ b/shared/extra-utils/index.ts | |||
@@ -2,6 +2,8 @@ export * from './bulk/bulk' | |||
2 | 2 | ||
3 | export * from './cli/cli' | 3 | export * from './cli/cli' |
4 | 4 | ||
5 | export * from './custom-pages/custom-pages' | ||
6 | |||
5 | export * from './feeds/feeds' | 7 | export * from './feeds/feeds' |
6 | 8 | ||
7 | export * from './mock-servers/mock-instances-index' | 9 | export * from './mock-servers/mock-instances-index' |
diff --git a/shared/models/actors/custom-page.model.ts b/shared/models/actors/custom-page.model.ts new file mode 100644 index 000000000..1e33584c1 --- /dev/null +++ b/shared/models/actors/custom-page.model.ts | |||
@@ -0,0 +1,3 @@ | |||
1 | export interface CustomPage { | ||
2 | content: string | ||
3 | } | ||
diff --git a/shared/models/actors/index.ts b/shared/models/actors/index.ts index 156f83248..e03f168cd 100644 --- a/shared/models/actors/index.ts +++ b/shared/models/actors/index.ts | |||
@@ -2,4 +2,5 @@ export * from './account.model' | |||
2 | export * from './actor-image.model' | 2 | export * from './actor-image.model' |
3 | export * from './actor-image.type' | 3 | export * from './actor-image.type' |
4 | export * from './actor.model' | 4 | export * from './actor.model' |
5 | export * from './custom-page.model' | ||
5 | export * from './follow.model' | 6 | export * from './follow.model' |
diff --git a/shared/models/custom-markup/custom-markup-data.model.ts b/shared/models/custom-markup/custom-markup-data.model.ts new file mode 100644 index 000000000..af697428e --- /dev/null +++ b/shared/models/custom-markup/custom-markup-data.model.ts | |||
@@ -0,0 +1,28 @@ | |||
1 | export type EmbedMarkupData = { | ||
2 | // Video or playlist uuid | ||
3 | uuid: string | ||
4 | } | ||
5 | |||
6 | export type VideoMiniatureMarkupData = { | ||
7 | // Video uuid | ||
8 | uuid: string | ||
9 | } | ||
10 | |||
11 | export type PlaylistMiniatureMarkupData = { | ||
12 | // Playlist uuid | ||
13 | uuid: string | ||
14 | } | ||
15 | |||
16 | export type ChannelMiniatureMarkupData = { | ||
17 | // Channel name (username) | ||
18 | name: string | ||
19 | } | ||
20 | |||
21 | export type VideosListMarkupData = { | ||
22 | title: string | ||
23 | description: string | ||
24 | sort: string | ||
25 | categoryOneOf: string // coma separated values | ||
26 | languageOneOf: string // coma separated values | ||
27 | count: string | ||
28 | } | ||
diff --git a/shared/models/custom-markup/index.ts b/shared/models/custom-markup/index.ts new file mode 100644 index 000000000..2898dfa90 --- /dev/null +++ b/shared/models/custom-markup/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './custom-markup-data.model' | |||
diff --git a/shared/models/index.ts b/shared/models/index.ts index dff5fdf0e..4db1f234e 100644 --- a/shared/models/index.ts +++ b/shared/models/index.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | export * from './activitypub' | 1 | export * from './activitypub' |
2 | export * from './actors' | 2 | export * from './actors' |
3 | export * from './moderation' | 3 | export * from './moderation' |
4 | export * from './custom-markup' | ||
4 | export * from './bulk' | 5 | export * from './bulk' |
5 | export * from './redundancy' | 6 | export * from './redundancy' |
6 | export * from './users' | 7 | export * from './users' |
diff --git a/shared/models/server/server-config.model.ts b/shared/models/server/server-config.model.ts index 2c5026b30..1667bc0e2 100644 --- a/shared/models/server/server-config.model.ts +++ b/shared/models/server/server-config.model.ts | |||
@@ -214,6 +214,10 @@ export interface ServerConfig { | |||
214 | level: BroadcastMessageLevel | 214 | level: BroadcastMessageLevel |
215 | dismissable: boolean | 215 | dismissable: boolean |
216 | } | 216 | } |
217 | |||
218 | homepage: { | ||
219 | enabled: boolean | ||
220 | } | ||
217 | } | 221 | } |
218 | 222 | ||
219 | export type HTMLServerConfig = Omit<ServerConfig, 'signup'> | 223 | export type HTMLServerConfig = Omit<ServerConfig, 'signup'> |
diff --git a/shared/models/users/user-right.enum.ts b/shared/models/users/user-right.enum.ts index bbedc9f00..950b22bad 100644 --- a/shared/models/users/user-right.enum.ts +++ b/shared/models/users/user-right.enum.ts | |||
@@ -16,6 +16,7 @@ export const enum UserRight { | |||
16 | MANAGE_JOBS, | 16 | MANAGE_JOBS, |
17 | 17 | ||
18 | MANAGE_CONFIGURATION, | 18 | MANAGE_CONFIGURATION, |
19 | MANAGE_INSTANCE_CUSTOM_PAGE, | ||
19 | 20 | ||
20 | MANAGE_ACCOUNTS_BLOCKLIST, | 21 | MANAGE_ACCOUNTS_BLOCKLIST, |
21 | MANAGE_SERVERS_BLOCKLIST, | 22 | MANAGE_SERVERS_BLOCKLIST, |