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

teableio / teable / 20065394908

09 Dec 2025 01:36PM UTC coverage: 71.858%. First build
20065394908

Pull #2168

github

web-flow
Merge b9dc7a0f8 into 6fd609a47
Pull Request #2168: feat: base node

22892 of 25545 branches covered (89.61%)

1916 of 2478 new or added lines in 35 files covered. (77.32%)

57741 of 80354 relevant lines covered (71.86%)

4259.47 hits per line

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

24.49
/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
} from '@teable/openapi';
21
import {
22
  IUpdateSettingRo,
23
  testLLMRoSchema,
24
  updateSettingRoSchema,
25
  ITestLLMRo,
26
  setSettingMailTransportConfigRoSchema,
27
  ISetSettingMailTransportConfigRo,
28
  SettingKey,
29
} from '@teable/openapi';
30
import { IThresholdConfig, ThresholdConfig } from '../../../configs/threshold.config';
31
import { ZodValidationPipe } from '../../../zod.validation.pipe';
32
import { Permissions } from '../../auth/decorators/permissions.decorator';
33
import { Public } from '../../auth/decorators/public.decorator';
34
import { TurnstileService } from '../../auth/turnstile/turnstile.service';
35
import { SettingOpenApiService } from './setting-open-api.service';
36

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

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

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

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

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

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

134
  @Permissions('instance|update')
301✔
135
  @Put('set-mail-transport-config')
136
  async setMailTransportConfig(
×
137
    @Body(new ZodValidationPipe(setSettingMailTransportConfigRoSchema))
×
138
    setMailTransportConfigRo: ISetSettingMailTransportConfigRo
×
139
  ): Promise<ISetSettingMailTransportConfigVo> {
×
140
    await this.settingOpenApiService.setMailTransportConfig(setMailTransportConfigRo);
×
141

142
    return {
×
143
      ...setMailTransportConfigRo,
×
144
      transportConfig: {
×
145
        ...setMailTransportConfigRo.transportConfig,
×
146
        auth: {
×
147
          user: setMailTransportConfigRo.transportConfig.auth.user,
×
148
          pass: '',
×
149
        },
×
150
      },
×
151
    };
×
152
  }
×
153
}
301✔
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

© 2025 Coveralls, Inc