mirror of
https://github.com/documenso/documenso.git
synced 2025-11-12 15:53:02 +10:00
fix: rework sessions
This commit is contained in:
@ -1,79 +1,37 @@
|
||||
import type { Context, Next } from 'hono';
|
||||
|
||||
import { extractSessionCookieFromHeaders } from '@documenso/auth/server/lib/session/session-cookies';
|
||||
import { getOptionalSession } from '@documenso/auth/server/lib/utils/get-session';
|
||||
import type { AppSession } from '@documenso/lib/client-only/providers/session';
|
||||
import { type TGetTeamByUrlResponse, getTeamByUrl } from '@documenso/lib/server-only/team/get-team';
|
||||
import { type TGetTeamsResponse, getTeams } from '@documenso/lib/server-only/team/get-teams';
|
||||
import {
|
||||
type RequestMetadata,
|
||||
extractRequestMetadata,
|
||||
} from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { AppDebugger } from '@documenso/lib/utils/debugger';
|
||||
|
||||
const debug = new AppDebugger('Middleware');
|
||||
|
||||
export type AppContext = {
|
||||
requestMetadata: RequestMetadata;
|
||||
session: AppSession | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Apply a context which can be accessed throughout the app.
|
||||
*
|
||||
* Keep this as lean as possible in terms of awaiting, because anything
|
||||
* here will increase each page load time.
|
||||
*/
|
||||
export const appContext = async (c: Context, next: Next) => {
|
||||
const initTime = Date.now();
|
||||
|
||||
const request = c.req.raw;
|
||||
const url = new URL(request.url);
|
||||
|
||||
const noSessionCookie = extractSessionCookieFromHeaders(request.headers) === null;
|
||||
|
||||
setAppContext(c, {
|
||||
requestMetadata: extractRequestMetadata(request),
|
||||
});
|
||||
|
||||
// These are non page paths like API.
|
||||
if (!isPageRequest(request) || noSessionCookie || blacklistedPathsRegex.test(url.pathname)) {
|
||||
// debug.log('Pathname ignored', url.pathname);
|
||||
|
||||
setAppContext(c, {
|
||||
requestMetadata: extractRequestMetadata(request),
|
||||
session: null,
|
||||
});
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
const splitUrl = url.pathname.replace('.data', '').split('/');
|
||||
|
||||
let team: TGetTeamByUrlResponse | null = null;
|
||||
let teams: TGetTeamsResponse = [];
|
||||
|
||||
const session = await getOptionalSession(c);
|
||||
|
||||
if (session.isAuthenticated) {
|
||||
let teamUrl = null;
|
||||
|
||||
if (splitUrl[1] === 't' && splitUrl[2]) {
|
||||
teamUrl = splitUrl[2];
|
||||
}
|
||||
|
||||
const result = await Promise.all([
|
||||
getTeams({ userId: session.user.id }),
|
||||
teamUrl ? getTeamByUrl({ userId: session.user.id, teamUrl }).catch(() => null) : null,
|
||||
]);
|
||||
|
||||
teams = result[0];
|
||||
team = result[1];
|
||||
}
|
||||
|
||||
const endTime = Date.now();
|
||||
debug.log(`Pathname accepted in ${endTime - initTime}ms`, url.pathname);
|
||||
|
||||
setAppContext(c, {
|
||||
requestMetadata: extractRequestMetadata(request),
|
||||
session: session.isAuthenticated
|
||||
? {
|
||||
session: session.session,
|
||||
user: session.user,
|
||||
currentTeam: team,
|
||||
teams,
|
||||
}
|
||||
: null,
|
||||
});
|
||||
// Add context to any pages you want here.
|
||||
|
||||
return next();
|
||||
};
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
import { getContext } from 'hono/context-storage';
|
||||
import { redirect } from 'react-router';
|
||||
import type { AppContext } from 'server/context';
|
||||
import type { HonoEnv } from 'server/router';
|
||||
|
||||
import type { AppSession } from '@documenso/lib/client-only/providers/session';
|
||||
|
||||
/**
|
||||
* Get the full context passed to the loader.
|
||||
*
|
||||
@ -14,46 +11,3 @@ export const getOptionalLoaderContext = (): AppContext => {
|
||||
const { context } = getContext<HonoEnv>().var;
|
||||
return context;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the session extracted from the app context.
|
||||
*
|
||||
* @returns The session, or null if not authenticated.
|
||||
*/
|
||||
export const getOptionalLoaderSession = (): AppSession | null => {
|
||||
const { context } = getContext<HonoEnv>().var;
|
||||
return context.session;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the session context or throws a redirect to signin if it is not present.
|
||||
*/
|
||||
export const getLoaderSession = (): AppSession => {
|
||||
const session = getOptionalLoaderSession();
|
||||
|
||||
if (!session) {
|
||||
throw redirect('/signin'); // Todo: Maybe add a redirect cookie to come back?
|
||||
}
|
||||
|
||||
return session;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the team session context or throws a redirect to signin if it is not present.
|
||||
*/
|
||||
export const getLoaderTeamSession = () => {
|
||||
const session = getOptionalLoaderSession();
|
||||
|
||||
if (!session) {
|
||||
throw redirect('/signin'); // Todo: Maybe add a redirect cookie to come back?
|
||||
}
|
||||
|
||||
if (!session.currentTeam) {
|
||||
throw new Response(null, { status: 404 }); // Todo: Test that 404 page shows up.
|
||||
}
|
||||
|
||||
return {
|
||||
...session,
|
||||
currentTeam: session.currentTeam,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user