fix: use private helcimApiToken for all server-side Helcim API calls

This commit is contained in:
Jennie Robinson Faber 2026-04-04 13:37:34 +01:00
parent ccd1d0783a
commit d31b5b4dac
53 changed files with 1755 additions and 572 deletions

View file

@ -1,48 +1,19 @@
// Update member's contribution tier
import jwt from "jsonwebtoken";
import {
getHelcimPlanId,
requiresPayment,
isValidContributionValue,
} from "../../config/contributions.js";
import Member from "../../models/member.js";
import { connectDB } from "../../utils/mongoose.js";
import Member from "../../models/member.js";
const HELCIM_API_BASE = "https://api.helcim.com/v2";
export default defineEventHandler(async (event) => {
try {
const member = await requireAuth(event);
await connectDB();
const config = useRuntimeConfig(event);
const body = await validateBody(event, updateContributionSchema);
const token = getCookie(event, "auth-token");
if (!token) {
throw createError({
statusCode: 401,
statusMessage: "Not authenticated",
});
}
// Decode JWT token
let decoded;
try {
decoded = jwt.verify(token, useRuntimeConfig().jwtSecret);
} catch (err) {
throw createError({
statusCode: 401,
statusMessage: "Invalid or expired token",
});
}
// Get member
const member = await Member.findById(decoded.memberId);
if (!member) {
throw createError({
statusCode: 404,
statusMessage: "Member not found",
});
}
const oldTier = member.contributionTier;
const newTier = body.contributionTier;
@ -55,8 +26,7 @@ export default defineEventHandler(async (event) => {
};
}
const helcimToken =
config.public.helcimToken || process.env.NUXT_PUBLIC_HELCIM_TOKEN;
const helcimToken = config.helcimApiToken;
const oldRequiresPayment = requiresPayment(oldTier);
const newRequiresPayment = requiresPayment(newTier);
@ -73,8 +43,7 @@ export default defineEventHandler(async (event) => {
}
// Try to fetch customer info from Helcim to check for saved cards
const helcimToken =
config.public.helcimToken || process.env.NUXT_PUBLIC_HELCIM_TOKEN;
const helcimToken = config.helcimApiToken;
try {
const customerResponse = await fetch(
@ -185,11 +154,11 @@ export default defineEventHandler(async (event) => {
}
// Update member record
member.contributionTier = newTier;
member.helcimSubscriptionId = subscription.id;
member.paymentMethod = "card";
member.status = "active";
await member.save();
await Member.findByIdAndUpdate(
member._id,
{ $set: { contributionTier: newTier, helcimSubscriptionId: subscription.id, paymentMethod: "card", status: "active" } },
{ runValidators: false }
);
return {
success: true,
@ -241,10 +210,11 @@ export default defineEventHandler(async (event) => {
}
// Update member to free tier
member.contributionTier = newTier;
member.helcimSubscriptionId = null;
member.paymentMethod = "none";
await member.save();
await Member.findByIdAndUpdate(
member._id,
{ $set: { contributionTier: newTier, helcimSubscriptionId: null, paymentMethod: "none" } },
{ runValidators: false }
);
return {
success: true,
@ -303,8 +273,11 @@ export default defineEventHandler(async (event) => {
const subscriptionData = await response.json();
// Update member record
member.contributionTier = newTier;
await member.save();
await Member.findByIdAndUpdate(
member._id,
{ $set: { contributionTier: newTier } },
{ runValidators: false }
);
return {
success: true,
@ -321,8 +294,11 @@ export default defineEventHandler(async (event) => {
}
// Case 4: Moving between free tiers (shouldn't happen but handle it)
member.contributionTier = newTier;
await member.save();
await Member.findByIdAndUpdate(
member._id,
{ $set: { contributionTier: newTier } },
{ runValidators: false }
);
return {
success: true,