add ALTCHA challenge endpoint and env config.

GET /api/altcha/challenge, nullcart-style env validation, and ALTCHA_ENABLED wiring.
This commit is contained in:
2026-10-05 23:53:28 +02:00
parent edd97c17f7
commit 87376ea37f
12 changed files with 293 additions and 18 deletions
@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { AltchaController } from './controllers/AltchaController';
import { AltchaService } from './services/AltchaService';
@Module({
controllers: [AltchaController],
providers: [AltchaService],
exports: [AltchaService]
})
export class AltchaModule {}
@@ -0,0 +1,23 @@
import { Controller, Get, NotFoundException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { AltchaService } from '../services/AltchaService';
import { Config } from '../../../types/Config';
@Controller('altcha')
export class AltchaController {
constructor(
private readonly altchaService: AltchaService,
private readonly configService: ConfigService
) {}
@Get('challenge')
async getChallenge() {
const { enabled } = this.configService.get('altcha') as Config['altcha'];
if (!enabled) {
throw new NotFoundException();
}
return this.altchaService.createChallenge();
}
}
@@ -0,0 +1,19 @@
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { createChallenge } from 'altcha-lib/v1';
import type { Challenge } from 'altcha-lib/v1/types';
import { Config } from '../../../types/Config';
@Injectable()
export class AltchaService {
constructor(private readonly configService: ConfigService) {}
async createChallenge(): Promise<Challenge> {
const { hmacKey, maxNumber } = this.configService.get('altcha') as Config['altcha'];
return createChallenge({
hmacKey,
maxNumber
});
}
}