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:
@@ -25,7 +25,7 @@ import {
|
|||||||
import { If } from '@kit/ui/if';
|
import { If } from '@kit/ui/if';
|
||||||
import { Trans } from '@kit/ui/trans';
|
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 { updateInvitationAction } from '../../server/actions/team-invitations-server-actions';
|
||||||
import { MembershipRoleSelector } from '../members/membership-role-selector';
|
import { MembershipRoleSelector } from '../members/membership-role-selector';
|
||||||
import { RolesDataProvider } from '../members/roles-data-provider';
|
import { RolesDataProvider } from '../members/roles-data-provider';
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import {
|
|||||||
import { If } from '@kit/ui/if';
|
import { If } from '@kit/ui/if';
|
||||||
import { Trans } from '@kit/ui/trans';
|
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 { updateMemberRoleAction } from '../../server/actions/team-members-server-actions';
|
||||||
import { MembershipRoleSelector } from './membership-role-selector';
|
import { MembershipRoleSelector } from './membership-role-selector';
|
||||||
import { RolesDataProvider } from './roles-data-provider';
|
import { RolesDataProvider } from './roles-data-provider';
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { useTransition } from 'react';
|
|||||||
|
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import { Button } from '@kit/ui/button';
|
import { Button } from '@kit/ui/button';
|
||||||
import {
|
import {
|
||||||
@@ -17,12 +16,9 @@ import {
|
|||||||
import { Input } from '@kit/ui/input';
|
import { Input } from '@kit/ui/input';
|
||||||
import { Trans } from '@kit/ui/trans';
|
import { Trans } from '@kit/ui/trans';
|
||||||
|
|
||||||
|
import { TeamNameFormSchema } from '../../schema/update-team-name.schema';
|
||||||
import { updateTeamAccountName } from '../../server/actions/team-details-server-actions';
|
import { updateTeamAccountName } from '../../server/actions/team-details-server-actions';
|
||||||
|
|
||||||
const Schema = z.object({
|
|
||||||
name: z.string().min(1).max(255),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const UpdateTeamAccountNameForm = (props: {
|
export const UpdateTeamAccountNameForm = (props: {
|
||||||
account: {
|
account: {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -34,7 +30,7 @@ export const UpdateTeamAccountNameForm = (props: {
|
|||||||
const [pending, startTransition] = useTransition();
|
const [pending, startTransition] = useTransition();
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
resolver: zodResolver(Schema),
|
resolver: zodResolver(TeamNameFormSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
name: props.account.name,
|
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) {
|
export async function leaveTeamAccountAction(formData: FormData) {
|
||||||
const body = Object.fromEntries(formData.entries());
|
const body = Object.fromEntries(formData.entries());
|
||||||
const params = LeaveTeamAccountSchema.parse(body);
|
const params = LeaveTeamAccountSchema.parse(body);
|
||||||
const client = getSupabaseServerActionClient();
|
|
||||||
|
|
||||||
|
const client = getSupabaseServerActionClient();
|
||||||
const auth = await requireUser(client);
|
const auth = await requireUser(client);
|
||||||
|
|
||||||
if (auth.error) {
|
if (auth.error) {
|
||||||
|
|||||||
@@ -2,23 +2,26 @@
|
|||||||
|
|
||||||
import { redirect } from 'next/navigation';
|
import { redirect } from 'next/navigation';
|
||||||
|
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
|
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
|
||||||
|
|
||||||
export async function updateTeamAccountName(params: {
|
import { UpdateTeamNameSchema } from '../../schema/update-team-name.schema';
|
||||||
name: string;
|
|
||||||
slug: string;
|
export async function updateTeamAccountName(
|
||||||
path: string;
|
params: z.infer<typeof UpdateTeamNameSchema>,
|
||||||
}) {
|
) {
|
||||||
const client = getSupabaseServerComponentClient();
|
const client = getSupabaseServerComponentClient();
|
||||||
|
const { name, slug, path } = UpdateTeamNameSchema.parse(params);
|
||||||
|
|
||||||
const { error, data } = await client
|
const { error, data } = await client
|
||||||
.from('accounts')
|
.from('accounts')
|
||||||
.update({
|
.update({
|
||||||
name: params.name,
|
name,
|
||||||
slug: params.slug,
|
slug,
|
||||||
})
|
})
|
||||||
.match({
|
.match({
|
||||||
slug: params.slug,
|
slug,
|
||||||
})
|
})
|
||||||
.select('slug')
|
.select('slug')
|
||||||
.single();
|
.single();
|
||||||
@@ -30,9 +33,9 @@ export async function updateTeamAccountName(params: {
|
|||||||
const newSlug = data.slug;
|
const newSlug = data.slug;
|
||||||
|
|
||||||
if (newSlug) {
|
if (newSlug) {
|
||||||
const path = params.path.replace('[account]', newSlug);
|
const nextPath = path.replace('[account]', newSlug);
|
||||||
|
|
||||||
redirect(path);
|
redirect(nextPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-clie
|
|||||||
import { AcceptInvitationSchema } from '../../schema/accept-invitation.schema';
|
import { AcceptInvitationSchema } from '../../schema/accept-invitation.schema';
|
||||||
import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema';
|
import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema';
|
||||||
import { InviteMembersSchema } from '../../schema/invite-members.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';
|
import { AccountInvitationsService } from '../services/account-invitations.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,9 +108,11 @@ export async function acceptInvitationAction(data: FormData) {
|
|||||||
return redirect(nextPath);
|
return redirect(nextPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function renewInvitationAction(params: { invitationId: number }) {
|
export async function renewInvitationAction(
|
||||||
|
params: z.infer<typeof RenewInvitationSchema>,
|
||||||
|
) {
|
||||||
const client = getSupabaseServerActionClient();
|
const client = getSupabaseServerActionClient();
|
||||||
const { invitationId } = params;
|
const { invitationId } = RenewInvitationSchema.parse(params);
|
||||||
|
|
||||||
await assertSession(client);
|
await assertSession(client);
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-clie
|
|||||||
|
|
||||||
import { RemoveMemberSchema } from '../../schema/remove-member.schema';
|
import { RemoveMemberSchema } from '../../schema/remove-member.schema';
|
||||||
import { TransferOwnershipConfirmationSchema } from '../../schema/transfer-ownership-confirmation.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';
|
import { AccountMembersService } from '../services/account-members.service';
|
||||||
|
|
||||||
export async function removeMemberFromAccountAction(
|
export async function removeMemberFromAccountAction(
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { requireUser } from '@kit/supabase/require-user';
|
|||||||
|
|
||||||
import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema';
|
import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema';
|
||||||
import { InviteMembersSchema } from '../../schema/invite-members.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 invitePath = process.env.INVITATION_PAGE_PATH;
|
||||||
const siteURL = process.env.NEXT_PUBLIC_SITE_URL;
|
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 { RemoveMemberSchema } from '../../schema/remove-member.schema';
|
||||||
import { TransferOwnershipConfirmationSchema } from '../../schema/transfer-ownership-confirmation.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 {
|
export class AccountMembersService {
|
||||||
private readonly namespace = 'account-members';
|
private readonly namespace = 'account-members';
|
||||||
|
|||||||
Reference in New Issue
Block a user