fix(api): correct API key generation and proxy handling

This commit resolves an issue where generating a new API key would fail. The root cause was improper handling of POST request bodies in the frontend proxy server.

- Refactored `ApiKeyController` methods to use arrow functions to ensure correct `this` binding.
This commit is contained in:
wayneshn
2025-11-15 18:33:19 +01:00
parent c2006dfa94
commit ca6e516d32
3 changed files with 31 additions and 17 deletions

View File

@@ -16,7 +16,7 @@ const generateApiKeySchema = z.object({
});
export class ApiKeyController {
private userService = new UserService();
public async generateApiKey(req: Request, res: Response) {
public generateApiKey = async (req: Request, res: Response) => {
try {
const { name, expiresInDays } = generateApiKeySchema.parse(req.body);
if (!req.user || !req.user.sub) {
@@ -45,9 +45,9 @@ export class ApiKeyController {
}
res.status(500).json({ message: req.t('errors.internalServerError') });
}
}
};
public async getApiKeys(req: Request, res: Response) {
public getApiKeys = async (req: Request, res: Response) => {
if (!req.user || !req.user.sub) {
return res.status(401).json({ message: 'Unauthorized' });
}
@@ -55,9 +55,9 @@ export class ApiKeyController {
const keys = await ApiKeyService.getKeys(userId);
res.status(200).json(keys);
}
};
public async deleteApiKey(req: Request, res: Response) {
public deleteApiKey = async (req: Request, res: Response) => {
const { id } = req.params;
if (!req.user || !req.user.sub) {
return res.status(401).json({ message: 'Unauthorized' });
@@ -70,5 +70,5 @@ export class ApiKeyController {
await ApiKeyService.deleteKey(id, userId, actor, req.ip || 'unknown');
res.status(204).send({ message: req.t('apiKeys.deleteSuccess') });
}
};
}

View File

@@ -20,16 +20,17 @@ export class ApiKeyService {
expiresAt.setDate(expiresAt.getDate() + expiresInDays);
const keyHash = createHash('sha256').update(key).digest('hex');
await db.insert(apiKeys).values({
userId,
name,
key: CryptoService.encrypt(key),
keyHash,
expiresAt,
});
try {
await db.insert(apiKeys).values({
userId,
name,
key: CryptoService.encrypt(key),
keyHash,
expiresAt,
});
await this.auditService.createAuditLog({
actorIdentifier: actor.id,
await this.auditService.createAuditLog({
actorIdentifier: actor.id,
actionType: 'GENERATE',
targetType: 'ApiKey',
targetId: name,
@@ -40,6 +41,9 @@ export class ApiKeyService {
});
return key;
} catch (error) {
throw error;
}
}
public static async getKeys(userId: string): Promise<ApiKey[]> {

View File

@@ -10,10 +10,20 @@ const handleRequest: RequestHandler = async ({ request, params, fetch }) => {
const targetUrl = `${BACKEND_URL}/${slug}${url.search}`;
try {
let body: ArrayBuffer | null = null;
const headers = new Headers(request.headers);
if (request.method !== 'GET' && request.method !== 'HEAD') {
body = await request.arrayBuffer();
if (body.byteLength > 0) {
headers.set('Content-Length', String(body.byteLength));
}
}
const proxyRequest = new Request(targetUrl, {
method: request.method,
headers: request.headers,
body: request.body,
headers: headers,
body: body,
duplex: 'half',
} as RequestInit);