Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 35 additions & 10 deletions frontend/app/somnia-session-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { defineChain } from "thirdweb/chains";
import { getContract } from "thirdweb/contract";
import {
getPermissionsForSigner,
isAdmin,
removeSessionKey,
} from "thirdweb/extensions/erc4337";
import { createWallet, type Account } from "thirdweb/wallets";
Expand Down Expand Up @@ -119,24 +120,48 @@ async function verifyStoredPermissions(record: SomniaSessionRecord) {
chain: somniaChain,
address: record.smartAccountAddress,
});
const permissions = await getPermissionsForSigner({
contract,
signer: record.sessionKeyAddress,
});
const [permissions, ownerIsAdmin, sessionSignerIsAdmin] = await Promise.all([
getPermissionsForSigner({
contract,
signer: record.sessionKeyAddress,
}),
isAdmin({
contract,
signer: record.ownerAddress,
}),
isAdmin({
contract,
signer: record.sessionKeyAddress,
}),
]);
const nowSeconds = BigInt(Math.floor(Date.now() / 1_000));
const targetAllowed = permissions.approvedTargets.some(
(target) =>
target.toLowerCase() === activeDeployment.dungeonAddress.toLowerCase()
const recordExpirySeconds = BigInt(
Math.floor(record.expiresAt / 1_000)
);
const maximumPermissionDuration = BigInt(
SESSION_DURATION_SECONDS + Math.ceil(CLOCK_SKEW_MS / 1_000)
);
const targetsAreRestricted =
permissions.approvedTargets.length === 1 &&
permissions.approvedTargets[0]?.toLowerCase() ===
activeDeployment.dungeonAddress.toLowerCase();
const permissionDuration =
permissions.endTimestamp - permissions.startTimestamp;

if (
permissions.signer.toLowerCase() !== record.sessionKeyAddress.toLowerCase() ||
!targetAllowed ||
!ownerIsAdmin ||
sessionSignerIsAdmin ||
!targetsAreRestricted ||
permissions.nativeTokenLimitPerTransaction !== BigInt(0) ||
permissions.startTimestamp > nowSeconds ||
permissions.endTimestamp <= nowSeconds
permissions.endTimestamp <= nowSeconds ||
permissions.endTimestamp > recordExpirySeconds ||
permissionDuration > maximumPermissionDuration
) {
throw new Error("Stored Somnia session permission is no longer active.");
throw new Error(
"Stored Somnia session permission is inactive or broader than expected."
);
}
}

Expand Down
79 changes: 78 additions & 1 deletion frontend/next.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,65 @@
import type { NextConfig } from "next";

const isDevelopment = process.env.NODE_ENV === "development";

const contentSecurityPolicy = [
"default-src 'self'",
`script-src 'self' 'unsafe-inline'${isDevelopment ? " 'unsafe-eval'" : ""} https://va.vercel-scripts.com https://vercel.live https://*.vercel.live`,
"script-src-attr 'none'",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' blob: data: https:",
"font-src 'self' data:",
[
"connect-src 'self'",
"https://dream-rpc.somnia.network",
"https://testnet.riselabs.xyz",
"wss://testnet.riselabs.xyz",
"https://*.thirdweb.com",
"wss://*.thirdweb.com",
"https://*.walletconnect.com",
"wss://*.walletconnect.com",
"https://*.walletconnect.org",
"wss://*.walletconnect.org",
"https://*.reown.com",
"wss://*.reown.com",
"https://*.metamask.io",
"wss://*.metamask.io",
"https://vitals.vercel-insights.com",
"https://vercel.live",
"https://*.vercel.live",
"wss://*.vercel.live",
...(isDevelopment
? [
"http://localhost:*",
"http://127.0.0.1:*",
"ws://localhost:*",
"ws://127.0.0.1:*",
]
: []),
].join(" "),
[
"frame-src 'self'",
"https://*.thirdweb.com",
"https://*.walletconnect.com",
"https://*.walletconnect.org",
"https://*.reown.com",
"https://vercel.live",
"https://*.vercel.live",
].join(" "),
"worker-src 'self' blob:",
"media-src 'self' blob:",
"manifest-src 'self'",
"object-src 'none'",
"base-uri 'self'",
"form-action 'self'",
"frame-ancestors 'none'",
...(isDevelopment ? [] : ["upgrade-insecure-requests"]),
].join("; ");

const securityHeaders = [
{
key: "Content-Security-Policy",
value: "frame-ancestors 'none'",
value: contentSecurityPolicy,
},
{
key: "X-Frame-Options",
Expand All @@ -21,9 +77,30 @@ const securityHeaders = [
key: "Permissions-Policy",
value: "camera=(), microphone=(), geolocation=()",
},
{
key: "Strict-Transport-Security",
value: "max-age=31536000",
},
{
key: "Cross-Origin-Opener-Policy",
value: "same-origin-allow-popups",
},
{
key: "Origin-Agent-Cluster",
value: "?1",
},
{
key: "X-DNS-Prefetch-Control",
value: "off",
},
{
key: "X-Permitted-Cross-Domain-Policies",
value: "none",
},
];

const nextConfig: NextConfig = {
poweredByHeader: false,
async redirects() {
return [
{
Expand Down
Loading
Loading