Update CSRF protection and modify database types

The CSRF protection in middleware has been re-implemented with `@edge-csrf/nextjs`, to catch and handle CSRF errors more effectively. Additionally, some parameters are renamed and functions are added in `database.types.ts` for better role management. The dependency in `package.json` has also been updated to reflect the changes.
This commit is contained in:
giancarlo
2024-04-22 11:27:54 +08:00
parent acd5ad08f9
commit e2503333e2
5 changed files with 42 additions and 15 deletions

View File

@@ -667,7 +667,7 @@ export type Database = {
can_action_account_member: { can_action_account_member: {
Args: { Args: {
target_team_account_id: string target_team_account_id: string
user_id: string target_user_id: string
} }
Returns: boolean Returns: boolean
} }
@@ -747,6 +747,10 @@ export type Database = {
Args: Record<PropertyKey, never> Args: Record<PropertyKey, never>
Returns: Json Returns: Json
} }
get_upper_system_role: {
Args: Record<PropertyKey, never>
Returns: string
}
has_more_elevated_role: { has_more_elevated_role: {
Args: { Args: {
target_user_id: string target_user_id: string
@@ -770,6 +774,14 @@ export type Database = {
} }
Returns: boolean Returns: boolean
} }
has_same_role_hierarchy_level: {
Args: {
target_user_id: string
target_account_id: string
role_name: string
}
Returns: boolean
}
is_account_owner: { is_account_owner: {
Args: { Args: {
account_id: string account_id: string

View File

@@ -1,7 +1,7 @@
import type { NextRequest } from 'next/server'; import type { NextRequest } from 'next/server';
import { NextResponse, URLPattern } from 'next/server'; import { NextResponse, URLPattern } from 'next/server';
import csrf from 'edge-csrf'; import { CsrfError, createCsrfProtect } from '@edge-csrf/nextjs';
import { checkRequiresMultiFactorAuthentication } from '@kit/supabase/check-requires-mfa'; import { checkRequiresMultiFactorAuthentication } from '@kit/supabase/check-requires-mfa';
import { createMiddlewareClient } from '@kit/supabase/middleware-client'; import { createMiddlewareClient } from '@kit/supabase/middleware-client';
@@ -46,7 +46,7 @@ async function withCsrfMiddleware(
response = new NextResponse(), response = new NextResponse(),
) { ) {
// set up CSRF protection // set up CSRF protection
const csrfMiddleware = csrf({ const csrfProtect = createCsrfProtect({
cookie: { cookie: {
secure: appConfig.production, secure: appConfig.production,
name: CSRF_SECRET_COOKIE, name: CSRF_SECRET_COOKIE,
@@ -58,17 +58,20 @@ async function withCsrfMiddleware(
['GET', 'HEAD', 'OPTIONS'], ['GET', 'HEAD', 'OPTIONS'],
}); });
const csrfError = await csrfMiddleware(request, response); try {
await csrfProtect(request, response);
// if there is a CSRF error, return a 403 response return response;
if (csrfError) { } catch (error) {
return NextResponse.json('Invalid CSRF token', { // if there is a CSRF error, return a 403 response
status: 401, if (error instanceof CsrfError) {
}); return NextResponse.json('Invalid CSRF token', {
status: 401,
});
}
throw error;
} }
// otherwise, return the response
return response;
} }
function isServerAction(request: NextRequest) { function isServerAction(request: NextRequest) {

View File

@@ -57,7 +57,7 @@
"@tanstack/react-query-next-experimental": "^5.29.2", "@tanstack/react-query-next-experimental": "^5.29.2",
"@tanstack/react-table": "^8.16.0", "@tanstack/react-table": "^8.16.0",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"edge-csrf": "1.0.12-sveltekit-1", "@edge-csrf/nextjs": "2.0.0",
"i18next": "^23.11.2", "i18next": "^23.11.2",
"i18next-resources-to-backend": "^1.2.1", "i18next-resources-to-backend": "^1.2.1",
"lucide-react": "^0.368.0", "lucide-react": "^0.368.0",

View File

@@ -74,7 +74,7 @@ export class AccountMembersService {
const { data: canActionAccountMember, error: accountError } = const { data: canActionAccountMember, error: accountError } =
await this.client.rpc('can_action_account_member', { await this.client.rpc('can_action_account_member', {
user_id: params.userId, target_user_id: params.userId,
target_team_account_id: params.accountId, target_team_account_id: params.accountId,
}); });

View File

@@ -667,7 +667,7 @@ export type Database = {
can_action_account_member: { can_action_account_member: {
Args: { Args: {
target_team_account_id: string target_team_account_id: string
user_id: string target_user_id: string
} }
Returns: boolean Returns: boolean
} }
@@ -747,6 +747,10 @@ export type Database = {
Args: Record<PropertyKey, never> Args: Record<PropertyKey, never>
Returns: Json Returns: Json
} }
get_upper_system_role: {
Args: Record<PropertyKey, never>
Returns: string
}
has_more_elevated_role: { has_more_elevated_role: {
Args: { Args: {
target_user_id: string target_user_id: string
@@ -770,6 +774,14 @@ export type Database = {
} }
Returns: boolean Returns: boolean
} }
has_same_role_hierarchy_level: {
Args: {
target_user_id: string
target_account_id: string
role_name: string
}
Returns: boolean
}
is_account_owner: { is_account_owner: {
Args: { Args: {
account_id: string account_id: string