Refactor schemas, enhance data validation

Implemented improvements in the data validation methods used in Stripe and Team Account features by refining the schemas. Adapted string types to UUID for accountId attributes in various services and ensured that Stripe keys follow appropriate prefixes. Autocomplete was turned off for destructive actions for enhanced security.
This commit is contained in:
giancarlo
2024-03-29 18:21:12 +08:00
parent 59c08c59d7
commit 65e970424f
13 changed files with 44 additions and 25 deletions
@@ -25,7 +25,7 @@ import {
import { If } from '@kit/ui/if';
import { Trans } from '@kit/ui/trans';
import { UpdateMemberRoleSchema } from '../../schema/update-member-role-schema';
import { UpdateMemberRoleSchema } from '../../schema/update-member-role.schema';
import { updateInvitationAction } from '../../server/actions/team-invitations-server-actions';
import { MembershipRoleSelector } from '../members/membership-role-selector';
import { RolesDataProvider } from '../members/roles-data-provider';
@@ -25,7 +25,7 @@ import {
import { If } from '@kit/ui/if';
import { Trans } from '@kit/ui/trans';
import { RoleSchema } from '../../schema/update-member-role-schema';
import { RoleSchema } from '../../schema/update-member-role.schema';
import { updateMemberRoleAction } from '../../server/actions/team-members-server-actions';
import { MembershipRoleSelector } from './membership-role-selector';
import { RolesDataProvider } from './roles-data-provider';
@@ -4,7 +4,6 @@ import { useTransition } from 'react';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { Button } from '@kit/ui/button';
import {
@@ -17,12 +16,9 @@ import {
import { Input } from '@kit/ui/input';
import { Trans } from '@kit/ui/trans';
import { TeamNameFormSchema } from '../../schema/update-team-name.schema';
import { updateTeamAccountName } from '../../server/actions/team-details-server-actions';
const Schema = z.object({
name: z.string().min(1).max(255),
});
export const UpdateTeamAccountNameForm = (props: {
account: {
name: string;
@@ -34,7 +30,7 @@ export const UpdateTeamAccountNameForm = (props: {
const [pending, startTransition] = useTransition();
const form = useForm({
resolver: zodResolver(Schema),
resolver: zodResolver(TeamNameFormSchema),
defaultValues: {
name: props.account.name,
},
@@ -0,0 +1,5 @@
import { z } from 'zod';
export const RenewInvitationSchema = z.object({
invitationId: z.number().positive(),
});
@@ -0,0 +1,12 @@
import { z } from 'zod';
export const TeamNameFormSchema = z.object({
name: z.string().min(1).max(255),
});
export const UpdateTeamNameSchema = TeamNameFormSchema.merge(
z.object({
slug: z.string().min(1).max(255),
path: z.string().min(1).max(255),
}),
);
@@ -12,8 +12,8 @@ import { LeaveTeamAccountService } from '../services/leave-team-account.service'
export async function leaveTeamAccountAction(formData: FormData) {
const body = Object.fromEntries(formData.entries());
const params = LeaveTeamAccountSchema.parse(body);
const client = getSupabaseServerActionClient();
const client = getSupabaseServerActionClient();
const auth = await requireUser(client);
if (auth.error) {
@@ -2,23 +2,26 @@
import { redirect } from 'next/navigation';
import { z } from 'zod';
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
export async function updateTeamAccountName(params: {
name: string;
slug: string;
path: string;
}) {
import { UpdateTeamNameSchema } from '../../schema/update-team-name.schema';
export async function updateTeamAccountName(
params: z.infer<typeof UpdateTeamNameSchema>,
) {
const client = getSupabaseServerComponentClient();
const { name, slug, path } = UpdateTeamNameSchema.parse(params);
const { error, data } = await client
.from('accounts')
.update({
name: params.name,
slug: params.slug,
name,
slug,
})
.match({
slug: params.slug,
slug,
})
.select('slug')
.single();
@@ -30,9 +33,9 @@ export async function updateTeamAccountName(params: {
const newSlug = data.slug;
if (newSlug) {
const path = params.path.replace('[account]', newSlug);
const nextPath = path.replace('[account]', newSlug);
redirect(path);
redirect(nextPath);
}
return { success: true };
@@ -14,7 +14,8 @@ import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-clie
import { AcceptInvitationSchema } from '../../schema/accept-invitation.schema';
import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema';
import { InviteMembersSchema } from '../../schema/invite-members.schema';
import { UpdateInvitationSchema } from '../../schema/update-invitation-schema';
import { RenewInvitationSchema } from '../../schema/renew-invitation.schema';
import { UpdateInvitationSchema } from '../../schema/update-invitation.schema';
import { AccountInvitationsService } from '../services/account-invitations.service';
/**
@@ -107,9 +108,11 @@ export async function acceptInvitationAction(data: FormData) {
return redirect(nextPath);
}
export async function renewInvitationAction(params: { invitationId: number }) {
export async function renewInvitationAction(
params: z.infer<typeof RenewInvitationSchema>,
) {
const client = getSupabaseServerActionClient();
const { invitationId } = params;
const { invitationId } = RenewInvitationSchema.parse(params);
await assertSession(client);
@@ -11,7 +11,7 @@ import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-clie
import { RemoveMemberSchema } from '../../schema/remove-member.schema';
import { TransferOwnershipConfirmationSchema } from '../../schema/transfer-ownership-confirmation.schema';
import { UpdateMemberRoleSchema } from '../../schema/update-member-role-schema';
import { UpdateMemberRoleSchema } from '../../schema/update-member-role.schema';
import { AccountMembersService } from '../services/account-members.service';
export async function removeMemberFromAccountAction(
@@ -11,7 +11,7 @@ import { requireUser } from '@kit/supabase/require-user';
import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema';
import { InviteMembersSchema } from '../../schema/invite-members.schema';
import { UpdateInvitationSchema } from '../../schema/update-invitation-schema';
import { UpdateInvitationSchema } from '../../schema/update-invitation.schema';
const invitePath = process.env.INVITATION_PAGE_PATH;
const siteURL = process.env.NEXT_PUBLIC_SITE_URL;
@@ -8,7 +8,7 @@ import { Database } from '@kit/supabase/database';
import { RemoveMemberSchema } from '../../schema/remove-member.schema';
import { TransferOwnershipConfirmationSchema } from '../../schema/transfer-ownership-confirmation.schema';
import { UpdateMemberRoleSchema } from '../../schema/update-member-role-schema';
import { UpdateMemberRoleSchema } from '../../schema/update-member-role.schema';
export class AccountMembersService {
private readonly namespace = 'account-members';