mirror of
https://github.com/documenso/documenso.git
synced 2025-11-15 01:01:49 +10:00
chore: refactor sessions
This commit is contained in:
@ -21,7 +21,6 @@ export const auth = new Hono<HonoAuthContext>()
|
||||
.use(async (c, next) => {
|
||||
c.set('requestMetadata', extractRequestMetadata(c.req.raw));
|
||||
|
||||
// Todo: Maybe use auth URL.
|
||||
const validOrigin = new URL(NEXT_PUBLIC_WEBAPP_URL()).origin;
|
||||
const headerOrigin = c.req.header('Origin');
|
||||
|
||||
@ -54,9 +53,6 @@ export const auth = new Hono<HonoAuthContext>()
|
||||
* Handle errors.
|
||||
*/
|
||||
auth.onError((err, c) => {
|
||||
// Todo Remove
|
||||
console.error(`${err}`);
|
||||
|
||||
if (err instanceof HTTPException) {
|
||||
return c.json(
|
||||
{
|
||||
|
||||
@ -1,13 +1,18 @@
|
||||
import type { Context } from 'hono';
|
||||
import { deleteCookie, getSignedCookie, setSignedCookie } from 'hono/cookie';
|
||||
|
||||
import { getCookieDomain, useSecureCookies } from '@documenso/lib/constants/auth';
|
||||
import {
|
||||
formatSecureCookieName,
|
||||
getCookieDomain,
|
||||
useSecureCookies,
|
||||
} from '@documenso/lib/constants/auth';
|
||||
import { appLog } from '@documenso/lib/utils/debugger';
|
||||
import { env } from '@documenso/lib/utils/env';
|
||||
|
||||
import { generateSessionToken } from './session';
|
||||
|
||||
export const sessionCookieName = 'sessionId';
|
||||
export const sessionCookieName = formatSecureCookieName('sessionId');
|
||||
export const csrfCookieName = formatSecureCookieName('csrfToken');
|
||||
|
||||
const getAuthSecret = () => {
|
||||
const authSecret = env('NEXTAUTH_SECRET');
|
||||
@ -86,7 +91,7 @@ export const deleteSessionCookie = (c: Context) => {
|
||||
};
|
||||
|
||||
export const getCsrfCookie = async (c: Context) => {
|
||||
const csrfToken = await getSignedCookie(c, getAuthSecret(), 'csrfToken');
|
||||
const csrfToken = await getSignedCookie(c, getAuthSecret(), csrfCookieName);
|
||||
|
||||
return csrfToken || null;
|
||||
};
|
||||
@ -94,7 +99,7 @@ export const getCsrfCookie = async (c: Context) => {
|
||||
export const setCsrfCookie = async (c: Context) => {
|
||||
const csrfToken = generateSessionToken();
|
||||
|
||||
await setSignedCookie(c, 'csrfToken', csrfToken, getAuthSecret(), {
|
||||
await setSignedCookie(c, csrfCookieName, csrfToken, getAuthSecret(), {
|
||||
...sessionCookieOptions,
|
||||
|
||||
// Explicity set to undefined for session lived cookie.
|
||||
|
||||
@ -7,7 +7,23 @@ import type { SessionValidationResult } from '../session/session';
|
||||
import { validateSessionToken } from '../session/session';
|
||||
import { getSessionCookie } from '../session/session-cookies';
|
||||
|
||||
export const getSession = async (c: Context | Request): Promise<SessionValidationResult> => {
|
||||
export const getSession = async (c: Context | Request) => {
|
||||
const { session, user } = await getOptionalSession(mapRequestToContextForCookie(c));
|
||||
|
||||
if (session && user) {
|
||||
return { session, user };
|
||||
}
|
||||
|
||||
if (c instanceof Request) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
throw new AppError(AuthenticationErrorCode.Unauthorized);
|
||||
};
|
||||
|
||||
export const getOptionalSession = async (
|
||||
c: Context | Request,
|
||||
): Promise<SessionValidationResult> => {
|
||||
const sessionId = await getSessionCookie(mapRequestToContextForCookie(c));
|
||||
|
||||
if (!sessionId) {
|
||||
@ -21,20 +37,6 @@ export const getSession = async (c: Context | Request): Promise<SessionValidatio
|
||||
return await validateSessionToken(sessionId);
|
||||
};
|
||||
|
||||
export const getRequiredSession = async (c: Context | Request) => {
|
||||
const { session, user } = await getSession(mapRequestToContextForCookie(c));
|
||||
|
||||
if (session && user) {
|
||||
return { session, user };
|
||||
}
|
||||
|
||||
if (c instanceof Request) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
throw new AppError(AuthenticationErrorCode.Unauthorized);
|
||||
};
|
||||
|
||||
/**
|
||||
* Todo: Rethink, this is pretty sketchy.
|
||||
*/
|
||||
|
||||
@ -4,10 +4,6 @@ import { GoogleAuthOptions, OidcAuthOptions } from '../config';
|
||||
import { handleOAuthCallbackUrl } from '../lib/utils/handle-oauth-callback-url';
|
||||
import type { HonoAuthContext } from '../types/context';
|
||||
|
||||
// Todo: Test
|
||||
// api/auth/callback/google?
|
||||
// api/auth/callback/oidc
|
||||
|
||||
/**
|
||||
* Have to create this route instead of bundling callback with oauth routes to provide
|
||||
* backwards compatibility for self-hosters (since we used to use NextAuth).
|
||||
@ -20,7 +16,5 @@ export const callbackRoute = new Hono<HonoAuthContext>()
|
||||
|
||||
/**
|
||||
* Google callback verification.
|
||||
*
|
||||
* Todo: Double check this is the correct callback.
|
||||
*/
|
||||
.get('/google', async (c) => handleOAuthCallbackUrl({ c, clientOptions: GoogleAuthOptions }));
|
||||
|
||||
@ -27,7 +27,7 @@ import { UserSecurityAuditLogType } from '@documenso/prisma/client';
|
||||
import { AuthenticationErrorCode } from '../lib/errors/error-codes';
|
||||
import { getCsrfCookie } from '../lib/session/session-cookies';
|
||||
import { onAuthorize } from '../lib/utils/authorizer';
|
||||
import { getRequiredSession, getSession } from '../lib/utils/get-session';
|
||||
import { getSession } from '../lib/utils/get-session';
|
||||
import type { HonoAuthContext } from '../types/context';
|
||||
import {
|
||||
ZForgotPasswordSchema,
|
||||
@ -176,10 +176,6 @@ export const emailPasswordRoute = new Hono<HonoAuthContext>()
|
||||
|
||||
const session = await getSession(c);
|
||||
|
||||
if (!session.isAuthenticated) {
|
||||
throw new AppError(AuthenticationErrorCode.Unauthorized);
|
||||
}
|
||||
|
||||
await updatePassword({
|
||||
userId: session.user.id,
|
||||
password,
|
||||
@ -251,7 +247,7 @@ export const emailPasswordRoute = new Hono<HonoAuthContext>()
|
||||
* Setup two factor authentication.
|
||||
*/
|
||||
.post('/2fa/setup', async (c) => {
|
||||
const { user } = await getRequiredSession(c);
|
||||
const { user } = await getSession(c);
|
||||
|
||||
const result = await setupTwoFactorAuthentication({
|
||||
user,
|
||||
@ -277,7 +273,7 @@ export const emailPasswordRoute = new Hono<HonoAuthContext>()
|
||||
async (c) => {
|
||||
const requestMetadata = c.get('requestMetadata');
|
||||
|
||||
const { user: sessionUser } = await getRequiredSession(c);
|
||||
const { user: sessionUser } = await getSession(c);
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
@ -324,7 +320,7 @@ export const emailPasswordRoute = new Hono<HonoAuthContext>()
|
||||
async (c) => {
|
||||
const requestMetadata = c.get('requestMetadata');
|
||||
|
||||
const { user: sessionUser } = await getRequiredSession(c);
|
||||
const { user: sessionUser } = await getSession(c);
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
@ -367,7 +363,7 @@ export const emailPasswordRoute = new Hono<HonoAuthContext>()
|
||||
}),
|
||||
),
|
||||
async (c) => {
|
||||
const { user: sessionUser } = await getRequiredSession(c);
|
||||
const { user: sessionUser } = await getSession(c);
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
|
||||
@ -119,28 +119,3 @@ export const passkeyRoute = new Hono<HonoAuthContext>()
|
||||
200,
|
||||
);
|
||||
});
|
||||
|
||||
// Todo
|
||||
// .post('/register', async (c) => {
|
||||
// const { user } = await getRequiredSession(c);
|
||||
|
||||
// //
|
||||
// })
|
||||
|
||||
// .post(
|
||||
// '/pre-authenticate',
|
||||
// sValidator(
|
||||
// 'json',
|
||||
// z.object({
|
||||
// code: z.string(),
|
||||
// }),
|
||||
// ),
|
||||
// async (c) => {
|
||||
// //
|
||||
|
||||
// return c.json({
|
||||
// success: true,
|
||||
// recoveryCodes: result.recoveryCodes,
|
||||
// });
|
||||
// },
|
||||
// );
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { Hono } from 'hono';
|
||||
|
||||
import type { SessionValidationResult } from '../lib/session/session';
|
||||
import { getSession } from '../lib/utils/get-session';
|
||||
import { getOptionalSession } from '../lib/utils/get-session';
|
||||
|
||||
export const sessionRoute = new Hono().get('/session', async (c) => {
|
||||
const session: SessionValidationResult = await getSession(c);
|
||||
const session: SessionValidationResult = await getOptionalSession(c);
|
||||
|
||||
return c.json(session);
|
||||
});
|
||||
|
||||
@ -9,7 +9,7 @@ import { viewBackupCodes } from '@documenso/lib/server-only/2fa/view-backup-code
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { AuthenticationErrorCode } from '../lib/errors/error-codes';
|
||||
import { getRequiredSession } from '../lib/utils/get-session';
|
||||
import { getSession } from '../lib/utils/get-session';
|
||||
import type { HonoAuthContext } from '../types/context';
|
||||
import {
|
||||
ZDisableTwoFactorRequestSchema,
|
||||
@ -22,7 +22,7 @@ export const twoFactorRoute = new Hono<HonoAuthContext>()
|
||||
* Setup two factor authentication.
|
||||
*/
|
||||
.post('/setup', async (c) => {
|
||||
const { user } = await getRequiredSession(c);
|
||||
const { user } = await getSession(c);
|
||||
|
||||
const result = await setupTwoFactorAuthentication({
|
||||
user,
|
||||
@ -41,7 +41,7 @@ export const twoFactorRoute = new Hono<HonoAuthContext>()
|
||||
.post('/enable', sValidator('json', ZEnableTwoFactorRequestSchema), async (c) => {
|
||||
const requestMetadata = c.get('requestMetadata');
|
||||
|
||||
const { user: sessionUser } = await getRequiredSession(c);
|
||||
const { user: sessionUser } = await getSession(c);
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
@ -79,7 +79,7 @@ export const twoFactorRoute = new Hono<HonoAuthContext>()
|
||||
.post('/disable', sValidator('json', ZDisableTwoFactorRequestSchema), async (c) => {
|
||||
const requestMetadata = c.get('requestMetadata');
|
||||
|
||||
const { user: sessionUser } = await getRequiredSession(c);
|
||||
const { user: sessionUser } = await getSession(c);
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
@ -117,7 +117,7 @@ export const twoFactorRoute = new Hono<HonoAuthContext>()
|
||||
'/view-recovery-codes',
|
||||
sValidator('json', ZViewTwoFactorRecoveryCodesRequestSchema),
|
||||
async (c) => {
|
||||
const { user: sessionUser } = await getRequiredSession(c);
|
||||
const { user: sessionUser } = await getSession(c);
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
|
||||
Reference in New Issue
Block a user