diff --git a/supabase/functions/deno-packages/billing-functions/lib/upsert-data.ts b/supabase/functions/deno-packages/billing-functions/lib/upsert-data.ts index af42470..9b4d65d 100644 --- a/supabase/functions/deno-packages/billing-functions/lib/upsert-data.ts +++ b/supabase/functions/deno-packages/billing-functions/lib/upsert-data.ts @@ -1,7 +1,8 @@ +import SupabaseClient from 'https://esm.sh/v117/@supabase/supabase-js@2.21.0/dist/module/SupabaseClient.d.ts'; import {Database as BASEJUMP_DATABASE_SCHEMA} from '../types/basejump-database.ts'; export type BASEJUMP_BILLING_DATA_UPSERT = { - provider: BASEJUMP_DATABASE_SCHEMA["public"]["Tables"]["billing_providers"]["Row"]["provider"]; + provider: BASEJUMP_DATABASE_SCHEMA["basejump"]["Tables"]["billing_subscriptions"]["Row"]["provider"]; customer?: { id: string; billing_email?: string; @@ -11,7 +12,7 @@ export type BASEJUMP_BILLING_DATA_UPSERT = { subscription?: { id: string; billing_customer_id?: string; - status: BASEJUMP_DATABASE_SCHEMA["public"]["Tables"]["billing_subscriptions"]["Row"]["status"]; + status: BASEJUMP_DATABASE_SCHEMA["basejump"]["Tables"]["billing_subscriptions"]["Row"]["status"]; account_id: string; created_at: Date; updated_at: Date; @@ -34,8 +35,8 @@ export type BASEJUMP_BILLING_DATA_UPSERT = { }; export async function upsertCustomerSubscription( - supabaseClient, - accountId, + supabaseClient: SupabaseClient, + accountId: string, upsertData: BASEJUMP_BILLING_DATA_UPSERT ) { const {data, error} = await supabaseClient.rpc( diff --git a/supabase/functions/deno-packages/billing-functions/src/billing-functions-wrapper.ts b/supabase/functions/deno-packages/billing-functions/src/billing-functions-wrapper.ts index 0e60983..68854ee 100644 --- a/supabase/functions/deno-packages/billing-functions/src/billing-functions-wrapper.ts +++ b/supabase/functions/deno-packages/billing-functions/src/billing-functions-wrapper.ts @@ -58,9 +58,9 @@ type GENERIC_URL_RESPONSE = { export type GET_BILLING_STATUS_RESPONSE = { subscription_id: string; subscription_active: boolean; - status: BASEJUMP_DATABASE_SCHEMA["public"]["Tables"]["billing_subscriptions"]["Row"]["status"]; + status: BASEJUMP_DATABASE_SCHEMA["basejump"]["Tables"]["billing_subscriptions"]["Row"]["status"]; billing_email?: string; - account_role: BASEJUMP_DATABASE_SCHEMA["public"]["Tables"]["account_user"]["Row"]["account_role"]; + account_role: BASEJUMP_DATABASE_SCHEMA["basejump"]["Tables"]["account_user"]["Row"]["account_role"]; is_primary_owner: boolean; billing_enabled: boolean; }; @@ -70,7 +70,7 @@ type BILLING_FUNCTION_WRAPPER_OPTIONS = { } export type BILLING_FUNCTION_WRAPPER_HANDLERS = { - provider: BASEJUMP_DATABASE_SCHEMA["public"]["Tables"]["billing_providers"]["Row"]["provider"]; + provider: BASEJUMP_DATABASE_SCHEMA["basejump"]["Tables"]["billing_subscriptions"]["Row"]["provider"]; getPlans: (args: GET_PLANS_ARGS) => Promise; getBillingPortalUrl: ( args: GET_BILLING_PORTAL_URL_ARGS diff --git a/supabase/functions/deno-packages/billing-functions/src/require-authorized-billing-user.ts b/supabase/functions/deno-packages/billing-functions/src/require-authorized-billing-user.ts index 17b6337..84ea15d 100644 --- a/supabase/functions/deno-packages/billing-functions/src/require-authorized-billing-user.ts +++ b/supabase/functions/deno-packages/billing-functions/src/require-authorized-billing-user.ts @@ -1,9 +1,9 @@ import createSupabaseClient from "../lib/create-supabase-client.ts"; -import {BASEJUMP_DATABASE_SCHEMA} from "../mod.ts"; +import {Database as BASEJUMP_DATABASE_SCHEMA} from "../types/basejump-database.ts"; import errorResponse from "../lib/error-response.ts"; export type AUTHORIZED_BILLING_USER_INFO = { - account_role: BASEJUMP_DATABASE_SCHEMA["public"]["Tables"]["account_user"]["Row"]["account_role"]; + account_role: BASEJUMP_DATABASE_SCHEMA["basejump"]["Tables"]["account_user"]["Row"]["account_role"]; is_primary_owner: boolean; is_personal_account: boolean; account_id: string; @@ -45,7 +45,9 @@ export async function requireAuthorizedBillingUser( const supabase = createSupabaseClient(authToken); const {data, error} = await supabase.rpc("get_account_billing_status", { account_id: options.accountId, - }); + }) as {data: AUTHORIZED_BILLING_USER_INFO | null; error: any}; + + // means this user isn't a member of this account, block if (!data || error) { @@ -69,9 +71,9 @@ export async function requireAuthorizedBillingUser( return await options.onBillingDisabled(); } return new Response( - { + JSON.stringify({ billing_enabled: false, - }, + }), { headers: { "Content-Type": "application/json", @@ -80,8 +82,12 @@ export async function requireAuthorizedBillingUser( ); } + if (!options.onBillableAndAuthorized) { + return errorResponse("Config error: No onBillableAndAuthorized function passed in", 400); + } + // means this user is a member of this account, and has the right role, allow - return await options.onBillableAndAuthorized(data); + return await options.onBillableAndAuthorized?.(data); } catch (e) { // something went wrong, throw an error if (options.onError) { diff --git a/supabase/functions/deno-packages/billing-functions/src/require-authorized-user.ts b/supabase/functions/deno-packages/billing-functions/src/require-authorized-user.ts index f200e19..33aca05 100644 --- a/supabase/functions/deno-packages/billing-functions/src/require-authorized-user.ts +++ b/supabase/functions/deno-packages/billing-functions/src/require-authorized-user.ts @@ -1,8 +1,8 @@ -import { createSupabaseClient } from "../deps.ts"; -import { BASEJUMP_DATABASE_SCHEMA } from "../mod.ts"; +import createSupabaseClient from "../lib/create-supabase-client.ts"; +import { Database as BASEJUMP_DATABASE_SCHEMA } from "../types/basejump-database.ts"; type AUTHORIZED_USER_INFO = { - account_role: BASEJUMP_DATABASE_SCHEMA["public"]["Tables"]["account_user"]["Row"]["account_role"]; + account_role: BASEJUMP_DATABASE_SCHEMA["basejump"]["Tables"]["account_user"]["Row"]["account_role"]; is_primary_owner: boolean; is_personal_account: boolean; }; @@ -22,7 +22,7 @@ export async function requireAuthorizedUser( try { const authToken = req.headers.get("Authorization"); // we don't have what we need. instant block. - if (!authToken || !accountId) { + if (!authToken || !options.accountId) { if (options.onUnauthorized) { return await options.onUnauthorized(); } @@ -32,7 +32,7 @@ export async function requireAuthorizedUser( const supabase = createSupabaseClient(authToken); const { data, error } = await supabase.rpc("current_user_account_role", { account_id: options.accountId, - }); + }) as { data: AUTHORIZED_USER_INFO | null; error: any }; // means this user isn't a member of this account, block if (!data || error) { if (options.onUnauthorized) { diff --git a/supabase/functions/deno-packages/billing-functions/types/basejump-database.ts b/supabase/functions/deno-packages/billing-functions/types/basejump-database.ts index 0f1cca6..fbb4990 100644 --- a/supabase/functions/deno-packages/billing-functions/types/basejump-database.ts +++ b/supabase/functions/deno-packages/billing-functions/types/basejump-database.ts @@ -3,30 +3,327 @@ export type Json = | number | boolean | null - | { [key: string]: Json } + | { [key: string]: Json | undefined } | Json[] export interface Database { - graphql_public: { + basejump: { Tables: { - [_ in never]: never + account_user: { + Row: { + account_id: string + account_role: Database["basejump"]["Enums"]["account_role"] + user_id: string + } + Insert: { + account_id: string + account_role: Database["basejump"]["Enums"]["account_role"] + user_id: string + } + Update: { + account_id?: string + account_role?: Database["basejump"]["Enums"]["account_role"] + user_id?: string + } + Relationships: [ + { + foreignKeyName: "account_user_account_id_fkey" + columns: ["account_id"] + referencedRelation: "accounts" + referencedColumns: ["id"] + }, + { + foreignKeyName: "account_user_user_id_fkey" + columns: ["user_id"] + referencedRelation: "users" + referencedColumns: ["id"] + } + ] + } + accounts: { + Row: { + created_at: string | null + created_by: string | null + id: string + name: string | null + personal_account: boolean + primary_owner_user_id: string + private_metadata: Json | null + public_metadata: Json | null + slug: string | null + updated_at: string | null + updated_by: string | null + } + Insert: { + created_at?: string | null + created_by?: string | null + id?: string + name?: string | null + personal_account?: boolean + primary_owner_user_id?: string + private_metadata?: Json | null + public_metadata?: Json | null + slug?: string | null + updated_at?: string | null + updated_by?: string | null + } + Update: { + created_at?: string | null + created_by?: string | null + id?: string + name?: string | null + personal_account?: boolean + primary_owner_user_id?: string + private_metadata?: Json | null + public_metadata?: Json | null + slug?: string | null + updated_at?: string | null + updated_by?: string | null + } + Relationships: [ + { + foreignKeyName: "accounts_created_by_fkey" + columns: ["created_by"] + referencedRelation: "users" + referencedColumns: ["id"] + }, + { + foreignKeyName: "accounts_primary_owner_user_id_fkey" + columns: ["primary_owner_user_id"] + referencedRelation: "users" + referencedColumns: ["id"] + }, + { + foreignKeyName: "accounts_updated_by_fkey" + columns: ["updated_by"] + referencedRelation: "users" + referencedColumns: ["id"] + } + ] + } + billing_customers: { + Row: { + account_id: string + active: boolean | null + email: string | null + id: string + provider: string | null + } + Insert: { + account_id: string + active?: boolean | null + email?: string | null + id: string + provider?: string | null + } + Update: { + account_id?: string + active?: boolean | null + email?: string | null + id?: string + provider?: string | null + } + Relationships: [ + { + foreignKeyName: "billing_customers_account_id_fkey" + columns: ["account_id"] + referencedRelation: "accounts" + referencedColumns: ["id"] + } + ] + } + billing_subscriptions: { + Row: { + account_id: string + billing_customer_id: string + cancel_at: string | null + cancel_at_period_end: boolean | null + canceled_at: string | null + created: string + current_period_end: string + current_period_start: string + ended_at: string | null + id: string + metadata: Json | null + plan_name: string | null + price_id: string | null + provider: string | null + quantity: number | null + status: Database["basejump"]["Enums"]["subscription_status"] | null + trial_end: string | null + trial_start: string | null + } + Insert: { + account_id: string + billing_customer_id: string + cancel_at?: string | null + cancel_at_period_end?: boolean | null + canceled_at?: string | null + created?: string + current_period_end?: string + current_period_start?: string + ended_at?: string | null + id: string + metadata?: Json | null + plan_name?: string | null + price_id?: string | null + provider?: string | null + quantity?: number | null + status?: Database["basejump"]["Enums"]["subscription_status"] | null + trial_end?: string | null + trial_start?: string | null + } + Update: { + account_id?: string + billing_customer_id?: string + cancel_at?: string | null + cancel_at_period_end?: boolean | null + canceled_at?: string | null + created?: string + current_period_end?: string + current_period_start?: string + ended_at?: string | null + id?: string + metadata?: Json | null + plan_name?: string | null + price_id?: string | null + provider?: string | null + quantity?: number | null + status?: Database["basejump"]["Enums"]["subscription_status"] | null + trial_end?: string | null + trial_start?: string | null + } + Relationships: [ + { + foreignKeyName: "billing_subscriptions_account_id_fkey" + columns: ["account_id"] + referencedRelation: "accounts" + referencedColumns: ["id"] + }, + { + foreignKeyName: "billing_subscriptions_billing_customer_id_fkey" + columns: ["billing_customer_id"] + referencedRelation: "billing_customers" + referencedColumns: ["id"] + } + ] + } + config: { + Row: { + billing_provider: string | null + enable_personal_account_billing: boolean | null + enable_team_account_billing: boolean | null + enable_team_accounts: boolean | null + } + Insert: { + billing_provider?: string | null + enable_personal_account_billing?: boolean | null + enable_team_account_billing?: boolean | null + enable_team_accounts?: boolean | null + } + Update: { + billing_provider?: string | null + enable_personal_account_billing?: boolean | null + enable_team_account_billing?: boolean | null + enable_team_accounts?: boolean | null + } + Relationships: [] + } + invitations: { + Row: { + account_id: string + account_name: string | null + account_role: Database["basejump"]["Enums"]["account_role"] + created_at: string | null + id: string + invitation_type: Database["basejump"]["Enums"]["invitation_type"] + invited_by_user_id: string + token: string + updated_at: string | null + } + Insert: { + account_id: string + account_name?: string | null + account_role: Database["basejump"]["Enums"]["account_role"] + created_at?: string | null + id?: string + invitation_type: Database["basejump"]["Enums"]["invitation_type"] + invited_by_user_id: string + token?: string + updated_at?: string | null + } + Update: { + account_id?: string + account_name?: string | null + account_role?: Database["basejump"]["Enums"]["account_role"] + created_at?: string | null + id?: string + invitation_type?: Database["basejump"]["Enums"]["invitation_type"] + invited_by_user_id?: string + token?: string + updated_at?: string | null + } + Relationships: [ + { + foreignKeyName: "invitations_account_id_fkey" + columns: ["account_id"] + referencedRelation: "accounts" + referencedColumns: ["id"] + }, + { + foreignKeyName: "invitations_invited_by_user_id_fkey" + columns: ["invited_by_user_id"] + referencedRelation: "users" + referencedColumns: ["id"] + } + ] + } } Views: { [_ in never]: never } Functions: { - graphql: { + generate_token: { + Args: { + length: number + } + Returns: string + } + get_accounts_with_role: { Args: { - operationName?: string - query?: string - variables?: Json - extensions?: Json + passed_in_role?: Database["basejump"]["Enums"]["account_role"] } + Returns: string[] + } + get_config: { + Args: Record Returns: Json } + has_role_on_account: { + Args: { + account_id: string + account_role?: Database["basejump"]["Enums"]["account_role"] + } + Returns: boolean + } + is_set: { + Args: { + field_name: string + } + Returns: boolean + } } Enums: { - [_ in never]: never + account_role: "owner" | "member" + invitation_type: "one_time" | "24_hour" + subscription_status: + | "trialing" + | "active" + | "canceled" + | "incomplete" + | "incomplete_expired" + | "past_due" + | "unpaid" } CompositeTypes: { [_ in never]: never @@ -44,7 +341,7 @@ export interface Database { Args: { lookup_invitation_token: string } - Returns: string + Returns: Json } create_account: { Args: { @@ -53,12 +350,26 @@ export interface Database { } Returns: Json } + create_invitation: { + Args: { + account_id: string + account_role: Database["basejump"]["Enums"]["account_role"] + invitation_type: Database["basejump"]["Enums"]["invitation_type"] + } + Returns: Json + } current_user_account_role: { Args: { - lookup_account_id: string + account_id: string } Returns: Json } + delete_invitation: { + Args: { + invitation_id: string + } + Returns: undefined + } get_account: { Args: { account_id: string @@ -67,7 +378,7 @@ export interface Database { } get_account_billing_status: { Args: { - lookup_account_id: string + account_id: string } Returns: Json } @@ -77,17 +388,33 @@ export interface Database { } Returns: Json } - get_accounts: { - Args: Record + get_account_id: { + Args: { + slug: string + } + Returns: string + } + get_account_invitations: { + Args: { + account_id: string + results_limit?: number + results_offset?: number + } Returns: Json } - get_profile: { + get_account_members: { Args: { - user_id?: string + account_id: string + results_limit?: number + results_offset?: number } Returns: Json } - get_service_role_config: { + get_accounts: { + Args: Record + Returns: Json + } + get_personal_account: { Args: Record Returns: Json } @@ -97,9 +424,16 @@ export interface Database { } Returns: Json } + remove_account_member: { + Args: { + account_id: string + user_id: string + } + Returns: undefined + } service_role_upsert_customer_subscription: { Args: { - account_id?: string + account_id: string customer?: Json subscription?: Json } @@ -119,205 +453,11 @@ export interface Database { Args: { account_id: string user_id: string - new_account_role: "owner" | "member" - make_primary_owner: boolean + new_account_role: Database["basejump"]["Enums"]["account_role"] + make_primary_owner?: boolean } Returns: undefined } - update_profile: { - Args: { - user_id?: string - name?: string - public_metadata?: Json - replace_metadata?: boolean - } - Returns: Json - } - } - Enums: { - [_ in never]: never - } - CompositeTypes: { - [_ in never]: never - } - } - storage: { - Tables: { - buckets: { - Row: { - allowed_mime_types: string[] | null - avif_autodetection: boolean | null - created_at: string | null - file_size_limit: number | null - id: string - name: string - owner: string | null - public: boolean | null - updated_at: string | null - } - Insert: { - allowed_mime_types?: string[] | null - avif_autodetection?: boolean | null - created_at?: string | null - file_size_limit?: number | null - id: string - name: string - owner?: string | null - public?: boolean | null - updated_at?: string | null - } - Update: { - allowed_mime_types?: string[] | null - avif_autodetection?: boolean | null - created_at?: string | null - file_size_limit?: number | null - id?: string - name?: string - owner?: string | null - public?: boolean | null - updated_at?: string | null - } - Relationships: [ - { - foreignKeyName: "buckets_owner_fkey" - columns: ["owner"] - referencedRelation: "users" - referencedColumns: ["id"] - } - ] - } - migrations: { - Row: { - executed_at: string | null - hash: string - id: number - name: string - } - Insert: { - executed_at?: string | null - hash: string - id: number - name: string - } - Update: { - executed_at?: string | null - hash?: string - id?: number - name?: string - } - Relationships: [] - } - objects: { - Row: { - bucket_id: string | null - created_at: string | null - id: string - last_accessed_at: string | null - metadata: Json | null - name: string | null - owner: string | null - path_tokens: string[] | null - updated_at: string | null - version: string | null - } - Insert: { - bucket_id?: string | null - created_at?: string | null - id?: string - last_accessed_at?: string | null - metadata?: Json | null - name?: string | null - owner?: string | null - path_tokens?: string[] | null - updated_at?: string | null - version?: string | null - } - Update: { - bucket_id?: string | null - created_at?: string | null - id?: string - last_accessed_at?: string | null - metadata?: Json | null - name?: string | null - owner?: string | null - path_tokens?: string[] | null - updated_at?: string | null - version?: string | null - } - Relationships: [ - { - foreignKeyName: "objects_bucketId_fkey" - columns: ["bucket_id"] - referencedRelation: "buckets" - referencedColumns: ["id"] - }, - { - foreignKeyName: "objects_owner_fkey" - columns: ["owner"] - referencedRelation: "users" - referencedColumns: ["id"] - } - ] - } - } - Views: { - [_ in never]: never - } - Functions: { - can_insert_object: { - Args: { - bucketid: string - name: string - owner: string - metadata: Json - } - Returns: undefined - } - extension: { - Args: { - name: string - } - Returns: string - } - filename: { - Args: { - name: string - } - Returns: string - } - foldername: { - Args: { - name: string - } - Returns: unknown - } - get_size_by_bucket: { - Args: Record - Returns: { - size: number - bucket_id: string - }[] - } - search: { - Args: { - prefix: string - bucketname: string - limits?: number - levels?: number - offsets?: number - search?: string - sortcolumn?: string - sortorder?: string - } - Returns: { - name: string - id: string - updated_at: string - created_at: string - last_accessed_at: string - metadata: Json - }[] - } } Enums: { [_ in never]: never