Files
stats/apps/dashboard/src/middleware.ts
Carl-Gerhard Lindesvärd d31d9924a5 feature(auth): replace clerk.com with custom auth (#103)
* feature(auth): replace clerk.com with custom auth

* minor fixes

* remove notification preferences

* decrease live events interval

fix(api): cookies..

# Conflicts:
#	.gitignore
#	apps/api/src/index.ts
#	apps/dashboard/src/app/providers.tsx
#	packages/trpc/src/trpc.ts
2024-12-20 22:23:07 +01:00

88 lines
2.4 KiB
TypeScript

import { COOKIE_MAX_AGE, COOKIE_OPTIONS } from '@openpanel/auth/constants';
import { type NextRequest, NextResponse } from 'next/server';
function createRouteMatcher(patterns: string[]) {
// Convert route patterns to regex patterns
const regexPatterns = patterns.map((pattern) => {
// Replace route parameters (:id) with regex capture groups
const regexPattern = pattern
.replace(/\//g, '\\/') // Escape forward slashes
.replace(/:\w+/g, '([^/]+)') // Convert :param to capture groups
.replace(/\(\.\*\)\?/g, '(?:.*)?'); // Handle optional wildcards
return new RegExp(`^${regexPattern}$`);
});
// Return a matcher function
return (req: { url: string }) => {
const pathname = new URL(req.url).pathname;
return regexPatterns.some((regex) => regex.test(pathname));
};
}
// This example protects all routes including api/trpc routes
// Please edit this to allow other routes to be public as needed.
const isPublicRoute = createRouteMatcher([
'/share/overview/:id',
'/login(.*)?',
'/reset-password(.*)?',
'/register(.*)?',
'/sso-callback(.*)?',
'/onboarding',
]);
export default (request: NextRequest) => {
if (request.method === 'GET') {
const response = NextResponse.next();
const token = request.cookies.get('session')?.value ?? null;
if (!isPublicRoute(request) && token === null) {
return NextResponse.redirect(new URL('/login', request.url));
}
if (token !== null) {
// Only extend cookie expiration on GET requests since we can be sure
// a new session wasn't set when handling the request.
response.cookies.set('session', token, {
maxAge: COOKIE_MAX_AGE,
...COOKIE_OPTIONS,
});
}
return response;
}
const originHeader = request.headers.get('Origin');
// NOTE: You may need to use `X-Forwarded-Host` instead
const hostHeader = request.headers.get('Host');
if (originHeader === null || hostHeader === null) {
return new NextResponse(null, {
status: 403,
});
}
let origin: URL;
try {
origin = new URL(originHeader);
} catch {
return new NextResponse(null, {
status: 403,
});
}
if (origin.host !== hostHeader) {
return new NextResponse(null, {
status: 403,
});
}
return NextResponse.next();
};
export const config = {
matcher: [
'/((?!.+\\.[\\w]+$|_next).*)',
'/',
'/(api)(.*)',
'/(api|trpc)(.*)',
'/api/trpc(.*)',
],
};