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

teableio / teable / 20687176870

04 Jan 2026 03:48AM UTC coverage: 71.723% (-0.2%) from 71.97%
20687176870

Pull #2385

github

web-flow
Merge 717d5ed80 into 3eb1bddbb
Pull Request #2385: [sync] fix: publish base modal preview style T1547 (#972)

24605 of 27585 branches covered (89.2%)

26 of 320 new or added lines in 5 files covered. (8.13%)

13 existing lines in 4 files now uncovered.

60457 of 84292 relevant lines covered (71.72%)

4537.66 hits per line

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

24.04
/apps/nestjs-backend/src/features/setting/open-api/setting-open-api.controller.ts
1
/* eslint-disable sonarjs/no-duplicate-string */
8✔
2
import {
3
  BadRequestException,
4
  Body,
5
  Controller,
6
  Get,
7
  Patch,
8
  Post,
9
  Put,
10
  UploadedFile,
11
  UseInterceptors,
12
} from '@nestjs/common';
13
import { FileInterceptor } from '@nestjs/platform-express';
14
import type {
15
  IPublicSettingVo,
16
  ISetSettingMailTransportConfigVo,
17
  ISettingVo,
18
  ITestLLMVo,
19
  IUploadLogoVo,
20
  IBatchTestLLMVo,
21
} from '@teable/openapi';
22
import {
23
  IUpdateSettingRo,
24
  testLLMRoSchema,
25
  updateSettingRoSchema,
26
  ITestLLMRo,
27
  setSettingMailTransportConfigRoSchema,
28
  ISetSettingMailTransportConfigRo,
29
  SettingKey,
30
  batchTestLLMRoSchema,
31
  IBatchTestLLMRo,
32
} from '@teable/openapi';
33
import { IThresholdConfig, ThresholdConfig } from '../../../configs/threshold.config';
34
import { ZodValidationPipe } from '../../../zod.validation.pipe';
35
import { Permissions } from '../../auth/decorators/permissions.decorator';
36
import { Public } from '../../auth/decorators/public.decorator';
37
import { TurnstileService } from '../../auth/turnstile/turnstile.service';
38
import { SettingOpenApiService } from './setting-open-api.service';
39

40
@Controller('api/admin/setting')
41
export class SettingOpenApiController {
8✔
42
  constructor(
315✔
43
    private readonly settingOpenApiService: SettingOpenApiService,
315✔
44
    private readonly turnstileService: TurnstileService,
315✔
45
    @ThresholdConfig() private readonly thresholdConfig: IThresholdConfig
315✔
46
  ) {}
315✔
47

48
  /**
315✔
49
   * Get the instance settings, now we have config for AI, there are some sensitive fields, we need check the permission before return.
50
   */
315✔
51
  @Permissions('instance|read')
315✔
52
  @Get()
53
  async getSetting(): Promise<ISettingVo> {
×
54
    return await this.settingOpenApiService.getSetting();
×
55
  }
×
56

57
  /**
315✔
58
   * Public endpoint for getting public settings without authentication
59
   */
315✔
60
  @Public()
315✔
61
  @Get('public')
62
  async getPublicSetting(): Promise<IPublicSettingVo> {
×
63
    const setting = await this.settingOpenApiService.getSetting([
×
64
      SettingKey.INSTANCE_ID,
×
65
      SettingKey.BRAND_NAME,
×
66
      SettingKey.BRAND_LOGO,
×
67
      SettingKey.DISALLOW_SIGN_UP,
×
68
      SettingKey.DISALLOW_SPACE_CREATION,
×
69
      SettingKey.DISALLOW_SPACE_INVITATION,
×
70
      SettingKey.DISALLOW_DASHBOARD,
×
71
      SettingKey.ENABLE_EMAIL_VERIFICATION,
×
72
      SettingKey.ENABLE_WAITLIST,
×
73
      SettingKey.AI_CONFIG,
×
74
      SettingKey.APP_CONFIG,
×
75
      SettingKey.WEB_SEARCH_CONFIG,
×
76
    ]);
×
77
    const { aiConfig, appConfig, webSearchConfig, ...rest } = setting;
×
78
    return {
×
79
      ...rest,
×
80
      aiConfig: {
×
81
        enable: aiConfig?.enable ?? false,
×
82
        llmProviders:
×
83
          aiConfig?.llmProviders?.map((provider) => ({
×
84
            type: provider.type,
×
85
            name: provider.name,
×
86
            models: provider.models,
×
87
          })) ?? [],
×
88
        chatModel: aiConfig?.chatModel,
×
89
        capabilities: aiConfig?.capabilities,
×
90
      },
×
91
      appGenerationEnabled: Boolean(appConfig?.apiKey),
×
92
      webSearchEnabled: Boolean(webSearchConfig?.apiKey),
×
93
      turnstileSiteKey: this.turnstileService.getTurnstileSiteKey(),
×
94
      changeEmailSendCodeMailRate: this.thresholdConfig.changeEmailSendCodeMailRate,
×
95
      resetPasswordSendMailRate: this.thresholdConfig.resetPasswordSendMailRate,
×
96
      signupVerificationSendCodeMailRate: this.thresholdConfig.signupVerificationSendCodeMailRate,
×
97
    };
×
98
  }
×
99

100
  @Patch()
315✔
101
  @Permissions('instance|update')
102
  async updateSetting(
1✔
103
    @Body(new ZodValidationPipe(updateSettingRoSchema))
1✔
104
    updateSettingRo: IUpdateSettingRo
1✔
105
  ): Promise<ISettingVo> {
1✔
106
    return await this.settingOpenApiService.updateSetting(updateSettingRo);
1✔
107
  }
1✔
108

109
  @UseInterceptors(
315✔
110
    FileInterceptor('file', {
111
      fileFilter: (_req, file, callback) => {
×
112
        if (file.mimetype.startsWith('image/')) {
×
113
          callback(null, true);
×
114
        } else {
×
115
          callback(new BadRequestException('Invalid file type'), false);
×
116
        }
×
117
      },
×
118
      limits: {
×
119
        fileSize: 500 * 1024, // limit file size is 500KB
×
120
      },
×
121
    })
122
  )
123
  @Patch('logo')
124
  @Permissions('instance|update')
125
  async uploadLogo(@UploadedFile() file: Express.Multer.File): Promise<IUploadLogoVo> {
×
126
    return this.settingOpenApiService.uploadLogo(file);
×
127
  }
×
128

129
  @Permissions('instance|update')
315✔
130
  @Post('test-llm')
131
  async testLLM(
×
132
    @Body(new ZodValidationPipe(testLLMRoSchema)) testLLMRo: ITestLLMRo
×
133
  ): Promise<ITestLLMVo> {
×
134
    return await this.settingOpenApiService.testLLM(testLLMRo);
×
135
  }
×
136

137
  @Permissions('instance|update')
315✔
138
  @Post('batch-test-llm')
NEW
139
  async batchTestLLM(
×
NEW
140
    @Body(new ZodValidationPipe(batchTestLLMRoSchema.optional())) batchTestLLMRo?: IBatchTestLLMRo
×
NEW
141
  ): Promise<IBatchTestLLMVo> {
×
NEW
142
    return await this.settingOpenApiService.batchTestLLM(batchTestLLMRo);
×
NEW
143
  }
×
144

145
  @Permissions('instance|update')
315✔
146
  @Put('set-mail-transport-config')
147
  async setMailTransportConfig(
×
148
    @Body(new ZodValidationPipe(setSettingMailTransportConfigRoSchema))
×
149
    setMailTransportConfigRo: ISetSettingMailTransportConfigRo
×
150
  ): Promise<ISetSettingMailTransportConfigVo> {
×
151
    await this.settingOpenApiService.setMailTransportConfig(setMailTransportConfigRo);
×
152

153
    return {
×
154
      ...setMailTransportConfigRo,
×
155
      transportConfig: {
×
156
        ...setMailTransportConfigRo.transportConfig,
×
157
        auth: {
×
158
          user: setMailTransportConfigRo.transportConfig.auth.user,
×
159
          pass: '',
×
160
        },
×
161
      },
×
162
    };
×
163
  }
×
164
}
315✔
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