Skip to content

Commit

Permalink
Merge branch 'main' of github.com:Cap-go/capgo into fix_sec_issue_rls
Browse files Browse the repository at this point in the history
  • Loading branch information
WcaleNieWolny committed Nov 9, 2024
2 parents dda08d7 + 9de82c4 commit f9c7efb
Show file tree
Hide file tree
Showing 8 changed files with 13,130 additions and 214 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### 11.4.125 (2024-11-09)


### Bug Fixes

* stripe ([19ec018](https://github.com/Cap-go/capgo/commit/19ec018112aead69d9e1d3c972d7c65e2f805327))

### 11.4.124 (2024-11-08)

### 11.4.123 (2024-11-07)
Expand Down
Binary file modified bun.lockb
Binary file not shown.
13,267 changes: 13,073 additions & 194 deletions deno.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "capgo-app",
"type": "module",
"version": "11.4.124",
"version": "11.4.125",
"private": true,
"scripts": {
"env:hard-setup": "supabase stop && supabase start && supabase db reset",
Expand Down Expand Up @@ -158,7 +158,7 @@
"plausible-tracker": "^0.3.9",
"postgres": "^3.4.5",
"posthog-js": "^1.177.0",
"stripe": "^16.10.0",
"stripe": "^17.3.0",
"tailwind-capacitor": "^1.0.8",
"unplugin-auto-import": "^0.18.3",
"unplugin-formkit": "^0.3.0",
Expand Down
26 changes: 22 additions & 4 deletions supabase/functions/_backend/triggers/stripe_event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Context } from '@hono/hono'
import { Hono } from 'hono/tiny'
import { addTagBento, trackBentoEvent } from '../utils/bento.ts'
import { logsnag } from '../utils/logsnag.ts'
import { removeOldSubscription } from '../utils/stripe.ts'
import { extractDataEvent, parseStripeEvent } from '../utils/stripe_event.ts'
import { customerToSegmentOrg, supabaseAdmin } from '../utils/supabase.ts'
import { getEnv } from '../utils/utils.ts'
Expand All @@ -21,7 +20,8 @@ app.post('/', async (c: Context) => {
// event.headers
const body = await c.req.text()
const stripeEvent = await parseStripeEvent(c, body, signature!)
const stripeData = await extractDataEvent(c, stripeEvent)
const stripeDataEvent = extractDataEvent(c, stripeEvent)
const stripeData = stripeDataEvent.data
if (stripeData.customer_id === '')
return c.json({ error: 'no customer found', stripeData, stripeEvent, body }, 500)

Expand Down Expand Up @@ -64,9 +64,24 @@ app.post('/', async (c: Context) => {
.from('stripe_info')
.update(stripeData)
.eq('customer_id', stripeData.customer_id)
if (customer && customer.subscription_id && customer.subscription_id !== stripeData.subscription_id) {
await removeOldSubscription(c, customer.subscription_id)
if (stripeDataEvent.isUpgrade && stripeDataEvent.previousProductId) {
statusName = 'upgraded'
const previousProduct = await supabaseAdmin(c)
.from('plans')
.select()
.eq('stripe_id', stripeDataEvent.previousProductId)
.single()
await LogSnag.track({
channel: 'usage',
event: 'User Upgraded',
icon: '💰',
user_id: org.id,
notify: true,
tags: {
plan_name: plan.name,
previous_plan_name: previousProduct.data?.name || '',
},
}).catch()
}

if (dbError2)
Expand All @@ -83,6 +98,9 @@ app.post('/', async (c: Context) => {
icon: '💰',
user_id: org.id,
notify: status === 'succeeded',
tags: {
plan_name: plan.name,
},
}).catch()
}
else {
Expand Down
12 changes: 8 additions & 4 deletions supabase/functions/_backend/utils/stripe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import type { Context } from '@hono/hono'
import Stripe from 'stripe'
import { existInEnv, getEnv } from './utils.ts'

const getStripe = (c: Context) => new Stripe(getEnv(c, 'STRIPE_SECRET_KEY'))
export function getStripe(c: Context) {
return new Stripe(getEnv(c, 'STRIPE_SECRET_KEY'), {
apiVersion: '2024-10-28.acacia',
httpClient: Stripe.createFetchHttpClient(),
})
}

export async function createPortal(c: Context, customerId: string, callbackUrl: string) {
if (!existInEnv(c, 'STRIPE_SECRET_KEY'))
Expand All @@ -24,12 +29,11 @@ export function updateCustomerEmail(c: Context, customerId: string, newEmail: st
export async function cancelSubscription(c: Context, customerId: string) {
if (!existInEnv(c, 'STRIPE_SECRET_KEY'))
return Promise.resolve()
const stripe = new Stripe(getEnv(c, 'STRIPE_SECRET_KEY'))
const allSubscriptions = await stripe.subscriptions.list({
const allSubscriptions = await getStripe(c).subscriptions.list({
customer: customerId,
})
return Promise.all(
allSubscriptions.data.map(sub => stripe.subscriptions.cancel(sub.id)),
allSubscriptions.data.map(sub => getStripe(c).subscriptions.cancel(sub.id)),
).catch((err) => {
console.error({ requestId: c.get('requestId'), context: 'cancelSubscription', error: err })
})
Expand Down
26 changes: 17 additions & 9 deletions supabase/functions/_backend/utils/stripe_event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@ import type { Context } from '@hono/hono'
import type { MeteredData } from './stripe.ts'
import type { Database } from './supabase.types.ts'
import Stripe from 'stripe'
import { parsePriceIds } from './stripe.ts'
import { getStripe, parsePriceIds } from './stripe.ts'
import { getEnv } from './utils.ts'

export function parseStripeEvent(c: Context, body: string, signature: string) {
const secretKey = getEnv(c, 'STRIPE_SECRET_KEY')
const webhookKey = getEnv(c, 'STRIPE_WEBHOOK_SECRET')
const stripe = new Stripe(secretKey, {
apiVersion: '2024-04-10',
httpClient: Stripe.createFetchHttpClient(),
})

return stripe.webhooks.constructEventAsync(
return getStripe(c).webhooks.constructEventAsync(
body,
signature,
webhookKey,
Expand All @@ -22,7 +17,7 @@ export function parseStripeEvent(c: Context, body: string, signature: string) {
)
}

export function extractDataEvent(c: Context, event: Stripe.Event): Database['public']['Tables']['stripe_info']['Insert'] {
export function extractDataEvent(c: Context, event: Stripe.Event): { data: Database['public']['Tables']['stripe_info']['Insert'], isUpgrade: boolean, previousProductId: string | undefined } {
const data: Database['public']['Tables']['stripe_info']['Insert'] = {
product_id: 'free',
price_id: '',
Expand All @@ -34,11 +29,19 @@ export function extractDataEvent(c: Context, event: Stripe.Event): Database['pub
is_good_plan: true,
status: undefined,
}
let isUpgrade = false
let previousProductId: string | undefined

console.log({ requestId: c.get('requestId'), context: 'event', event: JSON.stringify(event, null, 2) })
if (event && event.data && event.data.object) {
if (event.type === 'customer.subscription.updated') {
const subscription = event.data.object
const previousAttributes = event.data.previous_attributes as Partial<Stripe.Subscription>

// Get previous items if available
const previousItems = previousAttributes?.items?.data as Stripe.SubscriptionItem[] | undefined
previousProductId = previousItems?.[0]?.plan.product as string | undefined

const res = parsePriceIds(c, subscription.items.data)
data.price_id = res.priceId
if (res.productId)
Expand All @@ -54,6 +57,11 @@ export function extractDataEvent(c: Context, event: Stripe.Event): Database['pub
data.status = subscription.cancel_at ? 'canceled' : 'updated'
data.subscription_id = subscription.id
data.customer_id = String(subscription.customer)

// Check if this is an upgrade
if (previousProductId && data.product_id !== previousProductId) {
isUpgrade = true
}
}
else if (event.type === 'customer.subscription.deleted') {
const charge = event.data.object
Expand All @@ -65,5 +73,5 @@ export function extractDataEvent(c: Context, event: Stripe.Event): Database['pub
console.error({ requestId: c.get('requestId'), context: 'Other event', event })
}
}
return data
return { data, isUpgrade, previousProductId }
}
2 changes: 1 addition & 1 deletion supabase/functions/import_map.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"hono/http-exception": "jsr:@hono/hono@^4.6.7/http-exception",
"hono/adapter": "jsr:@hono/hono@^4.6.7/adapter",
"hono/utils/buffer": "jsr:@hono/hono@^4.6.7/utils/buffer",
"stripe": "npm:stripe@15.8.0",
"stripe": "npm:stripe@17.3.0",
"zod": "https://esm.sh/[email protected]?target=deno",
"dayjs": "https://esm.sh/[email protected]?target=deno",
"ky": "https://esm.sh/[email protected]",
Expand Down

0 comments on commit f9c7efb

Please sign in to comment.