diff --git a/account/src/lib/couch-db.ts b/account/src/lib/couch-db.ts index ebc81f0..dfd3343 100644 --- a/account/src/lib/couch-db.ts +++ b/account/src/lib/couch-db.ts @@ -106,6 +106,7 @@ export async function updateLingdocsUser(uuid: T.UUID, toUpdate: wordlistDbName: T.WordlistDbName, couchDbPassword: T.UserDbPassword, upgradeToStudentRequest: undefined, + subscriptionId: string | undefined, } | { level: "basic", diff --git a/account/src/lib/sample-users.ts b/account/src/lib/sample-users.ts index b11965b..ebb1b77 100644 --- a/account/src/lib/sample-users.ts +++ b/account/src/lib/sample-users.ts @@ -28,6 +28,7 @@ const student: AT.LingdocsUser = { "lastActive":1630414108552 as AT.TimeStamp, "couchDbPassword": "12345" as AT.UserDbPassword, "wordlistDbName": "jim-db" as AT.WordlistDbName, + subscriptionId: undefined, }; const admin: AT.LingdocsUser = { @@ -45,6 +46,7 @@ const admin: AT.LingdocsUser = { "lastActive":1630414108552 as AT.TimeStamp, "couchDbPassword": "12345" as AT.UserDbPassword, "wordlistDbName": "jim-db" as AT.WordlistDbName, + subscriptionId: undefined, }; const editor: AT.LingdocsUser = { @@ -61,6 +63,7 @@ const editor: AT.LingdocsUser = { "lastActive":1630414108552 as AT.TimeStamp, "couchDbPassword": "12345" as AT.UserDbPassword, "wordlistDbName": "jim-db" as AT.WordlistDbName, + subscriptionId: undefined, }; // @ts-ignore diff --git a/account/src/lib/user-utils.ts b/account/src/lib/user-utils.ts index 8754cf7..ce30f6a 100644 --- a/account/src/lib/user-utils.ts +++ b/account/src/lib/user-utils.ts @@ -16,6 +16,12 @@ import { } from "../lib/mail-utils"; import { outsideProviders } from "../middleware/setup-passport"; import * as T from "../../../website/src/types/account-types"; +import env from "../lib/env-vars"; +import Stripe from "stripe"; + +const stripe = new Stripe(env.stripeSecretKey, { + apiVersion: "2022-08-01", +}); function getUUID(): T.UUID { return uuidv4() as T.UUID; @@ -51,7 +57,7 @@ export function getEmailFromGoogleProfile(profile: T.GoogleProfile): { email: st }; } -export async function upgradeUser(userId: T.UUID): Promise { +export async function upgradeUser(userId: T.UUID, subscriptionId?: string): Promise { // add user to couchdb authentication db const { password, userDbName } = await addCouchDbAuthUser(userId); // // create user db @@ -61,6 +67,7 @@ export async function upgradeUser(userId: T.UUID): Promise { +export async function downgradeUser(userId: T.UUID, subscriptionId?: string): Promise { await deleteCouchDbAuthUser(userId); + if (subscriptionId) { + stripe.subscriptions.del(subscriptionId); + } const user = await updateLingdocsUser(userId, { level: "basic", wordlistDbName: undefined, diff --git a/account/src/routers/auth-router.ts b/account/src/routers/auth-router.ts index 559cb95..8acb9f3 100644 --- a/account/src/routers/auth-router.ts +++ b/account/src/routers/auth-router.ts @@ -196,7 +196,9 @@ const authRouter = (passport: PassportStatic) => { if (!req.user) { return res.redirect("/"); } - await downgradeUser(req.user.userId); + await downgradeUser(req.user.userId, "subscriptionId" in req.user + ? req.user.subscriptionId + : undefined); res.redirect("/"); } catch (e) { next(e); diff --git a/account/src/routers/payment-router.ts b/account/src/routers/payment-router.ts index e0f27da..4c178f0 100644 --- a/account/src/routers/payment-router.ts +++ b/account/src/routers/payment-router.ts @@ -54,7 +54,7 @@ paymentRouter.post( subscription = event.data.object; status = subscription.status; console.log(`Upgrading user ${userId}.`); - await upgradeUser(userId); + await upgradeUser(userId, subscription.id); // TODO: save subscription to db break; default: diff --git a/website/src/types/account-types.ts b/website/src/types/account-types.ts index fb582b1..c12c956 100644 --- a/website/src/types/account-types.ts +++ b/website/src/types/account-types.ts @@ -56,6 +56,7 @@ export type LingdocsUser = { level: "student" | "editor", couchDbPassword: UserDbPassword, wordlistDbName: WordlistDbName, + subscriptionId: string | undefined, } ) & import("nano").MaybeDocument;