Skip to content

Commit

Permalink
[payment] cancel all subscriptions on user deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
JanKoehnlein committed Jun 16, 2021
1 parent f3b6cbe commit 06e2f33
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ export class TeamSubscriptionService {
const subscriptionsFromTS = subscriptions.filter(s => AssignedTeamSubscription.is(s));
return new SubscriptionModel(userId, subscriptionsFromTS);
}

async findTeamSubscriptionSlotsByAssignee(assigneeId: string): Promise<TeamSubscriptionSlot[]> {
return this.db.findSlotsByAssignee(assigneeId);
}
}

const flatten = <T>(input: T[][]): T[] => {
Expand Down
50 changes: 35 additions & 15 deletions components/server/ee/src/user/user-deletion-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,58 @@ import { SubscriptionService } from "@gitpod/gitpod-payment-endpoint/lib/account
import { Plans } from "@gitpod/gitpod-protocol/lib/plans";
import { ChargebeeService } from "./chargebee-service";
import { EnvEE } from "../env";
import { TeamSubscriptionService } from "@gitpod/gitpod-payment-endpoint/lib/accounting";
import { log } from '@gitpod/gitpod-protocol/lib/util/logging';

@injectable()
export class UserDeletionServiceEE extends UserDeletionService {
@inject(ChargebeeService) protected readonly chargebeeService: ChargebeeService;
@inject(SubscriptionService) protected readonly subscriptionService: SubscriptionService;
@inject(EnvEE) protected readonly env: EnvEE;
@inject(TeamSubscriptionService) protected readonly teamSubscriptionService: TeamSubscriptionService;

async deleteUser(id: string): Promise<void> {
const user = await this.db.findUserById(id);
if (!user) {
throw new Error(`No user with id ${id} found!`);
}

const errors = [];
if (this.env.enablePayment) {
const now = new Date().toISOString();
const subscriptions = await this.subscriptionService.getNotYetCancelledSubscriptions(user, now);
const now = new Date();
const subscriptions = await this.subscriptionService.getNotYetCancelledSubscriptions(user, now.toISOString());
for (const subscription of subscriptions) {
const planId = subscription.planId!;
if (Plans.isFreeNonTransientPlan(planId)) {
// only delete those plans that are persisted in the DB
await this.subscriptionService.unsubscribe(user.id, now, planId);
} else if (Plans.isFreePlan(planId)) {
// we do not care about transient plans
continue;
} else {
// cancel Chargebee subscriptions
const subscriptionId = subscription.uid;
const chargebeeSubscriptionId = subscription.paymentReference!;
await this.chargebeeService.cancelSubscription(chargebeeSubscriptionId, { userId: user.id }, { subscriptionId, chargebeeSubscriptionId });
try {
const planId = subscription.planId!;
const paymentReference = subscription.paymentReference;
if (Plans.isFreeNonTransientPlan(planId)) {
// only delete those plans that are persisted in the DB
await this.subscriptionService.unsubscribe(user.id, now.toISOString(), planId);
} else if (Plans.isFreePlan(planId)) {
// we do not care about transient plans
continue;
}
if (!paymentReference) {
const teamSlots = await this.teamSubscriptionService.findTeamSubscriptionSlotsByAssignee(id);
teamSlots.forEach(async ts => await this.teamSubscriptionService.deactivateSlot(ts.teamSubscriptionId, ts.id, now))
} else if (paymentReference.startsWith("github:")) {
throw new Error("Cannot delete user subscription from GitHub")
} else {
// cancel Chargebee subscriptions
const subscriptionId = subscription.uid;
const chargebeeSubscriptionId = subscription.paymentReference!;
await this.chargebeeService.cancelSubscription(chargebeeSubscriptionId, { userId: user.id }, { subscriptionId, chargebeeSubscriptionId });
}
} catch (error) {
errors.push(error);
log.error("Error cancelling subscription", error, { subscription })
}
}
}

return super.deleteUser(id);
await super.deleteUser(id);
if (errors) {
throw new Error(errors.join("\n"))
}
}
}

0 comments on commit 06e2f33

Please sign in to comment.