refactor(server): config system (#11081)

This commit is contained in:
forehalo
2025-03-27 12:32:28 +00:00
parent 7091111f85
commit 0ea38680fa
274 changed files with 7583 additions and 5841 deletions
@@ -1,18 +1,12 @@
import {
defineRuntimeConfig,
defineStartupConfig,
ModuleConfig,
} from '../../base/config';
import { defineModuleConfig } from '../../base';
import { CaptchaConfig } from './types';
declare module '../config' {
interface PluginsConfig {
captcha: ModuleConfig<
CaptchaConfig,
{
enable: boolean;
}
>;
declare global {
interface AppConfigSchema {
captcha: {
enabled: boolean;
config: ConfigItem<CaptchaConfig>;
};
}
}
@@ -22,18 +16,20 @@ declare module '../../base/guard' {
}
}
defineStartupConfig('plugins.captcha', {
turnstile: {
secret: '',
},
challenge: {
bits: 20,
},
});
defineRuntimeConfig('plugins.captcha', {
enable: {
defineModuleConfig('captcha', {
enabled: {
desc: 'Check captcha challenge when user authenticating the app.',
default: false,
},
config: {
desc: 'The config for the captcha plugin.',
default: {
turnstile: {
secret: '',
},
challenge: {
bits: 20,
},
},
},
});
@@ -6,9 +6,9 @@ import type {
import { Injectable } from '@nestjs/common';
import {
Config,
getRequestResponseFromContext,
GuardProvider,
Runtime,
} from '../../base';
import { CaptchaService } from './service';
@@ -20,14 +20,14 @@ export class CaptchaGuardProvider
name = 'captcha' as const;
constructor(
private readonly captcha: CaptchaService,
private readonly runtime: Runtime
private readonly config: Config,
private readonly captcha: CaptchaService
) {
super();
}
async canActivate(context: ExecutionContext) {
if (!(await this.runtime.fetch('plugins.captcha/enable'))) {
if (!this.config.captcha.enabled) {
return true;
}
@@ -1,19 +1,17 @@
import './config';
import { Module } from '@nestjs/common';
import { ServerConfigModule } from '../../core';
import { AuthModule } from '../../core/auth';
import { ServerFeature } from '../../core/config';
import { Plugin } from '../registry';
import { CaptchaController } from './controller';
import { CaptchaGuardProvider } from './guard';
import { CaptchaService } from './service';
@Plugin({
name: 'captcha',
imports: [AuthModule],
@Module({
imports: [AuthModule, ServerConfigModule],
providers: [CaptchaService, CaptchaGuardProvider],
controllers: [CaptchaController],
contributesTo: ServerFeature.Captcha,
requires: ['plugins.captcha.turnstile.secret'],
})
export class CaptchaModule {}
@@ -1,4 +1,3 @@
import assert from 'node:assert';
import { randomUUID } from 'node:crypto';
import { Injectable, Logger } from '@nestjs/common';
@@ -6,12 +5,10 @@ import type { Request } from 'express';
import { nanoid } from 'nanoid';
import { z } from 'zod';
import {
CaptchaVerificationFailed,
Config,
verifyChallengeResponse,
} from '../../base';
import { CaptchaVerificationFailed, Config, OnEvent } from '../../base';
import { ServerFeature, ServerService } from '../../core';
import { Models, TokenType } from '../../models';
import { verifyChallengeResponse } from '../../native';
import { CaptchaConfig } from './types';
const validator = z
@@ -26,10 +23,22 @@ export class CaptchaService {
constructor(
private readonly config: Config,
private readonly models: Models
private readonly models: Models,
private readonly server: ServerService
) {
assert(config.plugins.captcha);
this.captcha = config.plugins.captcha;
this.captcha = config.captcha.config;
}
@OnEvent('config.init')
onConfigInit() {
this.setup();
}
@OnEvent('config.changed')
onConfigChanged(event: Events['config.changed']) {
if ('captcha' in event.updates) {
this.setup();
}
}
private async verifyCaptchaToken(token: any, ip: string) {
@@ -52,7 +61,7 @@ export class CaptchaService {
return (
!!outcome.success &&
// skip hostname check in dev mode
(this.config.node.dev || outcome.hostname === this.config.server.host)
(env.dev || outcome.hostname === this.config.server.host)
);
}
@@ -119,4 +128,12 @@ export class CaptchaService {
}
}
}
private setup() {
if (this.config.captcha.enabled) {
this.server.enableFeature(ServerFeature.Captcha);
} else {
this.server.disableFeature(ServerFeature.Captcha);
}
}
}