update pay function

This commit is contained in:
2025-11-22 11:41:56 +08:00
parent a4b634abff
commit d8e4c737c5
397 changed files with 19572 additions and 9326 deletions

View File

@@ -0,0 +1,44 @@
'use client';
import { createClient } from '@/utils/supabase/client';
import { type Provider } from '@supabase/supabase-js';
import { getURL } from '@/utils/helpers';
import { redirectToPath } from './server';
import { AppRouterInstance } from 'next/dist/shared/lib/app-router-context.shared-runtime';
export async function handleRequest(
e: React.FormEvent<HTMLFormElement>,
requestFunc: (formData: FormData) => Promise<string>,
router: AppRouterInstance | null = null
): Promise<boolean | void> {
// Prevent default form submission refresh
e.preventDefault();
const formData = new FormData(e.currentTarget);
const redirectUrl: string = await requestFunc(formData);
if (router) {
// If client-side router is provided, use it to redirect
return router.push(redirectUrl);
} else {
// Otherwise, redirect server-side
return await redirectToPath(redirectUrl);
}
}
export async function signInWithOAuth(e: React.FormEvent<HTMLFormElement>) {
// Prevent default form submission refresh
e.preventDefault();
const formData = new FormData(e.currentTarget);
const provider = String(formData.get('provider')).trim() as Provider;
// Create client-side supabase client and call signInWithOAuth
const supabase = createClient();
const redirectURL = getURL('/auth/callback');
await supabase.auth.signInWithOAuth({
provider: provider,
options: {
redirectTo: redirectURL
}
});
}

View File

@@ -0,0 +1,340 @@
'use server';
import { createClient } from '@/utils/supabase/server';
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';
import { getURL, getErrorRedirect, getStatusRedirect } from '@/utils/helpers';
import { getAuthTypes } from '@/utils/auth-helpers/settings';
function isValidEmail(email: string) {
var regex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
return regex.test(email);
}
export async function redirectToPath(path: string) {
return redirect(path);
}
export async function SignOut(formData: FormData) {
const pathName = String(formData.get('pathName')).trim();
const supabase = createClient();
const { error } = await supabase.auth.signOut();
if (error) {
return getErrorRedirect(
pathName,
'Hmm... Something went wrong.',
'You could not be signed out.'
);
}
return '/dashboard/signin';
}
export async function signInWithEmail(formData: FormData) {
const cookieStore = cookies();
const callbackURL = getURL('/auth/callback');
const email = String(formData.get('email')).trim();
let redirectPath: string;
if (!isValidEmail(email)) {
redirectPath = getErrorRedirect(
'/dashboard/signin/email_signin',
'Invalid email address.',
'Please try again.'
);
}
const supabase = createClient();
let options = {
emailRedirectTo: callbackURL,
shouldCreateUser: true
};
// If allowPassword is false, do not create a new user
const { allowPassword } = getAuthTypes();
if (allowPassword) options.shouldCreateUser = false;
const { data, error } = await supabase.auth.signInWithOtp({
email,
options: options
});
if (error) {
redirectPath = getErrorRedirect(
'/dashboard/signin/email_signin',
'You could not be signed in.',
error.message
);
} else if (data) {
cookieStore.set('preferredSignInView', 'email_signin', { path: '/' });
redirectPath = getStatusRedirect(
'/dashboard/signin/email_signin',
'Success!',
'Please check your email for a magic link. You may now close this tab.',
true
);
} else {
redirectPath = getErrorRedirect(
'/dashboard/signin/email_signin',
'Hmm... Something went wrong.',
'You could not be signed in.'
);
}
return redirectPath;
}
export async function requestPasswordUpdate(formData: FormData) {
const callbackURL = getURL('/auth/reset_password');
// Get form data
const email = String(formData.get('email')).trim();
let redirectPath: string;
if (!isValidEmail(email)) {
redirectPath = getErrorRedirect(
'/dashboard/signin/forgot_password',
'Invalid email address.',
'Please try again.'
);
}
const supabase = createClient();
const { data, error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: callbackURL
});
if (error) {
redirectPath = getErrorRedirect(
'/dashboard/signin/forgot_password',
error.message,
'Please try again.'
);
} else if (data) {
redirectPath = getStatusRedirect(
'/dashboard/signin/forgot_password',
'Success!',
'Please check your email for a password reset link. You may now close this tab.',
true
);
} else {
redirectPath = getErrorRedirect(
'/dashboard/signin/forgot_password',
'Hmm... Something went wrong.',
'Password reset email could not be sent.'
);
}
return redirectPath;
}
export async function signInWithPassword(formData: FormData) {
const cookieStore = cookies();
const email = String(formData.get('email')).trim();
const password = String(formData.get('password')).trim();
let redirectPath: string;
const supabase = createClient();
const { error, data } = await supabase.auth.signInWithPassword({
email,
password
});
if (error) {
redirectPath = getErrorRedirect(
'/dashboard/signin/password_signin',
'Sign in failed.',
error.message
);
} else if (data.user) {
cookieStore.set('preferredSignInView', 'password_signin', { path: '/' });
redirectPath = getStatusRedirect('/', 'Success!', 'You are now signed in.');
} else {
redirectPath = getErrorRedirect(
'/dashboard/signin/password_signin',
'Hmm... Something went wrong.',
'You could not be signed in.'
);
}
return redirectPath;
}
export async function signUp(formData: FormData) {
const callbackURL = getURL('/auth/callback');
const email = String(formData.get('email')).trim();
const password = String(formData.get('password')).trim();
let redirectPath: string;
if (!isValidEmail(email)) {
redirectPath = getErrorRedirect(
'/dashboard/signin/signup',
'Invalid email address.',
'Please try again.'
);
}
const supabase = createClient();
const { error, data } = await supabase.auth.signUp({
email,
password,
options: {
emailRedirectTo: callbackURL
}
});
if (error) {
redirectPath = getErrorRedirect(
'/dashboard/signin/signup',
'Sign up failed.',
error.message
);
} else if (data.session) {
redirectPath = getStatusRedirect('/', 'Success!', 'You are now signed in.');
} else if (
data.user &&
data.user.identities &&
data.user.identities.length == 0
) {
redirectPath = getErrorRedirect(
'/dashboard/signin/signup',
'Sign up failed.',
'There is already an account associated with this email address. Try resetting your password.'
);
} else if (data.user) {
redirectPath = getStatusRedirect(
'/',
'Success!',
'Please check your email for a confirmation link. You may now close this tab.'
);
} else {
redirectPath = getErrorRedirect(
'/dashboard/signin/signup',
'Hmm... Something went wrong.',
'You could not be signed up.'
);
}
return redirectPath;
}
export async function updatePassword(formData: FormData) {
const password = String(formData.get('password')).trim();
const passwordConfirm = String(formData.get('passwordConfirm')).trim();
let redirectPath: string;
// Check that the password and confirmation match
if (password !== passwordConfirm) {
redirectPath = getErrorRedirect(
'/dashboard/signin/update_password',
'Your password could not be updated.',
'Passwords do not match.'
);
}
const supabase = createClient();
const { error, data } = await supabase.auth.updateUser({
password
});
if (error) {
redirectPath = getErrorRedirect(
'/dashboard/signin/update_password',
'Your password could not be updated.',
error.message
);
} else if (data.user) {
redirectPath = getStatusRedirect(
'/',
'Success!',
'Your password has been updated.'
);
} else {
redirectPath = getErrorRedirect(
'/dashboard/signin/update_password',
'Hmm... Something went wrong.',
'Your password could not be updated.'
);
}
return redirectPath;
}
export async function updateEmail(formData: FormData) {
// Get form data
const newEmail = String(formData.get('newEmail')).trim();
// Check that the email is valid
if (!isValidEmail(newEmail)) {
return getErrorRedirect(
'/dashboard/settings',
'Your email could not be updated.',
'Invalid email address.'
);
}
const supabase = createClient();
const callbackUrl = getURL(
getStatusRedirect(
'/dashboard/settings',
'Success!',
`Your email has been updated.`
)
);
const { error } = await supabase.auth.updateUser(
{ email: newEmail },
{
emailRedirectTo: callbackUrl
}
);
if (error) {
return getErrorRedirect(
'/dashboard/settings',
'Your email could not be updated.',
error.message
);
} else {
return getStatusRedirect(
'/dashboard/settings',
'Confirmation emails sent.',
`You will need to confirm the update by clicking the links sent to both the old and new email addresses.`
);
}
}
export async function updateName(formData: FormData) {
// Get form data
const fullName = String(formData.get('fullName')).trim();
const supabase = createClient();
const { error, data } = await supabase.auth.updateUser({
data: { full_name: fullName }
});
if (error) {
return getErrorRedirect(
'/dashboard/settings',
'Your name could not be updated.',
error.message
);
} else if (data.user) {
return getStatusRedirect(
'/dashboard/settings',
'Success!',
'Your name has been updated.'
);
} else {
return getErrorRedirect(
'/dashboard/settings',
'Hmm... Something went wrong.',
'Your name could not be updated.'
);
}
}

View File

@@ -0,0 +1,49 @@
// Boolean toggles to determine which auth types are allowed
const allowOauth = true;
const allowEmail = true;
const allowPassword = true;
// Boolean toggle to determine whether auth interface should route through server or client
// (Currently set to false because screen sometimes flickers with server redirects)
const allowServerRedirect = false;
// Check that at least one of allowPassword and allowEmail is true
if (!allowPassword && !allowEmail)
throw new Error('At least one of allowPassword and allowEmail must be true');
export const getAuthTypes = () => {
return { allowOauth, allowEmail, allowPassword };
};
export const getViewTypes = () => {
// Define the valid view types
let viewTypes: string[] = [];
if (allowEmail) {
viewTypes = [...viewTypes, 'email_signin'];
}
if (allowPassword) {
viewTypes = [
...viewTypes,
'password_signin',
'forgot_password',
'update_password',
'signup'
];
}
return viewTypes;
};
export const getDefaultSignInView = (preferredSignInView: string | null) => {
// Define the default sign in view
let defaultView = allowPassword ? 'password_signin' : 'email_signin';
if (preferredSignInView && getViewTypes().includes(preferredSignInView)) {
defaultView = preferredSignInView;
}
return defaultView;
};
export const getRedirectMethod = () => {
return allowServerRedirect ? 'server' : 'client';
};