changemaker.lite/api/src/modules/payments/payment-settings.service.ts
2026-02-18 10:01:54 -07:00

72 lines
2.3 KiB
TypeScript

import { prisma } from '../../config/database';
import type { PaymentSettings } from '@prisma/client';
import type { UpdatePaymentSettingsInput } from './payments.schemas';
import { encrypt, decrypt } from '../../utils/crypto';
import { resetStripeClient } from '../../services/stripe.client';
const ENCRYPTED_FIELDS = ['stripeSecretKey', 'stripeWebhookSecret'] as const;
const SENSITIVE_FIELDS = ['stripeSecretKey', 'stripeWebhookSecret'] as const;
function decryptSettings(settings: PaymentSettings): PaymentSettings {
for (const field of ENCRYPTED_FIELDS) {
const value = settings[field];
if (typeof value === 'string' && value) {
(settings as Record<string, unknown>)[field] = decrypt(value);
}
}
return settings;
}
export const paymentSettingsService = {
/** Full settings with decrypted secrets (admin use) */
async get(): Promise<PaymentSettings> {
let settings = await prisma.paymentSettings.findFirst();
if (!settings) {
settings = await prisma.paymentSettings.create({ data: {} });
}
return decryptSettings(settings);
},
/** Public-safe settings (strips secret keys) */
async getPublic() {
const settings = await this.get();
const result = { ...settings } as Record<string, unknown>;
for (const field of SENSITIVE_FIELDS) {
delete result[field];
}
return result;
},
async update(data: UpdatePaymentSettingsInput): Promise<PaymentSettings> {
const toWrite = { ...data } as Record<string, unknown>;
// Encrypt sensitive fields
for (const field of ENCRYPTED_FIELDS) {
if (field in toWrite && typeof toWrite[field] === 'string' && toWrite[field]) {
toWrite[field] = encrypt(toWrite[field] as string);
}
}
// Handle donationSuggestedAmounts as JSON
if (data.donationSuggestedAmounts) {
toWrite.donationSuggestedAmounts = JSON.stringify(data.donationSuggestedAmounts);
}
const existing = await prisma.paymentSettings.findFirst();
let settings: PaymentSettings;
if (existing) {
settings = await prisma.paymentSettings.update({
where: { id: existing.id },
data: toWrite,
});
} else {
settings = await prisma.paymentSettings.create({ data: toWrite });
}
// Reset Stripe client so it picks up new keys
resetStripeClient();
return decryptSettings(settings);
},
};