diff options
author | Chocobozzz <me@florianbigard.com> | 2019-01-09 15:14:29 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-01-10 11:32:37 +0100 |
commit | a4101923e699e49ceb9ff36e971c75417fafc9f0 (patch) | |
tree | c098a87ac5a85e1bc7454facbb59ecbd6c7dac82 /server/controllers/api | |
parent | 8d00889b6038c38d9c86cbeca88a9f3c23962c48 (diff) | |
download | PeerTube-a4101923e699e49ceb9ff36e971c75417fafc9f0.tar.gz PeerTube-a4101923e699e49ceb9ff36e971c75417fafc9f0.tar.zst PeerTube-a4101923e699e49ceb9ff36e971c75417fafc9f0.zip |
Implement contact form on server side
Diffstat (limited to 'server/controllers/api')
-rw-r--r-- | server/controllers/api/config.ts | 55 | ||||
-rw-r--r-- | server/controllers/api/server/contact.ts | 28 | ||||
-rw-r--r-- | server/controllers/api/server/index.ts | 2 |
3 files changed, 58 insertions, 27 deletions
diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts index c75002aaf..43b20e078 100644 --- a/server/controllers/api/config.ts +++ b/server/controllers/api/config.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { omit } from 'lodash' | 2 | import { omit, snakeCase } from 'lodash' |
3 | import { ServerConfig, UserRight } from '../../../shared' | 3 | import { ServerConfig, UserRight } from '../../../shared' |
4 | import { About } from '../../../shared/models/server/about.model' | 4 | import { About } from '../../../shared/models/server/about.model' |
5 | import { CustomConfig } from '../../../shared/models/server/custom-config.model' | 5 | import { CustomConfig } from '../../../shared/models/server/custom-config.model' |
@@ -12,6 +12,8 @@ import { auditLoggerFactory, CustomConfigAuditView, getAuditIdFromRes } from '.. | |||
12 | import { remove, writeJSON } from 'fs-extra' | 12 | import { remove, writeJSON } from 'fs-extra' |
13 | import { getServerCommit } from '../../helpers/utils' | 13 | import { getServerCommit } from '../../helpers/utils' |
14 | import { Emailer } from '../../lib/emailer' | 14 | import { Emailer } from '../../lib/emailer' |
15 | import { isNumeric } from 'validator' | ||
16 | import { objectConverter } from '../../helpers/core-utils' | ||
15 | 17 | ||
16 | const packageJSON = require('../../../../package.json') | 18 | const packageJSON = require('../../../../package.json') |
17 | const configRouter = express.Router() | 19 | const configRouter = express.Router() |
@@ -65,6 +67,9 @@ async function getConfig (req: express.Request, res: express.Response) { | |||
65 | email: { | 67 | email: { |
66 | enabled: Emailer.Instance.isEnabled() | 68 | enabled: Emailer.Instance.isEnabled() |
67 | }, | 69 | }, |
70 | contactForm: { | ||
71 | enabled: CONFIG.CONTACT_FORM.ENABLED | ||
72 | }, | ||
68 | serverVersion: packageJSON.version, | 73 | serverVersion: packageJSON.version, |
69 | serverCommit, | 74 | serverCommit, |
70 | signup: { | 75 | signup: { |
@@ -154,34 +159,10 @@ async function deleteCustomConfig (req: express.Request, res: express.Response, | |||
154 | } | 159 | } |
155 | 160 | ||
156 | async function updateCustomConfig (req: express.Request, res: express.Response, next: express.NextFunction) { | 161 | async function updateCustomConfig (req: express.Request, res: express.Response, next: express.NextFunction) { |
157 | const toUpdate: CustomConfig = req.body | ||
158 | const oldCustomConfigAuditKeys = new CustomConfigAuditView(customConfig()) | 162 | const oldCustomConfigAuditKeys = new CustomConfigAuditView(customConfig()) |
159 | 163 | ||
160 | // Force number conversion | 164 | // camelCase to snake_case key + Force number conversion |
161 | toUpdate.cache.previews.size = parseInt('' + toUpdate.cache.previews.size, 10) | 165 | const toUpdateJSON = convertCustomConfigBody(req.body) |
162 | toUpdate.cache.captions.size = parseInt('' + toUpdate.cache.captions.size, 10) | ||
163 | toUpdate.signup.limit = parseInt('' + toUpdate.signup.limit, 10) | ||
164 | toUpdate.user.videoQuota = parseInt('' + toUpdate.user.videoQuota, 10) | ||
165 | toUpdate.user.videoQuotaDaily = parseInt('' + toUpdate.user.videoQuotaDaily, 10) | ||
166 | toUpdate.transcoding.threads = parseInt('' + toUpdate.transcoding.threads, 10) | ||
167 | |||
168 | // camelCase to snake_case key | ||
169 | const toUpdateJSON = omit( | ||
170 | toUpdate, | ||
171 | 'user.videoQuota', | ||
172 | 'instance.defaultClientRoute', | ||
173 | 'instance.shortDescription', | ||
174 | 'cache.videoCaptions', | ||
175 | 'signup.requiresEmailVerification', | ||
176 | 'transcoding.allowAdditionalExtensions' | ||
177 | ) | ||
178 | toUpdateJSON.user['video_quota'] = toUpdate.user.videoQuota | ||
179 | toUpdateJSON.user['video_quota_daily'] = toUpdate.user.videoQuotaDaily | ||
180 | toUpdateJSON.instance['default_client_route'] = toUpdate.instance.defaultClientRoute | ||
181 | toUpdateJSON.instance['short_description'] = toUpdate.instance.shortDescription | ||
182 | toUpdateJSON.instance['default_nsfw_policy'] = toUpdate.instance.defaultNSFWPolicy | ||
183 | toUpdateJSON.signup['requires_email_verification'] = toUpdate.signup.requiresEmailVerification | ||
184 | toUpdateJSON.transcoding['allow_additional_extensions'] = toUpdate.transcoding.allowAdditionalExtensions | ||
185 | 166 | ||
186 | await writeJSON(CONFIG.CUSTOM_FILE, toUpdateJSON, { spaces: 2 }) | 167 | await writeJSON(CONFIG.CUSTOM_FILE, toUpdateJSON, { spaces: 2 }) |
187 | 168 | ||
@@ -243,6 +224,9 @@ function customConfig (): CustomConfig { | |||
243 | admin: { | 224 | admin: { |
244 | email: CONFIG.ADMIN.EMAIL | 225 | email: CONFIG.ADMIN.EMAIL |
245 | }, | 226 | }, |
227 | contactForm: { | ||
228 | enabled: CONFIG.CONTACT_FORM.ENABLED | ||
229 | }, | ||
246 | user: { | 230 | user: { |
247 | videoQuota: CONFIG.USER.VIDEO_QUOTA, | 231 | videoQuota: CONFIG.USER.VIDEO_QUOTA, |
248 | videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY | 232 | videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY |
@@ -271,3 +255,20 @@ function customConfig (): CustomConfig { | |||
271 | } | 255 | } |
272 | } | 256 | } |
273 | } | 257 | } |
258 | |||
259 | function convertCustomConfigBody (body: CustomConfig) { | ||
260 | function keyConverter (k: string) { | ||
261 | // Transcoding resolutions exception | ||
262 | if (/^\d{3,4}p$/.exec(k)) return k | ||
263 | |||
264 | return snakeCase(k) | ||
265 | } | ||
266 | |||
267 | function valueConverter (v: any) { | ||
268 | if (isNumeric(v + '')) return parseInt('' + v, 10) | ||
269 | |||
270 | return v | ||
271 | } | ||
272 | |||
273 | return objectConverter(body, keyConverter, valueConverter) | ||
274 | } | ||
diff --git a/server/controllers/api/server/contact.ts b/server/controllers/api/server/contact.ts new file mode 100644 index 000000000..b1144c94e --- /dev/null +++ b/server/controllers/api/server/contact.ts | |||
@@ -0,0 +1,28 @@ | |||
1 | import * as express from 'express' | ||
2 | import { asyncMiddleware, contactAdministratorValidator } from '../../../middlewares' | ||
3 | import { Redis } from '../../../lib/redis' | ||
4 | import { Emailer } from '../../../lib/emailer' | ||
5 | import { ContactForm } from '../../../../shared/models/server' | ||
6 | |||
7 | const contactRouter = express.Router() | ||
8 | |||
9 | contactRouter.post('/contact', | ||
10 | asyncMiddleware(contactAdministratorValidator), | ||
11 | asyncMiddleware(contactAdministrator) | ||
12 | ) | ||
13 | |||
14 | async function contactAdministrator (req: express.Request, res: express.Response) { | ||
15 | const data = req.body as ContactForm | ||
16 | |||
17 | await Emailer.Instance.addContactFormJob(data.fromEmail, data.fromName, data.body) | ||
18 | |||
19 | await Redis.Instance.setContactFormIp(req.ip) | ||
20 | |||
21 | return res.status(204).end() | ||
22 | } | ||
23 | |||
24 | // --------------------------------------------------------------------------- | ||
25 | |||
26 | export { | ||
27 | contactRouter | ||
28 | } | ||
diff --git a/server/controllers/api/server/index.ts b/server/controllers/api/server/index.ts index c08192a8c..814248e5f 100644 --- a/server/controllers/api/server/index.ts +++ b/server/controllers/api/server/index.ts | |||
@@ -3,6 +3,7 @@ import { serverFollowsRouter } from './follows' | |||
3 | import { statsRouter } from './stats' | 3 | import { statsRouter } from './stats' |
4 | import { serverRedundancyRouter } from './redundancy' | 4 | import { serverRedundancyRouter } from './redundancy' |
5 | import { serverBlocklistRouter } from './server-blocklist' | 5 | import { serverBlocklistRouter } from './server-blocklist' |
6 | import { contactRouter } from './contact' | ||
6 | 7 | ||
7 | const serverRouter = express.Router() | 8 | const serverRouter = express.Router() |
8 | 9 | ||
@@ -10,6 +11,7 @@ serverRouter.use('/', serverFollowsRouter) | |||
10 | serverRouter.use('/', serverRedundancyRouter) | 11 | serverRouter.use('/', serverRedundancyRouter) |
11 | serverRouter.use('/', statsRouter) | 12 | serverRouter.use('/', statsRouter) |
12 | serverRouter.use('/', serverBlocklistRouter) | 13 | serverRouter.use('/', serverBlocklistRouter) |
14 | serverRouter.use('/', contactRouter) | ||
13 | 15 | ||
14 | // --------------------------------------------------------------------------- | 16 | // --------------------------------------------------------------------------- |
15 | 17 | ||