Refactor authentication method to requireUser
Replaced the requireAuth method with requireUser to improve clarity and modified all instances where it was used. Renamed the import throughout multiple files and services and made changes accordingly, thus making it more specific and understandable that a logged-in user is needed. The return type of the method was also updated from Session to User to more accurately reflect the information it provides.
This commit is contained in:
@@ -5,7 +5,7 @@ import { RedirectType, redirect } from 'next/navigation';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { Logger } from '@kit/shared/logger';
|
||||
import { requireAuth } from '@kit/supabase/require-auth';
|
||||
import { requireUser } from '@kit/supabase/require-user';
|
||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||
|
||||
import { DeletePersonalAccountService } from './services/delete-personal-account.service';
|
||||
@@ -28,17 +28,17 @@ export async function deletePersonalAccountAction(formData: FormData) {
|
||||
}
|
||||
|
||||
const client = getSupabaseServerActionClient();
|
||||
const session = await requireAuth(client);
|
||||
const auth = await requireUser(client);
|
||||
|
||||
if (session.error) {
|
||||
if (auth.error) {
|
||||
Logger.error(`User is not authenticated. Redirecting to login page`);
|
||||
|
||||
redirect(session.redirectTo);
|
||||
redirect(auth.redirectTo);
|
||||
}
|
||||
|
||||
// retrieve user ID and email
|
||||
const userId = session.data.user.id;
|
||||
const userEmail = session.data.user.email ?? null;
|
||||
const userId = auth.data.id;
|
||||
const userEmail = auth.data.email ?? null;
|
||||
|
||||
// create a new instance of the personal accounts service
|
||||
const service = new DeletePersonalAccountService();
|
||||
|
||||
@@ -2,5 +2,4 @@ import { z } from 'zod';
|
||||
|
||||
export const LeaveTeamAccountSchema = z.object({
|
||||
accountId: z.string(),
|
||||
userId: z.string(),
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import { redirect } from 'next/navigation';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { Logger } from '@kit/shared/logger';
|
||||
import { requireAuth } from '@kit/supabase/require-auth';
|
||||
import { requireUser } from '@kit/supabase/require-user';
|
||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||
|
||||
import { CreateTeamSchema } from '../../schema/create-team.schema';
|
||||
@@ -25,13 +25,13 @@ export async function createOrganizationAccountAction(
|
||||
|
||||
const client = getSupabaseServerActionClient();
|
||||
const service = new CreateTeamAccountService(client);
|
||||
const session = await requireAuth(client);
|
||||
const auth = await requireUser(client);
|
||||
|
||||
if (session.error) {
|
||||
redirect(session.redirectTo);
|
||||
if (auth.error) {
|
||||
redirect(auth.redirectTo);
|
||||
}
|
||||
|
||||
const userId = session.data.user.id;
|
||||
const userId = auth.data.id;
|
||||
|
||||
const createAccountResponse = await service.createNewOrganizationAccount({
|
||||
name: accountName,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { redirect } from 'next/navigation';
|
||||
import { SupabaseClient } from '@supabase/supabase-js';
|
||||
|
||||
import { Database } from '@kit/supabase/database';
|
||||
import { requireAuth } from '@kit/supabase/require-auth';
|
||||
import { requireUser } from '@kit/supabase/require-user';
|
||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||
|
||||
import { DeleteTeamAccountSchema } from '../../schema/delete-team-account.schema';
|
||||
@@ -17,7 +17,7 @@ export async function deleteTeamAccountAction(formData: FormData) {
|
||||
);
|
||||
|
||||
const client = getSupabaseServerActionClient();
|
||||
const auth = await requireAuth(client);
|
||||
const auth = await requireUser(client);
|
||||
|
||||
if (auth.error) {
|
||||
throw new Error('Authentication required');
|
||||
@@ -36,7 +36,7 @@ export async function deleteTeamAccountAction(formData: FormData) {
|
||||
}),
|
||||
{
|
||||
accountId: params.accountId,
|
||||
userId: auth.data.user.id,
|
||||
userId: auth.data.id,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -47,13 +47,13 @@ async function assertUserPermissionsToDeleteTeamAccount(
|
||||
client: SupabaseClient<Database>,
|
||||
accountId: string,
|
||||
) {
|
||||
const auth = await requireAuth(client);
|
||||
const auth = await requireUser(client);
|
||||
|
||||
if (auth.error ?? !auth.data.user.id) {
|
||||
if (auth.error ?? !auth.data.id) {
|
||||
throw new Error('Authentication required');
|
||||
}
|
||||
|
||||
const userId = auth.data.user.id;
|
||||
const userId = auth.data.id;
|
||||
|
||||
const { data, error } = await client
|
||||
.from('accounts')
|
||||
|
||||
@@ -1,16 +1,35 @@
|
||||
'use server';
|
||||
|
||||
import { revalidatePath } from 'next/cache';
|
||||
import { redirect } from 'next/navigation';
|
||||
|
||||
import { requireUser } from '@kit/supabase/require-user';
|
||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||
|
||||
import { LeaveTeamAccountSchema } from '../../schema/leave-team-account.schema';
|
||||
import { LeaveAccountService } from '../services/leave-account.service';
|
||||
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 service = new LeaveAccountService(getSupabaseServerActionClient());
|
||||
const client = getSupabaseServerActionClient();
|
||||
|
||||
await service.leaveTeamAccount(params);
|
||||
const auth = await requireUser(client);
|
||||
|
||||
return { success: true };
|
||||
if (auth.error) {
|
||||
throw new Error('Authentication required');
|
||||
}
|
||||
|
||||
const service = new LeaveTeamAccountService(
|
||||
getSupabaseServerActionClient({ admin: true }),
|
||||
);
|
||||
|
||||
await service.leaveTeamAccount({
|
||||
accountId: params.accountId,
|
||||
userId: auth.data.id,
|
||||
});
|
||||
|
||||
revalidatePath('/home/[account]', 'layout');
|
||||
|
||||
return redirect('/home');
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import { SupabaseClient } from '@supabase/supabase-js';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { Database } from '@kit/supabase/database';
|
||||
import { requireAuth } from '@kit/supabase/require-auth';
|
||||
import { requireUser } from '@kit/supabase/require-user';
|
||||
import { getSupabaseServerActionClient } from '@kit/supabase/server-actions-client';
|
||||
|
||||
import { AcceptInvitationSchema } from '../../schema/accept-invitation.schema';
|
||||
@@ -94,7 +94,7 @@ export async function acceptInvitationAction(data: FormData) {
|
||||
Object.fromEntries(data),
|
||||
);
|
||||
|
||||
const { user } = await assertSession(client);
|
||||
const user = await assertSession(client);
|
||||
|
||||
const service = new AccountInvitationsService(client);
|
||||
|
||||
@@ -123,7 +123,7 @@ export async function renewInvitationAction(params: { invitationId: number }) {
|
||||
}
|
||||
|
||||
async function assertSession(client: SupabaseClient<Database>) {
|
||||
const { error, data } = await requireAuth(client);
|
||||
const { error, data } = await requireUser(client);
|
||||
|
||||
if (error) {
|
||||
throw new Error(`Authentication required`);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { z } from 'zod';
|
||||
import { Mailer } from '@kit/mailers';
|
||||
import { Logger } from '@kit/shared/logger';
|
||||
import { Database } from '@kit/supabase/database';
|
||||
import { requireAuth } from '@kit/supabase/require-auth';
|
||||
import { requireUser } from '@kit/supabase/require-user';
|
||||
|
||||
import { DeleteInvitationSchema } from '../../schema/delete-invitation.schema';
|
||||
import { InviteMembersSchema } from '../../schema/invite-members.schema';
|
||||
@@ -102,8 +102,7 @@ export class AccountInvitationsService {
|
||||
);
|
||||
|
||||
const mailer = new Mailer();
|
||||
|
||||
const { user } = await this.getUser();
|
||||
const user = await this.getUser();
|
||||
|
||||
const accountResponse = await this.client
|
||||
.from('accounts')
|
||||
@@ -258,7 +257,7 @@ export class AccountInvitationsService {
|
||||
}
|
||||
|
||||
private async getUser() {
|
||||
const { data, error } = await requireAuth(this.client);
|
||||
const { data, error } = await requireUser(this.client);
|
||||
|
||||
if (error ?? !data) {
|
||||
throw new Error('Authentication required');
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import { SupabaseClient } from '@supabase/supabase-js';
|
||||
|
||||
import 'server-only';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { Database } from '@kit/supabase/database';
|
||||
|
||||
import { LeaveTeamAccountSchema } from '../../schema/leave-team-account.schema';
|
||||
|
||||
export class LeaveAccountService {
|
||||
constructor(private readonly client: SupabaseClient<Database>) {}
|
||||
|
||||
async leaveTeamAccount(params: z.infer<typeof LeaveTeamAccountSchema>) {
|
||||
await Promise.resolve();
|
||||
|
||||
console.log(params);
|
||||
// TODO
|
||||
// implement this method
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { SupabaseClient } from '@supabase/supabase-js';
|
||||
|
||||
import 'server-only';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { Database } from '@kit/supabase/database';
|
||||
|
||||
const Schema = z.object({
|
||||
accountId: z.string(),
|
||||
userId: z.string(),
|
||||
});
|
||||
|
||||
export class LeaveTeamAccountService {
|
||||
constructor(private readonly adminClient: SupabaseClient<Database>) {}
|
||||
|
||||
async leaveTeamAccount(params: z.infer<typeof Schema>) {
|
||||
const { accountId, userId } = Schema.parse(params);
|
||||
|
||||
const { error } = await this.adminClient
|
||||
.from('accounts_memberships')
|
||||
.delete()
|
||||
.match({
|
||||
account_id: accountId,
|
||||
user_id: userId,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,7 +195,7 @@ export class StripeWebhookHandlerService
|
||||
cancel_at_period_end: subscription.cancel_at_period_end ?? false,
|
||||
interval: interval as string,
|
||||
currency: (price as Stripe.Price).currency,
|
||||
product_id: (price as Stripe.Price).product,
|
||||
product_id: (price as Stripe.Price).product as string,
|
||||
variant_id: priceId,
|
||||
interval_count: price?.recurring?.interval_count ?? 1,
|
||||
period_starts_at: getISOString(subscription.current_period_start),
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"./server-component-client": "./src/clients/server-component.client.ts",
|
||||
"./browser-client": "./src/clients/browser.client.ts",
|
||||
"./check-requires-mfa": "./src/check-requires-mfa.ts",
|
||||
"./require-auth": "./src/require-auth.ts",
|
||||
"./require-user": "./src/require-user.ts",
|
||||
"./hooks/*": "./src/hooks/*.ts",
|
||||
"./components/*": "./src/components/*.tsx",
|
||||
"./database": "./src/database.types.ts"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Session, SupabaseClient } from '@supabase/supabase-js';
|
||||
import type { SupabaseClient, User } from '@supabase/supabase-js';
|
||||
|
||||
import { z } from 'zod';
|
||||
|
||||
@@ -15,18 +15,14 @@ const SIGN_IN_PATH = z
|
||||
.parse(process.env.SIGN_IN_PATH);
|
||||
|
||||
/**
|
||||
* @name requireAuth
|
||||
* @name requireUser
|
||||
* @description Require a session to be present in the request
|
||||
* @param client
|
||||
* @param verifyFromServer
|
||||
*/
|
||||
export async function requireAuth(
|
||||
client: SupabaseClient,
|
||||
verifyFromServer = true,
|
||||
): Promise<
|
||||
export async function requireUser(client: SupabaseClient): Promise<
|
||||
| {
|
||||
error: null;
|
||||
data: Session;
|
||||
data: User;
|
||||
}
|
||||
| (
|
||||
| {
|
||||
@@ -41,9 +37,9 @@ export async function requireAuth(
|
||||
}
|
||||
)
|
||||
> {
|
||||
const { data, error } = await client.auth.getSession();
|
||||
const { data, error } = await client.auth.getUser();
|
||||
|
||||
if (!data.session || error) {
|
||||
if (!data.user || error) {
|
||||
return {
|
||||
data: null,
|
||||
error: new AuthenticationError(),
|
||||
@@ -63,21 +59,9 @@ export async function requireAuth(
|
||||
};
|
||||
}
|
||||
|
||||
if (verifyFromServer) {
|
||||
const { data: user, error } = await client.auth.getUser();
|
||||
|
||||
if (!user || error) {
|
||||
return {
|
||||
data: null,
|
||||
error: new AuthenticationError(),
|
||||
redirectTo: SIGN_IN_PATH,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
error: null,
|
||||
data: data.session,
|
||||
data: data.user,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { MDXComponents } from 'mdx/types';
|
||||
import { getMDXComponent } from 'next-contentlayer/hooks';
|
||||
|
||||
import Components from './mdx-components';
|
||||
// @ts-expect-error: weird typescript error with css modules
|
||||
// @ts-ignore: ignore weird error
|
||||
import styles from './mdx-renderer.module.css';
|
||||
|
||||
export function Mdx({
|
||||
|
||||
Reference in New Issue
Block a user