72 lines
2.3 KiB
TypeScript
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);
|
|
},
|
|
};
|