mirror of
https://github.com/jcreek/SvelteKitSaasBoilerplate.git
synced 2026-07-15 20:13:50 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c47c933ce1 | |||
| 4d80534244 | |||
| 18772364f7 | |||
| 0539afb16e | |||
| ef3abfe396 | |||
| 7bf05b35a6 |
@@ -1,7 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { general } from '$lib/stores/generalStore.js';
|
||||
|
||||
import stripe from 'stripe';
|
||||
import { PUBLIC_STRIPE_SECRET_KEY } from '$env/static/public';
|
||||
|
||||
const stripeClient = new stripe(PUBLIC_STRIPE_SECRET_KEY);
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function emitSignedInEvent() {
|
||||
@@ -13,16 +17,62 @@
|
||||
|
||||
// Access the supabase client from the layout data
|
||||
export let supabase: any;
|
||||
export let session: any;
|
||||
|
||||
async function signInWithEmail() {
|
||||
// TODO use the data and error from the response
|
||||
const { data, error } = await supabase.auth
|
||||
.signInWithPassword({
|
||||
try {
|
||||
// Sign in with email and password
|
||||
const { data, error } = await supabase.auth.signInWithPassword({
|
||||
email: email,
|
||||
password: password
|
||||
password: password,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
console.error('Sign in error:', error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Emit signed-in event
|
||||
emitSignedInEvent();
|
||||
|
||||
// Check if the session data is available
|
||||
if (data && data.session && data.session.user) {
|
||||
const userId = data.session.user.id;
|
||||
// Create Stripe customer
|
||||
await createStripeCustomer(userId);
|
||||
} else {
|
||||
console.error('User session data is missing');
|
||||
}
|
||||
|
||||
// Log data for debugging purposes
|
||||
console.log(data);
|
||||
|
||||
} catch (err) {
|
||||
console.error('Unexpected error:', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function createStripeCustomer(userId: string) {
|
||||
console.log('createStripeCustomer');
|
||||
await stripeClient.customers
|
||||
.create({
|
||||
email
|
||||
})
|
||||
.then(() => {
|
||||
emitSignedInEvent();
|
||||
.then(async (customer) => {
|
||||
// Create a new customer in the database customers table with id data.user.id and stripe_customer_id customer.id
|
||||
const { dataFromUpsert, error } = await supabase.from('customers').upsert([
|
||||
{
|
||||
id: userId,
|
||||
stripe_customer_id: customer.id
|
||||
}
|
||||
]);
|
||||
|
||||
console.log(dataFromUpsert);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +1,14 @@
|
||||
<script lang="ts">
|
||||
import stripe from 'stripe';
|
||||
import { PUBLIC_STRIPE_SECRET_KEY } from '$env/static/public';
|
||||
|
||||
let email = '';
|
||||
let password = '';
|
||||
|
||||
// Access the supabase client from the layout data
|
||||
export let supabase: any;
|
||||
|
||||
const stripeClient = new stripe(PUBLIC_STRIPE_SECRET_KEY);
|
||||
|
||||
async function signUpNewUser() {
|
||||
try {
|
||||
const { data, error } = await supabase.auth.signUp({
|
||||
email: email,
|
||||
password: password,
|
||||
options: {
|
||||
// Redirect URL after successful sign-up
|
||||
redirectTo: '/account'
|
||||
}
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const customer = await stripeClient.customers.create({
|
||||
email
|
||||
});
|
||||
|
||||
const response = await supabase
|
||||
.from('user')
|
||||
.update({
|
||||
customer_id: customer.id
|
||||
})
|
||||
.match({
|
||||
id: data.user.id
|
||||
});
|
||||
|
||||
console.log(response);
|
||||
await supabaseSignUp();
|
||||
|
||||
// Handle success (optional)
|
||||
} catch (error: any) {
|
||||
@@ -46,6 +16,25 @@
|
||||
// Handle error
|
||||
}
|
||||
}
|
||||
|
||||
async function supabaseSignUp() {
|
||||
console.log('supabaseSignUp');
|
||||
const { data, error } = await supabase.auth.signUp({
|
||||
email: email,
|
||||
password: password,
|
||||
options: {
|
||||
// Redirect URL after successful sign-up
|
||||
redirectTo: '/account'
|
||||
}
|
||||
});
|
||||
console.log(data);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
</script>
|
||||
|
||||
<form class="card-body">
|
||||
|
||||
@@ -155,8 +155,15 @@ const createOrRetrieveCustomer = async ({ email, uuid }: { email: string; uuid:
|
||||
console.warn(`Supabase customer record was missing. A new record was created.`);
|
||||
|
||||
// If Supabase has no record, create a new record and return Stripe customer ID
|
||||
const upsertedStripeCustomer = await upsertCustomerToSupabase(uuid, stripeIdToInsert);
|
||||
if (!upsertedStripeCustomer) throw new Error('Supabase customer record creation failed.');
|
||||
try {
|
||||
const upsertedStripeCustomer = await upsertCustomerToSupabase(uuid, stripeIdToInsert);
|
||||
|
||||
if (!upsertedStripeCustomer) throw new Error('Supabase customer record creation failed.');
|
||||
return upsertedStripeCustomer;
|
||||
} catch (error) {
|
||||
console.error(`Supabase customer record creation failed: ${error}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return upsertedStripeCustomer;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
<div
|
||||
class="mt-3 z-[1] p-2 shadow menu menu-sm dropdown-content bg-base-100 text-base-content rounded-box min-w-[13rem] w-auto"
|
||||
>
|
||||
<SignIn {supabase} />
|
||||
<SignIn {supabase} {session} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import stripe from 'stripe';
|
||||
import { PUBLIC_STRIPE_SECRET_KEY } from '$env/static/public';
|
||||
import { PUBLIC_STRIPE_ENDPOINT_SECRET } from '$env/static/public';
|
||||
import {
|
||||
createOrRetrieveCustomer,
|
||||
deletePriceRecord,
|
||||
deleteProductRecord,
|
||||
manageSubscriptionStatusChange,
|
||||
@@ -54,6 +55,14 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||
case 'product.deleted':
|
||||
await deleteProductRecord(event.data.object as stripe.Product);
|
||||
break;
|
||||
// case 'customer.created':
|
||||
// case 'customer.updated':
|
||||
// // TODO - this should be passing the supabase customer uuid not the stripe customer id
|
||||
// await createOrRetrieveCustomer({
|
||||
// email: (event.data.object as stripe.Customer).email!,
|
||||
// uuid: event.data.object.id
|
||||
// });
|
||||
// break;
|
||||
case 'customer.subscription.created':
|
||||
case 'customer.subscription.updated':
|
||||
case 'customer.subscription.deleted': {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
-- TESTS FOR RLS policy
|
||||
create policy "Enable update for users based on id"
|
||||
on "public"."customers"
|
||||
as permissive
|
||||
for update
|
||||
to public
|
||||
using ((( SELECT auth.uid() AS uid) = id))
|
||||
with check ((( SELECT auth.uid() AS uid) = id));
|
||||
|
||||
create policy "Enable insert for users based on id"
|
||||
on "public"."customers"
|
||||
as permissive
|
||||
for insert
|
||||
to public
|
||||
with check ((( SELECT auth.uid() AS uid) = id));
|
||||
|
||||
create policy "DEMO Enable insert for users based on id"
|
||||
on "public"."customers"
|
||||
as permissive
|
||||
for insert
|
||||
to public
|
||||
with check (true);
|
||||
|
||||
create policy "DEMO Enable update for users based on id"
|
||||
on "public"."customers"
|
||||
as permissive
|
||||
for update
|
||||
to public
|
||||
using (true)
|
||||
with check (true);
|
||||
|
||||
|
||||
|
||||
GRANT USAGE ON SCHEMA public TO anon, authenticated, service_role;
|
||||
GRANT ALL ON ALL TABLES IN SCHEMA public TO anon, authenticated, service_role;
|
||||
GRANT ALL ON ALL ROUTINES IN SCHEMA public TO anon, authenticated, service_role;
|
||||
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO anon, authenticated, service_role;
|
||||
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON TABLES TO anon, authenticated, service_role;
|
||||
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON ROUTINES TO anon, authenticated, service_role;
|
||||
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT ALL ON SEQUENCES TO anon, authenticated, service_role;
|
||||
Reference in New Issue
Block a user