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
9 changes: 5 additions & 4 deletions .github/workflows/publish-ghcr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
Expand All @@ -29,6 +29,7 @@ jobs:
- name: lowercase github.repository
run: |
echo "IMAGE_NAME=`echo ${{github.repository}} | tr '[:upper:]' '[:lower:]'`" >>${GITHUB_ENV}
echo "SAFE_REF_NAME=`echo ${{github.ref_name}} | tr '/' '-'`" >>${GITHUB_ENV}

- name: Bump version and push tag
id: tag_version
Expand All @@ -53,7 +54,7 @@ jobs:
org.opencontainers.image.source=https://github.com/${{ github.repository }}
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.SAFE_REF_NAME }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.tag_version.outputs.new_version }}

- name: Build and push Docker image for non-main branches
Expand All @@ -64,8 +65,8 @@ jobs:
push: true
build-args: |
NEXT_PUBLIC_GA_ID=${{ vars.NEXT_PUBLIC_GA_ID }}
NEXT_PUBLIC_VERSION=${{ github.ref_name }}
NEXT_PUBLIC_VERSION=${{ env.SAFE_REF_NAME }}
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository }}
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.SAFE_REF_NAME }}
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
audit-level=high
engine-strict=false
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# ---- Base Node ----
FROM node:19-alpine AS base
RUN corepack enable && corepack prepare pnpm@latest --activate
FROM node:22-alpine AS base
RUN corepack enable && corepack prepare pnpm@11.1.1 --activate
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
# ---- Dependencies ----
FROM base AS dependencies
RUN pnpm install --frozen-lockfile
Expand All @@ -19,8 +19,8 @@ ARG NEXT_PUBLIC_WEBSOCKET_URLS
ENV NEXT_PUBLIC_WEBSOCKET_URLS=${NEXT_PUBLIC_WEBSOCKET_URLS}
RUN pnpm run build
# ---- Production ----
FROM node:19-alpine AS production
RUN corepack enable && corepack prepare pnpm@latest --activate
FROM node:22-alpine AS production
RUN corepack enable && corepack prepare pnpm@11.1.1 --activate
WORKDIR /app
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=build /app/.next ./.next
Expand Down
6 changes: 4 additions & 2 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import './globals.css';

import { UserProvider } from '@auth0/nextjs-auth0/client';
import { Inter } from 'next/font/google';
import { headers } from 'next/headers';
import { ThemeProvider } from 'next-themes';

import { ConditionalAnalytics } from '@/components/analytics';
Expand Down Expand Up @@ -90,16 +91,17 @@ export const metadata = {
}
};

export default function RootLayout({
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const nonce = (await headers()).get('x-nonce') ?? '';
return (
<html lang="en" suppressHydrationWarning>
<head>
<meta name="color-scheme" content="light dark" />
<ThemeScript />
<ThemeScript nonce={nonce} />
</head>
<body className={inter.className}>
<ThemeProvider
Expand Down
3 changes: 2 additions & 1 deletion components/theme-script.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function ThemeScript() {
export function ThemeScript({ nonce }: { nonce: string }) {
const codeToRunOnClient = `
(function() {
try {
Expand All @@ -17,6 +17,7 @@ export function ThemeScript() {

return (
<script
nonce={nonce}
dangerouslySetInnerHTML={{
__html: codeToRunOnClient,
}}
Expand Down
47 changes: 47 additions & 0 deletions middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
if (process.env.NODE_ENV !== 'production') {
return NextResponse.next();
}

const nonce = btoa(crypto.randomUUID());

const csp = [
`script-src 'self' 'nonce-${nonce}' 'strict-dynamic' https://www.googletagmanager.com`,
`style-src 'self' 'unsafe-inline'`,
`img-src 'self' data: blob: https://chat.akash.network https://www.google-analytics.com`,
`font-src 'self'`,
`connect-src 'self' https://api.akashml.com https://chatapi.akash.network https://auth.akash.network https://*.auth0.com https://www.google-analytics.com https://www.googletagmanager.com wss:`,
`worker-src 'self'`,
`media-src 'self' blob:`,
`frame-src 'none'`,
`frame-ancestors 'self'`,
`object-src 'none'`,
`base-uri 'self'`,
`form-action 'self'`,
`manifest-src 'self'`,
`upgrade-insecure-requests`,
].join('; ');

const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-nonce', nonce);

const response = NextResponse.next({ request: { headers: requestHeaders } });
response.headers.set('Content-Security-Policy', csp);

return response;
}

export const config = {
matcher: [
{
source: '/((?!_next/static|_next/image|.*\\.(?:ico|png|jpg|jpeg|svg|gif|webp|woff|woff2|ttf|otf|mp3|mp4|webm)).*)',
missing: [
{ type: 'header', key: 'next-router-prefetch' },
{ type: 'header', key: 'purpose', value: 'prefetch' },
],
},
],
};
20 changes: 18 additions & 2 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,25 @@ const nextConfig = {
key: 'X-XSS-Protection',
value: '1; mode=block',
},
...(process.env.NODE_ENV === 'production' ? [{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload',
}] : []),
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(self), geolocation=()',
},
{
key: 'Cross-Origin-Opener-Policy',
value: 'same-origin',
},
{
key: 'Cross-Origin-Resource-Policy',
value: 'same-origin',
},
],
},
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"@ai-sdk/openai": "^1.3.24",
"@ai-sdk/react": "^1.2.12",
"@auth0/nextjs-auth0": "^3.8.0",
"@next/third-parties": "^15.5.15",
"@next/third-parties": "^15.5.18",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-separator": "^1.1.8",
Expand All @@ -27,7 +27,7 @@
"ioredis": "^5.10.1",
"katex": "^0.16.45",
"lucide-react": "^0.469.0",
"next": "^15.5.15",
"next": "^15.5.18",
"next-pwa": "^5.6.0",
"next-themes": "^0.4.6",
"openai": "4.52.6",
Expand Down Expand Up @@ -58,18 +58,18 @@
"@types/react-dom": "^18.3.7",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"autoprefixer": "^10.4.27",
"autoprefixer": "^10.5.0",
"eslint": "8.57.1",
"eslint-config-next": "^15.5.15",
"eslint-config-next": "^15.5.18",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"postcss": "^8.5.9",
"postcss": "^8.5.14",
"tailwindcss": "^3.4.19",
"tsx": "^4.21.0",
"typescript": "5.6.3"
},
"packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0",
"packageManager": "pnpm@11.1.1+sha512.d1fdf5f73c617b64fa1a56a81c3c8dfe0e966e33a6010aa256b517ae77be21d93e05affc0de1a83b0e4f29d569f68b446ae8f068cd7247c0bb3df0fb4d7bdf9a",
"pnpm": {
"overrides": {
"serialize-javascript": ">=6.0.2"
Expand Down
Loading
Loading