mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-14 08:36:22 +08:00
refactor(server): config system (#11081)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user