Skip to content

Commit 0deb21c

Browse files
Copilot0xrinegade
andcommitted
Fix critical security and functional issues from audit
Co-authored-by: 0xrinegade <[email protected]>
1 parent 524cabb commit 0deb21c

File tree

5 files changed

+99
-55
lines changed

5 files changed

+99
-55
lines changed

netlify.toml

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,39 @@
33
command = "bun install && bun run build --filter=@saasfly/nextjs"
44
publish = "apps/nextjs/.next"
55

6+
# Environment variables should be set in Netlify dashboard, not committed to repo
7+
# This is for reference only - use actual secrets in Netlify environment settings
68
[build.environment]
7-
NEXTAUTH_SECRET = "netlify-build-secret-12345"
9+
# Authentication secrets - SET THESE IN NETLIFY DASHBOARD
10+
# NEXTAUTH_SECRET = "your-secure-nextauth-secret-here"
811
NEXTAUTH_URL = "https://svm-pay.netlify.app"
912
NEXT_PUBLIC_APP_URL = "https://svm-pay.netlify.app"
10-
GITHUB_CLIENT_ID = "1"
11-
GITHUB_CLIENT_SECRET = "1"
12-
RESEND_API_KEY = "1"
13-
RESEND_FROM = "1"
14-
STRIPE_API_KEY = "1"
15-
STRIPE_WEBHOOK_SECRET = "1"
16-
NEXT_PUBLIC_STRIPE_STD_PRODUCT_ID = "prod_"
17-
NEXT_PUBLIC_STRIPE_STD_MONTHLY_PRICE_ID = "price_"
18-
NEXT_PUBLIC_STRIPE_PRO_PRODUCT_ID = "prod_"
19-
NEXT_PUBLIC_STRIPE_PRO_MONTHLY_PRICE_ID = "price_"
20-
NEXT_PUBLIC_STRIPE_PRO_YEARLY_PRICE_ID = "price_"
21-
NEXT_PUBLIC_STRIPE_BUSINESS_PRODUCT_ID = "prod_"
22-
NEXT_PUBLIC_STRIPE_BUSINESS_MONTHLY_PRICE_ID = "price_"
23-
NEXT_PUBLIC_STRIPE_BUSINESS_YEARLY_PRICE_ID = "price_"
24-
NEXT_PUBLIC_POSTHOG_KEY = " "
13+
14+
# OAuth secrets - SET THESE IN NETLIFY DASHBOARD
15+
# GITHUB_CLIENT_ID = "your-github-client-id"
16+
# GITHUB_CLIENT_SECRET = "your-github-client-secret"
17+
18+
# Email service secrets - SET THESE IN NETLIFY DASHBOARD
19+
# RESEND_API_KEY = "your-resend-api-key"
20+
# RESEND_FROM = "your-sender-email"
21+
22+
# Payment provider secrets - SET THESE IN NETLIFY DASHBOARD
23+
# STRIPE_API_KEY = "your-stripe-api-key"
24+
# STRIPE_WEBHOOK_SECRET = "your-stripe-webhook-secret"
25+
26+
# Public configuration (safe to commit)
27+
NEXT_PUBLIC_STRIPE_STD_PRODUCT_ID = "prod_placeholder"
28+
NEXT_PUBLIC_STRIPE_STD_MONTHLY_PRICE_ID = "price_placeholder"
29+
NEXT_PUBLIC_STRIPE_PRO_PRODUCT_ID = "prod_placeholder"
30+
NEXT_PUBLIC_STRIPE_PRO_MONTHLY_PRICE_ID = "price_placeholder"
31+
NEXT_PUBLIC_STRIPE_PRO_YEARLY_PRICE_ID = "price_placeholder"
32+
NEXT_PUBLIC_STRIPE_BUSINESS_PRODUCT_ID = "prod_placeholder"
33+
NEXT_PUBLIC_STRIPE_BUSINESS_MONTHLY_PRICE_ID = "price_placeholder"
34+
NEXT_PUBLIC_STRIPE_BUSINESS_YEARLY_PRICE_ID = "price_placeholder"
35+
NEXT_PUBLIC_POSTHOG_KEY = ""
2536
NEXT_PUBLIC_POSTHOG_HOST = "https://app.posthog.com"
26-
ADMIN_EMAIL = "admin@saasfly.io,[email protected]"
37+
ADMIN_EMAIL = "admin@example.com"
2738
IS_DEBUG = "false"
2839

2940
[[plugins]]
30-
package = "@netlify/plugin-nextjs"
41+
package = "@netlify/plugin-nextjs"

website/apps/nextjs/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"@solana/wallet-adapter-base": "^0.9.27",
2222
"@solana/wallet-adapter-react": "^0.15.39",
2323
"@solana/wallet-adapter-react-ui": "^0.9.39",
24+
"@solana/wallet-adapter-wallets": "^0.19.27",
2425
"@solana/web3.js": "^1.98.2",
2526
"@t3-oss/env-nextjs": "0.8.0",
2627
"@tanstack/react-query": "5.72.2",

website/apps/nextjs/src/app/[lang]/(marketing)/page-old.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,16 @@ export default async function IndexPage({
106106
</div>
107107
<div className="flex flex-col items-center justify-start ml-8">
108108
<div className="w-[340px]">
109-
<text className="font-semibold">6 </text>
110-
<text
111-
className="text-neutral-500 dark:text-neutral-400">{dict.marketing.contributors?.contributors_desc || "contributors made SVM-Pay stronger"}</text>
109+
<span className="font-semibold">6 </span>
110+
<span
111+
className="text-neutral-500 dark:text-neutral-400">{dict.marketing.contributors?.contributors_desc || "contributors made SVM-Pay stronger"}</span>
112112
</div>
113113
<div className="w-[340px]">
114-
<text
115-
className="text-neutral-500 dark:text-neutral-400">{dict.marketing.contributors?.developers_first || "Help more than "}</text>
114+
<span
115+
className="text-neutral-500 dark:text-neutral-400">{dict.marketing.contributors?.developers_first || "Help more than "}</span>
116116
<ColourfulText text="1000"/>
117-
<text
118-
className="text-neutral-500 dark:text-neutral-400">{dict.marketing.contributors?.developers_second || " developers"}</text>
117+
<span
118+
className="text-neutral-500 dark:text-neutral-400">{dict.marketing.contributors?.developers_second || " developers"}</span>
119119
</div>
120120
</div>
121121
</div>

website/apps/nextjs/src/lib/sdk/solana-payment.tsx

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import React, { FC, useState } from 'react';
44
import { useWallet } from '@solana/wallet-adapter-react';
55
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
6-
import { PublicKey, Transaction, Connection } from '@solana/web3.js';
6+
import { PublicKey, Transaction, Connection, SystemProgram, LAMPORTS_PER_SOL } from '@solana/web3.js';
77

88
export interface SolanaPaymentProps {
99
amount: number; // Amount in SOL
@@ -18,45 +18,43 @@ export const SolanaPayment: FC<SolanaPaymentProps> = ({
1818
onSuccess,
1919
onError
2020
}) => {
21-
// Use try-catch to handle missing wallet context gracefully
22-
let walletState = { publicKey: null, sendTransaction: null };
23-
try {
24-
const { publicKey, sendTransaction } = useWallet();
25-
walletState = { publicKey, sendTransaction };
26-
} catch (error) {
27-
console.warn("Wallet context not available:", error);
28-
}
29-
30-
const { publicKey, sendTransaction } = walletState;
21+
const { publicKey, sendTransaction, connected } = useWallet();
3122
const [isProcessing, setIsProcessing] = useState(false);
3223
const [txSignature, setTxSignature] = useState<string | null>(null);
3324

3425
const handlePayment = async () => {
35-
if (!publicKey || !sendTransaction) return;
26+
if (!publicKey || !sendTransaction || !connected) return;
3627

3728
try {
3829
setIsProcessing(true);
3930

40-
// Create a simple transfer transaction
41-
const transaction = new Transaction().add(
42-
// Create a transfer instruction
43-
// This is a simplified example - in a real app, you would use the Solana SDK to create a proper transfer instruction
44-
{
45-
keys: [
46-
{ pubkey: publicKey, isSigner: true, isWritable: true },
47-
{ pubkey: new PublicKey(recipientAddress), isSigner: false, isWritable: true },
48-
],
49-
programId: new PublicKey('11111111111111111111111111111111'), // System program ID
50-
data: Buffer.from([2, ...new Uint8Array(8).fill(0)]), // Transfer instruction with amount
51-
}
52-
);
53-
5431
// Create a connection to use for sending the transaction
5532
const connection = new Connection('https://api.mainnet-beta.solana.com');
33+
34+
// Convert SOL amount to lamports
35+
const lamports = Math.floor(amount * LAMPORTS_PER_SOL);
36+
37+
// Create a proper transfer instruction using SystemProgram
38+
const transferInstruction = SystemProgram.transfer({
39+
fromPubkey: publicKey,
40+
toPubkey: new PublicKey(recipientAddress),
41+
lamports: lamports,
42+
});
43+
44+
// Create transaction and add the transfer instruction
45+
const transaction = new Transaction().add(transferInstruction);
46+
47+
// Get latest blockhash for the transaction
48+
const { blockhash } = await connection.getLatestBlockhash();
49+
transaction.recentBlockhash = blockhash;
50+
transaction.feePayer = publicKey;
5651

5752
// Send the transaction
5853
const signature = await sendTransaction(transaction, connection);
5954

55+
// Wait for confirmation
56+
await connection.confirmTransaction(signature, 'confirmed');
57+
6058
setTxSignature(signature);
6159
onSuccess?.(signature);
6260
} catch (error) {
@@ -69,7 +67,7 @@ export const SolanaPayment: FC<SolanaPaymentProps> = ({
6967

7068
return (
7169
<div className="solana-payment">
72-
{!publicKey ? (
70+
{!connected || !publicKey ? (
7371
<div>
7472
<p>Connect your wallet to make a payment</p>
7573
<WalletMultiButton />

website/apps/nextjs/src/lib/sdk/solana-provider.tsx

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,34 @@ import { clusterApiUrl } from '@solana/web3.js';
99
// Import the styles for the wallet modal
1010
import '@solana/wallet-adapter-react-ui/styles.css';
1111

12+
// Define wallet adapters with fallback
13+
let walletAdapters: any[] = [];
14+
15+
try {
16+
// Try to import wallet adapters
17+
const {
18+
PhantomWalletAdapter,
19+
SolflareWalletAdapter,
20+
MathWalletAdapter,
21+
Coin98WalletAdapter,
22+
SolletWalletAdapter,
23+
SolletExtensionWalletAdapter,
24+
} = require('@solana/wallet-adapter-wallets');
25+
26+
walletAdapters = [
27+
PhantomWalletAdapter,
28+
SolflareWalletAdapter,
29+
MathWalletAdapter,
30+
Coin98WalletAdapter,
31+
SolletWalletAdapter,
32+
SolletExtensionWalletAdapter,
33+
];
34+
} catch (error) {
35+
console.warn('Wallet adapters not available:', error);
36+
// Fallback to empty array if wallet adapters are not installed
37+
walletAdapters = [];
38+
}
39+
1240
export interface SolanaWalletProviderProps {
1341
children: ReactNode;
1442
projectId: string;
@@ -23,9 +51,15 @@ export const SolanaWalletProvider: FC<SolanaWalletProviderProps> = ({
2351
// The network can be set to 'devnet', 'testnet', or 'mainnet-beta'
2452
const endpoint = useMemo(() => clusterApiUrl(network), [network]);
2553

26-
// For now, use an empty array of wallets to get the build working
27-
// In production, you would add specific wallet adapters here
28-
const wallets = useMemo(() => [], []);
54+
// Configure wallet adapters for popular Solana wallets with fallback
55+
const wallets = useMemo(() => {
56+
try {
57+
return walletAdapters.map((WalletAdapter: any) => new WalletAdapter());
58+
} catch (error) {
59+
console.warn('Error initializing wallet adapters:', error);
60+
return [];
61+
}
62+
}, []);
2963

3064
return (
3165
<ConnectionProvider endpoint={endpoint}>

0 commit comments

Comments
 (0)