Skip to content

Commit 58adc97

Browse files
committed
Refactor API handlers to include client IP and enhance session management
- Updated multiple API routes to incorporate client IP retrieval for improved security and tracking. - Refactored the createCaller function to include additional session parameters, enhancing user session management. - Removed unnecessary client-side loading of MeshProvider, replacing it with a dynamic import to avoid SSR issues.
1 parent a511fef commit 58adc97

File tree

8 files changed

+278
-8
lines changed

8 files changed

+278
-8
lines changed
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
-- Enable Row Level Security (RLS) and deny-all policies for PostgREST roles
2+
-- This migration is designed for Supabase:
3+
-- - Blocks access for `anon` and `authenticated` roles (used by PostgREST)
4+
-- - Allows Prisma (using the service role) to continue bypassing RLS
5+
6+
-- Helper comment:
7+
-- Pattern applied for each table:
8+
-- ALTER TABLE "TableName" ENABLE ROW LEVEL SECURITY;
9+
-- CREATE POLICY "deny_all_anon_TableName" ON "TableName"
10+
-- FOR ALL TO anon USING (false) WITH CHECK (false);
11+
-- CREATE POLICY "deny_all_authenticated_TableName" ON "TableName"
12+
-- FOR ALL TO authenticated USING (false) WITH CHECK (false);
13+
14+
-- =========================
15+
-- User
16+
-- =========================
17+
ALTER TABLE "User" ENABLE ROW LEVEL SECURITY;
18+
19+
CREATE POLICY "deny_all_anon_User" ON "User"
20+
FOR ALL
21+
TO anon
22+
USING (false)
23+
WITH CHECK (false);
24+
25+
CREATE POLICY "deny_all_authenticated_User" ON "User"
26+
FOR ALL
27+
TO authenticated
28+
USING (false)
29+
WITH CHECK (false);
30+
31+
-- =========================
32+
-- Wallet
33+
-- =========================
34+
ALTER TABLE "Wallet" ENABLE ROW LEVEL SECURITY;
35+
36+
CREATE POLICY "deny_all_anon_Wallet" ON "Wallet"
37+
FOR ALL
38+
TO anon
39+
USING (false)
40+
WITH CHECK (false);
41+
42+
CREATE POLICY "deny_all_authenticated_Wallet" ON "Wallet"
43+
FOR ALL
44+
TO authenticated
45+
USING (false)
46+
WITH CHECK (false);
47+
48+
-- =========================
49+
-- Transaction
50+
-- =========================
51+
ALTER TABLE "Transaction" ENABLE ROW LEVEL SECURITY;
52+
53+
CREATE POLICY "deny_all_anon_Transaction" ON "Transaction"
54+
FOR ALL
55+
TO anon
56+
USING (false)
57+
WITH CHECK (false);
58+
59+
CREATE POLICY "deny_all_authenticated_Transaction" ON "Transaction"
60+
FOR ALL
61+
TO authenticated
62+
USING (false)
63+
WITH CHECK (false);
64+
65+
-- =========================
66+
-- Signable
67+
-- =========================
68+
ALTER TABLE "Signable" ENABLE ROW LEVEL SECURITY;
69+
70+
CREATE POLICY "deny_all_anon_Signable" ON "Signable"
71+
FOR ALL
72+
TO anon
73+
USING (false)
74+
WITH CHECK (false);
75+
76+
CREATE POLICY "deny_all_authenticated_Signable" ON "Signable"
77+
FOR ALL
78+
TO authenticated
79+
USING (false)
80+
WITH CHECK (false);
81+
82+
-- =========================
83+
-- NewWallet
84+
-- =========================
85+
ALTER TABLE "NewWallet" ENABLE ROW LEVEL SECURITY;
86+
87+
CREATE POLICY "deny_all_anon_NewWallet" ON "NewWallet"
88+
FOR ALL
89+
TO anon
90+
USING (false)
91+
WITH CHECK (false);
92+
93+
CREATE POLICY "deny_all_authenticated_NewWallet" ON "NewWallet"
94+
FOR ALL
95+
TO authenticated
96+
USING (false)
97+
WITH CHECK (false);
98+
99+
-- =========================
100+
-- Nonce
101+
-- =========================
102+
ALTER TABLE "Nonce" ENABLE ROW LEVEL SECURITY;
103+
104+
CREATE POLICY "deny_all_anon_Nonce" ON "Nonce"
105+
FOR ALL
106+
TO anon
107+
USING (false)
108+
WITH CHECK (false);
109+
110+
CREATE POLICY "deny_all_authenticated_Nonce" ON "Nonce"
111+
FOR ALL
112+
TO authenticated
113+
USING (false)
114+
WITH CHECK (false);
115+
116+
-- =========================
117+
-- Ballot
118+
-- =========================
119+
ALTER TABLE "Ballot" ENABLE ROW LEVEL SECURITY;
120+
121+
CREATE POLICY "deny_all_anon_Ballot" ON "Ballot"
122+
FOR ALL
123+
TO anon
124+
USING (false)
125+
WITH CHECK (false);
126+
127+
CREATE POLICY "deny_all_authenticated_Ballot" ON "Ballot"
128+
FOR ALL
129+
TO authenticated
130+
USING (false)
131+
WITH CHECK (false);
132+
133+
-- =========================
134+
-- Proxy
135+
-- =========================
136+
ALTER TABLE "Proxy" ENABLE ROW LEVEL SECURITY;
137+
138+
CREATE POLICY "deny_all_anon_Proxy" ON "Proxy"
139+
FOR ALL
140+
TO anon
141+
USING (false)
142+
WITH CHECK (false);
143+
144+
CREATE POLICY "deny_all_authenticated_Proxy" ON "Proxy"
145+
FOR ALL
146+
TO authenticated
147+
USING (false)
148+
WITH CHECK (false);
149+
150+
-- =========================
151+
-- BalanceSnapshot
152+
-- =========================
153+
ALTER TABLE "BalanceSnapshot" ENABLE ROW LEVEL SECURITY;
154+
155+
CREATE POLICY "deny_all_anon_BalanceSnapshot" ON "BalanceSnapshot"
156+
FOR ALL
157+
TO anon
158+
USING (false)
159+
WITH CHECK (false);
160+
161+
CREATE POLICY "deny_all_authenticated_BalanceSnapshot" ON "BalanceSnapshot"
162+
FOR ALL
163+
TO authenticated
164+
USING (false)
165+
WITH CHECK (false);
166+
167+
-- =========================
168+
-- Migration
169+
-- =========================
170+
ALTER TABLE "Migration" ENABLE ROW LEVEL SECURITY;
171+
172+
CREATE POLICY "deny_all_anon_Migration" ON "Migration"
173+
FOR ALL
174+
TO anon
175+
USING (false)
176+
WITH CHECK (false);
177+
178+
CREATE POLICY "deny_all_authenticated_Migration" ON "Migration"
179+
FOR ALL
180+
TO authenticated
181+
USING (false)
182+
WITH CHECK (false);
183+
184+
-- =========================
185+
-- Crowdfund
186+
-- =========================
187+
-- Note: Crowdfund table exists in the database but is not defined in the current Prisma schema.
188+
-- We still enable RLS and deny-all policies to secure its PostgREST exposure.
189+
ALTER TABLE "Crowdfund" ENABLE ROW LEVEL SECURITY;
190+
191+
CREATE POLICY "deny_all_anon_Crowdfund" ON "Crowdfund"
192+
FOR ALL
193+
TO anon
194+
USING (false)
195+
WITH CHECK (false);
196+
197+
CREATE POLICY "deny_all_authenticated_Crowdfund" ON "Crowdfund"
198+
FOR ALL
199+
TO authenticated
200+
USING (false)
201+
WITH CHECK (false);
202+
203+
-- =========================
204+
-- _prisma_migrations (optional system table)
205+
-- =========================
206+
-- While Prisma typically manages this table without RLS, enabling RLS here
207+
-- and denying anon/authenticated helps ensure it is not exposed via PostgREST.
208+
ALTER TABLE "_prisma_migrations" ENABLE ROW LEVEL SECURITY;
209+
210+
CREATE POLICY "deny_all_anon__prisma_migrations" ON "_prisma_migrations"
211+
FOR ALL
212+
TO anon
213+
USING (false)
214+
WITH CHECK (false);
215+
216+
CREATE POLICY "deny_all_authenticated__prisma_migrations" ON "_prisma_migrations"
217+
FOR ALL
218+
TO authenticated
219+
USING (false)
220+
WITH CHECK (false);
221+
222+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"use client";
2+
3+
import "@meshsdk/react/styles.css";
4+
import { MeshProvider } from "@meshsdk/react";
5+
6+
export default MeshProvider;
7+
8+

src/pages/_app.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import dynamic from "next/dynamic";
1010
import { api } from "@/utils/api";
1111

1212
import "@/styles/globals.css";
13-
import "@meshsdk/react/styles.css";
1413
import { Toaster } from "@/components/ui/toaster";
1514
import Metatags from "@/components/ui/metatags";
1615
import RootLayout from "@/components/common/overall-layout/layout";
@@ -20,9 +19,9 @@ import "swagger-ui-react/swagger-ui.css";
2019
import "../styles/swagger-overrides.css";
2120

2221
// MeshProvider pulls in dependencies that assume a browser/webpack env.
23-
// Load it client-side only to avoid SSR/runtime issues in Next.js dev/SSR.
22+
// Load it client-side only (including its styles) to avoid SSR/runtime issues.
2423
const MeshProviderNoSSR = dynamic(
25-
() => import("@meshsdk/react").then((m) => m.MeshProvider),
24+
() => import("@/components/common/MeshProviderClient"),
2625
{ ssr: false },
2726
);
2827

src/pages/api/v1/freeUtxos.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { db } from "@/server/db";
1313
import { verifyJwt } from "@/lib/verifyJwt";
1414
import { DbWalletWithLegacy } from "@/types/wallet";
1515
import { applyRateLimit } from "@/lib/security/requestGuards";
16+
import { getClientIP } from "@/lib/security/rateLimit";
1617

1718
export default async function handler(
1819
req: NextApiRequest,
@@ -50,7 +51,15 @@ export default async function handler(
5051
user: { id: payload.address },
5152
expires: new Date(Date.now() + 60 * 60 * 1000).toISOString(), // 1 hour from now
5253
};
53-
const caller = createCaller({ db, session });
54+
55+
const caller = createCaller({
56+
db,
57+
session,
58+
sessionAddress: payload.address,
59+
sessionWallets: [payload.address],
60+
primaryWallet: payload.address,
61+
ip: getClientIP(req),
62+
});
5463

5564
const { walletId, address } = req.query;
5665

src/pages/api/v1/nativeScript.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { createCaller } from "@/server/api/root";
77
import { db } from "@/server/db";
88
import { DbWalletWithLegacy } from "@/types/wallet";
99
import { applyRateLimit } from "@/lib/security/requestGuards";
10+
import { getClientIP } from "@/lib/security/rateLimit";
1011

1112
export default async function handler(
1213
req: NextApiRequest,
@@ -58,7 +59,14 @@ export default async function handler(
5859
return res.status(403).json({ error: "Address mismatch" });
5960
}
6061

61-
const caller = createCaller({ db, session });
62+
const caller = createCaller({
63+
db,
64+
session,
65+
sessionAddress: payload.address,
66+
sessionWallets: [payload.address],
67+
primaryWallet: payload.address,
68+
ip: getClientIP(req),
69+
});
6270
const walletFetch: DbWallet | null = await caller.wallet.getWallet({ walletId, address });
6371
if (!walletFetch) {
6472
return res.status(404).json({ error: "Wallet not found" });

src/pages/api/v1/pendingTransactions.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { createCaller } from "@/server/api/root";
44
import { db } from "@/server/db";
55
import type { NextApiRequest, NextApiResponse } from "next";
66
import { applyRateLimit } from "@/lib/security/requestGuards";
7+
import { getClientIP } from "@/lib/security/rateLimit";
78

89
export default async function handler(
910
req: NextApiRequest,
@@ -55,7 +56,14 @@ export default async function handler(
5556
}
5657

5758
try {
58-
const caller = createCaller({ db, session });
59+
const caller = createCaller({
60+
db,
61+
session,
62+
sessionAddress: payload.address,
63+
sessionWallets: [payload.address],
64+
primaryWallet: payload.address,
65+
ip: getClientIP(req),
66+
});
5967

6068
const wallet = await caller.wallet.getWallet({ walletId, address });
6169
if (!wallet) {

src/pages/api/v1/signTransaction.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { addressToNetwork } from "@/utils/multisigSDK";
99
import { resolvePaymentKeyHash } from "@meshsdk/core";
1010
import { csl, calculateTxHash } from "@meshsdk/core-csl";
1111
import { applyRateLimit, enforceBodySize } from "@/lib/security/requestGuards";
12+
import { getClientIP } from "@/lib/security/rateLimit";
1213

1314
function coerceBoolean(value: unknown, fallback = false): boolean {
1415
if (typeof value === "boolean") return value;
@@ -123,7 +124,14 @@ export default async function handler(
123124
}
124125

125126
try {
126-
const caller = createCaller({ db, session });
127+
const caller = createCaller({
128+
db,
129+
session,
130+
sessionAddress: payload.address,
131+
sessionWallets: [payload.address],
132+
primaryWallet: payload.address,
133+
ip: getClientIP(req),
134+
});
127135

128136
const wallet = await caller.wallet.getWallet({ walletId, address });
129137
if (!wallet) {

src/pages/api/v1/walletIds.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { db } from "@/server/db";
44
import { verifyJwt } from "@/lib/verifyJwt";
55
import { cors, addCorsCacheBustingHeaders } from "@/lib/cors";
66
import { applyRateLimit } from "@/lib/security/requestGuards";
7+
import { getClientIP } from "@/lib/security/rateLimit";
78

89
export default async function handler(
910
req: NextApiRequest,
@@ -41,7 +42,14 @@ export default async function handler(
4142
user: { id: payload.address },
4243
expires: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
4344
};
44-
const caller = createCaller({ db, session });
45+
const caller = createCaller({
46+
db,
47+
session,
48+
sessionAddress: payload.address,
49+
sessionWallets: [payload.address],
50+
primaryWallet: payload.address,
51+
ip: getClientIP(req),
52+
});
4553

4654
const { address } = req.query;
4755

0 commit comments

Comments
 (0)