]>
Commit | Line | Data |
---|---|---|
1 | import cors from 'cors' | |
2 | import express from 'express' | |
3 | import { CONFIG, isEmailEnabled } from '@server/initializers/config' | |
4 | import { serveIndexHTML } from '@server/lib/client-html' | |
5 | import { ServerConfigManager } from '@server/lib/server-config-manager' | |
6 | import { HttpStatusCode } from '@shared/models' | |
7 | import { HttpNodeinfoDiasporaSoftwareNsSchema20 } from '../../shared/models/nodeinfo/nodeinfo.model' | |
8 | import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION, ROUTE_CACHE_LIFETIME } from '../initializers/constants' | |
9 | import { getThemeOrDefault } from '../lib/plugins/theme-utils' | |
10 | import { asyncMiddleware } from '../middlewares' | |
11 | import { cacheRoute } from '../middlewares/cache/cache' | |
12 | import { UserModel } from '../models/user/user' | |
13 | import { VideoModel } from '../models/video/video' | |
14 | import { VideoCommentModel } from '../models/video/video-comment' | |
15 | ||
16 | const miscRouter = express.Router() | |
17 | ||
18 | miscRouter.use(cors()) | |
19 | ||
20 | miscRouter.use('/nodeinfo/:version.json', | |
21 | cacheRoute(ROUTE_CACHE_LIFETIME.NODEINFO), | |
22 | asyncMiddleware(generateNodeinfo) | |
23 | ) | |
24 | ||
25 | // robots.txt service | |
26 | miscRouter.get('/robots.txt', | |
27 | cacheRoute(ROUTE_CACHE_LIFETIME.ROBOTS), | |
28 | (_, res: express.Response) => { | |
29 | res.type('text/plain') | |
30 | ||
31 | return res.send(CONFIG.INSTANCE.ROBOTS) | |
32 | } | |
33 | ) | |
34 | ||
35 | miscRouter.all('/teapot', | |
36 | getCup, | |
37 | asyncMiddleware(serveIndexHTML) | |
38 | ) | |
39 | ||
40 | // security.txt service | |
41 | miscRouter.get('/security.txt', | |
42 | (_, res: express.Response) => { | |
43 | return res.redirect(HttpStatusCode.MOVED_PERMANENTLY_301, '/.well-known/security.txt') | |
44 | } | |
45 | ) | |
46 | ||
47 | // --------------------------------------------------------------------------- | |
48 | ||
49 | export { | |
50 | miscRouter | |
51 | } | |
52 | ||
53 | // --------------------------------------------------------------------------- | |
54 | ||
55 | async function generateNodeinfo (req: express.Request, res: express.Response) { | |
56 | const { totalVideos } = await VideoModel.getStats() | |
57 | const { totalLocalVideoComments } = await VideoCommentModel.getStats() | |
58 | const { totalUsers, totalMonthlyActiveUsers, totalHalfYearActiveUsers } = await UserModel.getStats() | |
59 | ||
60 | if (!req.params.version || req.params.version !== '2.0') { | |
61 | return res.fail({ | |
62 | status: HttpStatusCode.NOT_FOUND_404, | |
63 | message: 'Nodeinfo schema version not handled' | |
64 | }) | |
65 | } | |
66 | ||
67 | const json = { | |
68 | version: '2.0', | |
69 | software: { | |
70 | name: 'peertube', | |
71 | version: PEERTUBE_VERSION | |
72 | }, | |
73 | protocols: [ | |
74 | 'activitypub' | |
75 | ], | |
76 | services: { | |
77 | inbound: [], | |
78 | outbound: [ | |
79 | 'atom1.0', | |
80 | 'rss2.0' | |
81 | ] | |
82 | }, | |
83 | openRegistrations: CONFIG.SIGNUP.ENABLED, | |
84 | usage: { | |
85 | users: { | |
86 | total: totalUsers, | |
87 | activeMonth: totalMonthlyActiveUsers, | |
88 | activeHalfyear: totalHalfYearActiveUsers | |
89 | }, | |
90 | localPosts: totalVideos, | |
91 | localComments: totalLocalVideoComments | |
92 | }, | |
93 | metadata: { | |
94 | taxonomy: { | |
95 | postsName: 'Videos' | |
96 | }, | |
97 | nodeName: CONFIG.INSTANCE.NAME, | |
98 | nodeDescription: CONFIG.INSTANCE.SHORT_DESCRIPTION, | |
99 | nodeConfig: { | |
100 | search: { | |
101 | remoteUri: { | |
102 | users: CONFIG.SEARCH.REMOTE_URI.USERS, | |
103 | anonymous: CONFIG.SEARCH.REMOTE_URI.ANONYMOUS | |
104 | } | |
105 | }, | |
106 | plugin: { | |
107 | registered: ServerConfigManager.Instance.getRegisteredPlugins() | |
108 | }, | |
109 | theme: { | |
110 | registered: ServerConfigManager.Instance.getRegisteredThemes(), | |
111 | default: getThemeOrDefault(CONFIG.THEME.DEFAULT, DEFAULT_THEME_NAME) | |
112 | }, | |
113 | email: { | |
114 | enabled: isEmailEnabled() | |
115 | }, | |
116 | contactForm: { | |
117 | enabled: CONFIG.CONTACT_FORM.ENABLED | |
118 | }, | |
119 | transcoding: { | |
120 | hls: { | |
121 | enabled: CONFIG.TRANSCODING.HLS.ENABLED | |
122 | }, | |
123 | webtorrent: { | |
124 | enabled: CONFIG.TRANSCODING.WEBTORRENT.ENABLED | |
125 | }, | |
126 | enabledResolutions: ServerConfigManager.Instance.getEnabledResolutions('vod') | |
127 | }, | |
128 | live: { | |
129 | enabled: CONFIG.LIVE.ENABLED, | |
130 | transcoding: { | |
131 | enabled: CONFIG.LIVE.TRANSCODING.ENABLED, | |
132 | enabledResolutions: ServerConfigManager.Instance.getEnabledResolutions('live') | |
133 | } | |
134 | }, | |
135 | import: { | |
136 | videos: { | |
137 | http: { | |
138 | enabled: CONFIG.IMPORT.VIDEOS.HTTP.ENABLED | |
139 | }, | |
140 | torrent: { | |
141 | enabled: CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED | |
142 | } | |
143 | } | |
144 | }, | |
145 | autoBlacklist: { | |
146 | videos: { | |
147 | ofUsers: { | |
148 | enabled: CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED | |
149 | } | |
150 | } | |
151 | }, | |
152 | avatar: { | |
153 | file: { | |
154 | size: { | |
155 | max: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max | |
156 | }, | |
157 | extensions: CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME | |
158 | } | |
159 | }, | |
160 | video: { | |
161 | image: { | |
162 | extensions: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME, | |
163 | size: { | |
164 | max: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max | |
165 | } | |
166 | }, | |
167 | file: { | |
168 | extensions: CONSTRAINTS_FIELDS.VIDEOS.EXTNAME | |
169 | } | |
170 | }, | |
171 | videoCaption: { | |
172 | file: { | |
173 | size: { | |
174 | max: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.FILE_SIZE.max | |
175 | }, | |
176 | extensions: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.EXTNAME | |
177 | } | |
178 | }, | |
179 | user: { | |
180 | videoQuota: CONFIG.USER.VIDEO_QUOTA, | |
181 | videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY | |
182 | }, | |
183 | trending: { | |
184 | videos: { | |
185 | intervalDays: CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS | |
186 | } | |
187 | }, | |
188 | tracker: { | |
189 | enabled: CONFIG.TRACKER.ENABLED | |
190 | } | |
191 | } | |
192 | } | |
193 | } as HttpNodeinfoDiasporaSoftwareNsSchema20 | |
194 | ||
195 | res.contentType('application/json; profile="http://nodeinfo.diaspora.software/ns/schema/2.0#"') | |
196 | .send(json) | |
197 | .end() | |
198 | } | |
199 | ||
200 | function getCup (req: express.Request, res: express.Response, next: express.NextFunction) { | |
201 | res.status(HttpStatusCode.I_AM_A_TEAPOT_418) | |
202 | res.setHeader('Accept-Additions', 'Non-Dairy;1,Sugar;1') | |
203 | res.setHeader('Safe', 'if-sepia-awake') | |
204 | ||
205 | return next() | |
206 | } |