Frontend: - Add runtime configuration service for deployment-time API URL injection - Create docker-entrypoint.sh to generate config.json from environment variables - Update ApiService, ApprovalService, and DocumentViewer to use RuntimeConfigService - Add APP_INITIALIZER to load runtime config before app starts Backend: - Fix init-blockchain.js to properly quote mnemonic phrases in .env file - Improve docker-entrypoint.sh with health checks and better error handling Docker: - Add API_BASE_URL environment variable to frontend container - Update docker-compose.yml with clear documentation for remote deployment - Reorganize .env.example with clear categories (REQUIRED FOR REMOTE, PRODUCTION, AUTO-GENERATED) Workflow fixes: - Fix DepartmentApproval interface to match backend schema - Fix stage transformation for 0-indexed stageOrder - Fix workflow list to show correct stage count from definition.stages Cleanup: - Move development artifacts to .trash directory - Remove root-level package.json (was only for utility scripts) - Add .trash/ to .gitignore
42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
|
import { PassportStrategy } from '@nestjs/passport';
|
|
import { Strategy } from 'passport-jwt';
|
|
import { Request } from 'express';
|
|
import { AuthService } from '../auth.service';
|
|
import { API_KEY_HEADER, DEPARTMENT_CODE_HEADER } from '../../../common/constants';
|
|
|
|
@Injectable()
|
|
export class ApiKeyStrategy extends PassportStrategy(Strategy, 'api-key') {
|
|
constructor(private readonly authService: AuthService) {
|
|
super({
|
|
jwtFromRequest: (req: Request) => {
|
|
const apiKey = req.headers[API_KEY_HEADER] as string;
|
|
const departmentCode = req.headers[DEPARTMENT_CODE_HEADER] as string;
|
|
|
|
if (!apiKey || !departmentCode) {
|
|
return null;
|
|
}
|
|
|
|
// Return a dummy token - actual validation happens in validate()
|
|
return `${apiKey}:${departmentCode}`;
|
|
},
|
|
secretOrKey: 'api-key-strategy',
|
|
});
|
|
}
|
|
|
|
async validate(token: string): Promise<{ departmentId: string; departmentCode: string }> {
|
|
const [apiKey, departmentCode] = token.split(':');
|
|
|
|
if (!apiKey || !departmentCode) {
|
|
throw new UnauthorizedException('API key and department code are required');
|
|
}
|
|
|
|
const result = await this.authService.validateDepartmentApiKey(apiKey, departmentCode);
|
|
|
|
return {
|
|
departmentId: result.department.id,
|
|
departmentCode: result.department.code,
|
|
};
|
|
}
|
|
}
|