From 55869ea16fd3748c1386aebe250c3ea1bbd6a965 Mon Sep 17 00:00:00 2001 From: k4rli Date: Thu, 17 Jul 2025 10:19:27 +0300 Subject: [PATCH] feat(MED-100): create medusa store account for user --- .../server/actions/update-account-actions.ts | 8 ++++ .../medusa-storefront/src/lib/data/cookies.ts | 27 +++++++++++ .../src/lib/data/customer.ts | 48 +++++++++++++++++++ packages/shared/src/utils.ts | 2 +- .../hooks/use-sign-in-with-email-password.ts | 14 +++++- .../hooks/use-sign-up-with-email-password.ts | 13 +++++ 6 files changed, 110 insertions(+), 2 deletions(-) diff --git a/packages/features/auth/src/server/actions/update-account-actions.ts b/packages/features/auth/src/server/actions/update-account-actions.ts index 0efdab8..abb847f 100644 --- a/packages/features/auth/src/server/actions/update-account-actions.ts +++ b/packages/features/auth/src/server/actions/update-account-actions.ts @@ -6,6 +6,7 @@ import { enhanceAction } from '@kit/next/actions'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; import pathsConfig from '~/config/paths.config'; +import { updateCustomer } from '@lib/data/customer'; import { UpdateAccountSchema } from '../../schemas/update-account.schema'; import { createAuthApi } from '../api'; @@ -36,6 +37,13 @@ export const onUpdateAccount = enhanceAction( } console.warn('On update account error: ', err); } + + await updateCustomer({ + first_name: params.firstName, + last_name: params.lastName, + phone: params.phone, + }); + const hasUnseenMembershipConfirmation = await api.hasUnseenMembershipConfirmation(); diff --git a/packages/features/medusa-storefront/src/lib/data/cookies.ts b/packages/features/medusa-storefront/src/lib/data/cookies.ts index 1e21f78..7694904 100644 --- a/packages/features/medusa-storefront/src/lib/data/cookies.ts +++ b/packages/features/medusa-storefront/src/lib/data/cookies.ts @@ -18,6 +18,23 @@ export const getAuthHeaders = async (): Promise< } } +export const getMedusaCustomerId = async (): Promise< + { customerId: string | null } +> => { + try { + const cookies = await nextCookies() + const customerId = cookies.get("_medusa_customer_id")?.value + + if (!customerId) { + return { customerId: null } + } + + return { customerId } + } catch { + return { customerId: null} + } +} + export const getCacheTag = async (tag: string): Promise => { try { const cookies = await nextCookies() @@ -59,6 +76,16 @@ export const setAuthToken = async (token: string) => { }) } +export const setMedusaCustomerId = async (customerId: string) => { + const cookies = await nextCookies() + cookies.set("_medusa_customer_id", customerId, { + maxAge: 60 * 60 * 24 * 7, + httpOnly: true, + sameSite: "strict", + secure: process.env.NODE_ENV === "production", + }) +} + export const removeAuthToken = async () => { const cookies = await nextCookies() cookies.set("_medusa_jwt", "", { diff --git a/packages/features/medusa-storefront/src/lib/data/customer.ts b/packages/features/medusa-storefront/src/lib/data/customer.ts index 309d774..9b22479 100644 --- a/packages/features/medusa-storefront/src/lib/data/customer.ts +++ b/packages/features/medusa-storefront/src/lib/data/customer.ts @@ -259,3 +259,51 @@ export const updateCustomerAddress = async ( return { success: false, error: err.toString() } }) } + +export async function medusaLoginOrRegister(credentials: { + email: string + password?: string +}) { + const { email, password } = credentials; + + try { + const token = await sdk.auth.login("customer", "emailpass", { + email, + password, + }); + await setAuthToken(token as string); + await transferCart(); + + const customerCacheTag = await getCacheTag("customers"); + revalidateTag(customerCacheTag); + } catch (error) { + console.error("Failed to login customer, attempting to register", error); + try { + const registerToken = await sdk.auth.register("customer", "emailpass", { + email: email, + password: password, + }) + + await setAuthToken(registerToken as string); + + const headers = { + ...(await getAuthHeaders()), + }; + + await sdk.store.customer.create({ email }, {}, headers); + + const loginToken = await sdk.auth.login("customer", "emailpass", { + email, + password, + }); + + await setAuthToken(loginToken as string); + + const customerCacheTag = await getCacheTag("customers"); + revalidateTag(customerCacheTag); + await transferCart(); + } catch (registerError) { + throw medusaError(registerError); + } + } +} diff --git a/packages/shared/src/utils.ts b/packages/shared/src/utils.ts index 4ec9ae7..1b8d1af 100644 --- a/packages/shared/src/utils.ts +++ b/packages/shared/src/utils.ts @@ -14,7 +14,7 @@ export function formatCurrency(params: { locale: string; value: string | number; }) { - const [lang, region] = params.locale.split('-'); + const [lang, region] = (params.locale ?? 'et-ET').split('-'); return new Intl.NumberFormat(region ?? lang, { style: 'currency', diff --git a/packages/supabase/src/hooks/use-sign-in-with-email-password.ts b/packages/supabase/src/hooks/use-sign-in-with-email-password.ts index d6ba8e7..2e11a95 100644 --- a/packages/supabase/src/hooks/use-sign-in-with-email-password.ts +++ b/packages/supabase/src/hooks/use-sign-in-with-email-password.ts @@ -2,6 +2,7 @@ import type { SignInWithPasswordCredentials } from '@supabase/supabase-js'; import { useMutation } from '@tanstack/react-query'; +import { medusaLoginOrRegister } from '../../../features/medusa-storefront/src/lib/data/customer'; import { useSupabase } from './use-supabase'; export function useSignInWithEmailPassword() { @@ -18,11 +19,22 @@ export function useSignInWithEmailPassword() { const user = response.data?.user; const identities = user?.identities ?? []; - // if the user has no identities, it means that the email is taken if (identities.length === 0) { throw new Error('User already registered'); } + if ('email' in credentials) { + try { + await medusaLoginOrRegister({ + email: credentials.email, + password: credentials.password, + }); + } catch (error) { + await client.auth.signOut(); + throw error; + } + } + return response.data; }; diff --git a/packages/supabase/src/hooks/use-sign-up-with-email-password.ts b/packages/supabase/src/hooks/use-sign-up-with-email-password.ts index a387d0e..01a247f 100644 --- a/packages/supabase/src/hooks/use-sign-up-with-email-password.ts +++ b/packages/supabase/src/hooks/use-sign-up-with-email-password.ts @@ -1,6 +1,7 @@ import { useMutation } from '@tanstack/react-query'; import { useSupabase } from './use-supabase'; +import { medusaLoginOrRegister } from '../../../features/medusa-storefront/src/lib/data/customer'; interface Credentials { personalCode: string; @@ -41,6 +42,18 @@ export function useSignUpWithEmailAndPassword() { throw new Error('User already registered'); } + if ('email' in credentials) { + try { + await medusaLoginOrRegister({ + email: credentials.email, + password: credentials.password, + }); + } catch (error) { + await client.auth.signOut(); + throw error; + } + } + return response.data; };