• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cameri / nostream / 29475888092

16 Jul 2026 06:09AM UTC coverage: 68.718%. First build
29475888092

Pull #690

github

web-flow
Merge cc5c7b38e into 7d99a24bd
Pull Request #690: feat(admin): add authenticated settings API endpoints

2166 of 3511 branches covered (61.69%)

Branch coverage included in aggregate %.

324 of 364 new or added lines in 17 files covered. (89.01%)

4925 of 6808 relevant lines covered (72.34%)

23.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.67
/src/controllers/admin/patch-settings-controller.ts
1
import { Request, Response } from 'express'
2

3
import { Settings } from '../../@types/settings'
4
import { IController } from '../../@types/controllers'
5
import { adminSettingsPatchBodySchema } from '../../schemas/admin-settings-schema'
2✔
6
import {
2✔
7
  getByPath,
8
  loadMergedSettings,
9
  loadUserSettings,
10
  saveSettings,
11
  setByPath,
12
  validatePathAgainstDefaults,
13
  validateSettings,
14
} from '../../utils/settings-config'
15
import {
2✔
16
  isWriteProtectedSettingsPath,
17
  redactSettingsValue,
18
} from '../../utils/settings-redaction'
19
import { validateSchema } from '../../utils/validation'
2✔
20

21
export class PatchAdminSettingsController implements IController {
2✔
22
  public async handleRequest(request: Request, response: Response): Promise<void> {
23
    const validation = validateSchema(adminSettingsPatchBodySchema)(request.body)
4✔
24
    if (validation.error) {
4✔
25
      response.status(400).setHeader('content-type', 'application/json').send({ error: 'Invalid request' })
1✔
26
      return
1✔
27
    }
28

29
    const { path, value } = validation.value
3✔
30

31
    if (isWriteProtectedSettingsPath(path)) {
3✔
32
      response
1✔
33
        .status(400)
34
        .setHeader('content-type', 'application/json')
35
        .send({
36
          error: 'Validation failed',
37
          issues: [{ path, message: 'Path is write-protected' }],
38
        })
39
      return
1✔
40
    }
41

42
    const pathIssues = validatePathAgainstDefaults(path)
2✔
43
    if (pathIssues.length > 0) {
2✔
44
      response
1✔
45
        .status(400)
46
        .setHeader('content-type', 'application/json')
47
        .send({ error: 'Validation failed', issues: pathIssues })
48
      return
1✔
49
    }
50

51
    const userSettings = loadUserSettings() as unknown as Record<string, unknown>
1✔
52
    const nextUserSettings = setByPath(userSettings, path, value)
1✔
53

54
    const merged = loadMergedSettings() as unknown as Record<string, unknown>
1✔
55
    const mergedNext = setByPath(merged, path, getByPath(nextUserSettings, path))
1✔
56
    const validationIssues = validateSettings(mergedNext as unknown as Settings)
1✔
57

58
    if (validationIssues.length > 0) {
1!
NEW
59
      response
×
60
        .status(400)
61
        .setHeader('content-type', 'application/json')
62
        .send({ error: 'Validation failed', issues: validationIssues })
NEW
63
      return
×
64
    }
65

66
    saveSettings(nextUserSettings as unknown as Settings)
1✔
67

68
    const updatedValue = redactSettingsValue(path, getByPath(nextUserSettings, path))
1✔
69

70
    response.status(200).setHeader('content-type', 'application/json').send({
1✔
71
      ok: true,
72
      path,
73
      value: updatedValue,
74
    })
75
  }
76
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc