Skip to content

Commit

Permalink
Middleware tweaks; TODOs
Browse files Browse the repository at this point in the history
  • Loading branch information
Soxasora committed Mar 9, 2025
1 parent bd72179 commit 2acbb44
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 117 deletions.
1 change: 0 additions & 1 deletion api/paidAction/territoryDomain.js

This file was deleted.

43 changes: 0 additions & 43 deletions api/resolvers/customDomain.js

This file was deleted.

20 changes: 3 additions & 17 deletions components/sub-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export function useSubs ({ prependSubs = DEFAULT_PREPEND_SUBS, sub, filterSubs =
...appendSubs])
}, [data])

// TODO: can pass custom domain

return subs
}

Expand Down Expand Up @@ -79,23 +81,7 @@ export default function SubSelect ({ prependSubs, sub, onChange, size, appendSub
return
}

// Check if we're on a custom domain

// TODO: main domain should be in the env
// If we're on stacker.news and selecting a territory, redirect to territory subdomain
const host = window.location.host
console.log('host', host)
if (host === 'sn.soxa.dev' && sub) {
// Get the base domain (e.g., soxa.dev) from environment or config
const protocol = window.location.protocol

// Create the territory subdomain URL
const territoryUrl = `${protocol}//${sub}.soxa.dev/?source=stackernews`

// Redirect to the territory subdomain
window.location.href = territoryUrl
return
}
// TODO: redirect to the custom domain if it has one

let asPath
// are we currently in a sub (ie not home)
Expand Down
7 changes: 4 additions & 3 deletions components/territory-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export default function TerritoryForm ({ sub }) {
}
}, [sub, billing])

// TODO: Add a custom domain textbox and verification status; validation too
return (
<FeeButtonProvider baseLineItems={lineItems}>
<Form
Expand Down Expand Up @@ -274,9 +275,9 @@ export default function TerritoryForm ({ sub }) {
name='nsfw'
groupClassName='ms-1'
/>
<BootstrapForm.Label>personalized domains</BootstrapForm.Label>
<div className='mb-3'>WIP {sub?.customDomain?.domain}</div>
<BootstrapForm.Label>color scheme</BootstrapForm.Label>
<BootstrapForm.Label>personalized domains (TODO textbox/status)</BootstrapForm.Label>
<div className='mb-3'>WIP {sub?.customDomain?.domain || 'not set'}</div>
<BootstrapForm.Label>color scheme (TODO 5 options)</BootstrapForm.Label>
<div className='mb-3'>WIP</div>
</>

Expand Down
4 changes: 4 additions & 0 deletions docs/user/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ The stats for each territory are the following:

You can filter the same stats by different periods in [top territories](/top/territories/day).

### TODO: How can I add a custom domain to a territory?

TODO

---

## Zaps
Expand Down
100 changes: 49 additions & 51 deletions middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,14 @@ const SN_REFERRER_NONCE = 'sn_referrer_nonce'
// key for referred pages
const SN_REFEREE_LANDING = 'sn_referee_landing'

const TERRITORY_PATHS = [
'/',
'/~',
'/recent',
'/random',
'/top',
'/items'
]
const TERRITORY_PATHS = ['/~', '/recent', '/random', '/top', '/post', '/edit']
const NO_REWRITE_PATHS = ['/api', '/_next', '/_error', '/404', '/500', '/offline', '/static', '/items']

function getDomainMapping () {
// placeholder for cachedFetcher
return {
'forum.pizza.com': { subName: 'pizza' }
// placeholder
// placeholder for other domains
}
}

Expand All @@ -33,7 +27,9 @@ export function customDomainMiddleware (request, referrerResp) {
const referer = request.headers.get('referer')
const url = request.nextUrl.clone()
const pathname = url.pathname
const mainDomain = process.env.NEXT_PUBLIC_URL
const mainDomain = process.env.NEXT_PUBLIC_URL + '/'
console.log('host', host)
console.log('mainDomain', mainDomain)

console.log('referer', referer)

Expand All @@ -43,31 +39,25 @@ export function customDomainMiddleware (request, referrerResp) {
return NextResponse.redirect(new URL(pathname, mainDomain))
}

// For territory paths, handle them directly on the custom domain
if (TERRITORY_PATHS.includes(pathname)) {
// Internally rewrite the request to the territory path without changing the URL
const internalUrl = new URL(url)
if (NO_REWRITE_PATHS.some(p => pathname.startsWith(p)) || pathname.includes('.')) {
return NextResponse.next()
}

// If we're at the root path, internally rewrite to the territory path
if (pathname === '/' || pathname === '/~') {
internalUrl.pathname = `/~${domainInfo.subName}`
console.log('Internal rewrite to:', internalUrl.pathname)
console.log('pathname', pathname)
console.log('query', url.searchParams)

// NextResponse.rewrite() keeps the URL the same for the user
// but internally fetches from the rewritten path
return NextResponse.rewrite(internalUrl)
}

// For other territory paths like /recent, /top, etc.
// We need to rewrite them to the territory-specific versions
if (pathname === '/recent' || pathname === '/top' || pathname === '/random' || pathname === '/items') {
internalUrl.pathname = `/~${domainInfo.subName}${pathname}`
console.log('Internal rewrite to:', internalUrl.pathname)
return NextResponse.rewrite(internalUrl)
}
// if the url contains the territory path, remove it
if (pathname.startsWith(`/~${domainInfo.subName}`)) {
// remove the territory prefix from the path
const cleanPath = pathname.replace(`/~${domainInfo.subName}`, '') || '/'
console.log('Redirecting to clean path:', cleanPath)
return NextResponse.redirect(new URL(cleanPath + url.search, url.origin))
}

// Handle auth if needed
if (!referer || referer !== mainDomain) {
// if territory path, retain custom domain
if (pathname === '/' || TERRITORY_PATHS.some(p => pathname.startsWith(p))) {
// if coming from main domain, handle auth automatically
if (referer && referer === mainDomain) {
const authResp = customDomainAuthMiddleware(request, url)
if (authResp && authResp.status !== 200) {
// copy referrer cookies to auth redirect
Expand All @@ -77,7 +67,15 @@ export function customDomainMiddleware (request, referrerResp) {
return authResp
}
}
return referrerResp

const internalUrl = new URL(url)

// rewrite to the territory path if we're at the root
internalUrl.pathname = `/~${domainInfo.subName}${pathname === '/' ? '' : pathname}`
console.log('Rewrite to:', internalUrl.pathname)

// rewrite to the territory path
return NextResponse.rewrite(internalUrl)
}

// redirect to main domain for non-territory paths
Expand All @@ -93,7 +91,7 @@ export function customDomainMiddleware (request, referrerResp) {
}

// TODO: dirty of previous iterations, refactor
// Not safe, tokens are visible in the URL
// UNSAFE UNSAFE UNSAFE tokens are visible in the URL
export function customDomainAuthMiddleware (request, url) {
const pathname = url.pathname
const host = request.headers.get('host')
Expand All @@ -114,7 +112,6 @@ export function customDomainAuthMiddleware (request, url) {
const response = NextResponse.next()

if (!hasSession && isCustomDomain) {
// Use the original request's host and protocol for the redirect URL
// TODO: original request url points to localhost, this is a workaround atm
const protocol = secure ? 'https' : 'http'
const originalDomain = `${protocol}://${host}`
Expand Down Expand Up @@ -206,22 +203,7 @@ function referrerMiddleware (request) {
return response
}

export function middleware (request) {
const host = request.headers.get('host')
const isCustomDomain = host !== process.env.NEXT_PUBLIC_URL.replace(/^https?:\/\//, '')

// First run referrer middleware to capture referrer data
const referrerResp = referrerMiddleware(request)

// If we're on a custom domain, handle that next
if (isCustomDomain) {
return customDomainMiddleware(request, referrerResp)
}

const resp = referrerResp

// TODO: This doesn't run for custom domains, need to support it

export function applySecurityHeaders (resp) {
const isDev = process.env.NODE_ENV === 'development'

const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
Expand Down Expand Up @@ -268,6 +250,22 @@ export function middleware (request) {
return resp
}

export function middleware (request) {
const host = request.headers.get('host')
const isCustomDomain = host !== process.env.NEXT_PUBLIC_URL.replace(/^https?:\/\//, '')

// First run referrer middleware to capture referrer data
const referrerResp = referrerMiddleware(request)

// If we're on a custom domain, handle that next
if (isCustomDomain) {
const customDomainResp = customDomainMiddleware(request, referrerResp)
return applySecurityHeaders(customDomainResp)
}

return applySecurityHeaders(referrerResp)
}

export const config = {
matcher: [
// NextJS recommends to not add the CSP header to prefetches and static assets
Expand Down
6 changes: 4 additions & 2 deletions pages/api/auth/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { getAuthOptions } from './[...nextauth]'
import { serialize } from 'cookie'
import { datePivot } from '@/lib/time'

// TODO: not safe, tokens are visible in the URL
// TODO: dirty of previous iterations, refactor
// UNSAFE UNSAFE UNSAFE tokens are visible in the URL
export default async function handler (req, res) {
console.log(req.query)
if (req.query.token) {
Expand All @@ -12,6 +13,7 @@ export default async function handler (req, res) {
} else {
const { redirectUrl } = req.query
const session = await getServerSession(req, res, getAuthOptions(req))
// TODO: use session to create a verification token
if (session) {
console.log('session', session)
console.log('req.cookies', req.cookies)
Expand Down Expand Up @@ -43,12 +45,12 @@ export default async function handler (req, res) {
}

export async function saveCookie (req, res, tokenData) {
const secure = process.env.NODE_ENV === 'development'
if (!tokenData) {
return res.status(400).json({ error: 'Missing token' })
}

try {
const secure = process.env.NODE_ENV === 'development'
const expiresAt = datePivot(new Date(), { months: 1 })
const cookieOptions = {
path: '/',
Expand Down

0 comments on commit 2acbb44

Please sign in to comment.