mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-13 22:18:27 +09:00
51 lines
2.0 KiB
TypeScript
51 lines
2.0 KiB
TypeScript
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import {AdminACLs} from '@fluxer/constants/src/AdminACLs';
|
|
import {FeatureNotAvailableSelfHostedError} from '@fluxer/errors/src/domains/core/FeatureNotAvailableSelfHostedError';
|
|
import {CodesResponse, GenerateGiftCodesRequest} from '@fluxer/schema/src/domains/admin/AdminSchemas';
|
|
import {Config} from '../../Config';
|
|
import {requireAdminACL} from '../../middleware/AdminMiddleware';
|
|
import {RateLimitMiddleware} from '../../middleware/RateLimitMiddleware';
|
|
import {OpenAPI} from '../../middleware/ResponseTypeMiddleware';
|
|
import {RateLimitConfigs} from '../../RateLimitConfig';
|
|
import type {HonoApp} from '../../types/HonoEnv';
|
|
import {Validator} from '../../Validator';
|
|
|
|
function trimTrailingSlash(value: string): string {
|
|
return value.endsWith('/') ? value.slice(0, -1) : value;
|
|
}
|
|
|
|
export function CodesAdminController(app: HonoApp) {
|
|
app.post(
|
|
'/admin/gift-codes',
|
|
RateLimitMiddleware(RateLimitConfigs.ADMIN_CODE_GENERATION),
|
|
requireAdminACL(AdminACLs.GIFT_CODES_GENERATE),
|
|
Validator('json', GenerateGiftCodesRequest),
|
|
OpenAPI({
|
|
operationId: 'create_admin_gift_codes',
|
|
summary: 'Issue gift codes',
|
|
description:
|
|
'Create one-use Plutonium gift codes with an explicit positive duration and return their complete redemption links. Lifetime gifts are not supported. Not available on self-hosted instances. Requires GIFT_CODES_GENERATE permission.',
|
|
responseSchema: CodesResponse,
|
|
statusCode: 200,
|
|
security: 'adminApiKey',
|
|
tags: 'Admin',
|
|
}),
|
|
async (ctx) => {
|
|
if (Config.instance.selfHosted) {
|
|
throw new FeatureNotAvailableSelfHostedError();
|
|
}
|
|
const {count, duration_type, duration_quantity} = ctx.req.valid('json');
|
|
const codes = await ctx.get('adminService').codeGenerationService.generateGiftCodes({
|
|
count,
|
|
durationType: duration_type,
|
|
durationQuantity: duration_quantity,
|
|
});
|
|
const baseUrl = trimTrailingSlash(Config.endpoints.gift);
|
|
return ctx.json({
|
|
codes: codes.map((code) => `${baseUrl}/${code}`),
|
|
});
|
|
},
|
|
);
|
|
}
|