diff --git a/server/auth/sessions/app.ts b/server/auth/sessions/app.ts index 62850453..bdd593f7 100644 --- a/server/auth/sessions/app.ts +++ b/server/auth/sessions/app.ts @@ -129,18 +129,19 @@ export async function invalidateAllSessions(userId: string): Promise { export function serializeSessionCookie( token: string, - isSecure: boolean + isSecure: boolean, + expiresAt: Date ): string { if (isSecure) { - return `${SESSION_COOKIE_NAME}=${token}; HttpOnly; SameSite=Strict; Max-Age=${SESSION_COOKIE_EXPIRES / 1000}; Path=/; Secure; Domain=${COOKIE_DOMAIN}`; + return `${SESSION_COOKIE_NAME}=${token}; HttpOnly; SameSite=Lax; Expires=${expiresAt.toUTCString()}; Path=/; Secure; Domain=${COOKIE_DOMAIN}`; } else { - return `${SESSION_COOKIE_NAME}=${token}; HttpOnly; SameSite=Lax; Max-Age=${SESSION_COOKIE_EXPIRES}; Path=/;`; + return `${SESSION_COOKIE_NAME}=${token}; HttpOnly; SameSite=Lax; Expires=${expiresAt.toUTCString()}; Path=/;`; } } export function createBlankSessionTokenCookie(isSecure: boolean): string { if (isSecure) { - return `${SESSION_COOKIE_NAME}=; HttpOnly; SameSite=Strict; Max-Age=0; Path=/; Secure; Domain=${COOKIE_DOMAIN}`; + return `${SESSION_COOKIE_NAME}=; HttpOnly; SameSite=Lax; Max-Age=0; Path=/; Secure; Domain=${COOKIE_DOMAIN}`; } else { return `${SESSION_COOKIE_NAME}=; HttpOnly; SameSite=Lax; Max-Age=0; Path=/;`; } diff --git a/server/auth/sessions/resource.ts b/server/auth/sessions/resource.ts index 3336ebde..65f4674d 100644 --- a/server/auth/sessions/resource.ts +++ b/server/auth/sessions/resource.ts @@ -167,12 +167,19 @@ export function serializeResourceSessionCookie( cookieName: string, domain: string, token: string, - isHttp: boolean = false + isHttp: boolean = false, + expiresAt?: Date ): string { if (!isHttp) { - return `${cookieName}_s=${token}; HttpOnly; SameSite=Lax; Max-Age=${SESSION_COOKIE_EXPIRES / 1000}; Path=/; Secure; Domain=${"." + domain}`; + if (expiresAt === undefined) { + return `${cookieName}_s=${token}; HttpOnly; SameSite=Lax; Path=/; Secure; Domain=${"." + domain}`; + } + return `${cookieName}_s=${token}; HttpOnly; SameSite=Lax; Expires=${expiresAt.toUTCString()}; Path=/; Secure; Domain=${"." + domain}`; } else { - return `${cookieName}=${token}; HttpOnly; SameSite=Lax; Max-Age=${SESSION_COOKIE_EXPIRES / 1000}; Path=/; Domain=${"." + domain}`; + if (expiresAt === undefined) { + return `${cookieName}=${token}; HttpOnly; SameSite=Lax; Path=/; Domain=${"." + domain}`; + } + return `${cookieName}=${token}; HttpOnly; SameSite=Lax; Expires=${expiresAt.toUTCString()}; Path=/; Domain=${"." + domain}`; } } diff --git a/server/routers/auth/login.ts b/server/routers/auth/login.ts index 09bd9661..8ed49cf0 100644 --- a/server/routers/auth/login.ts +++ b/server/routers/auth/login.ts @@ -137,9 +137,13 @@ export async function login( } const token = generateSessionToken(); - await createSession(token, existingUser.userId); + const sess = await createSession(token, existingUser.userId); const isSecure = req.protocol === "https"; - const cookie = serializeSessionCookie(token, isSecure); + const cookie = serializeSessionCookie( + token, + isSecure, + new Date(sess.expiresAt) + ); res.appendHeader("Set-Cookie", cookie); diff --git a/server/routers/auth/signup.ts b/server/routers/auth/signup.ts index 4bb5394e..cb099162 100644 --- a/server/routers/auth/signup.ts +++ b/server/routers/auth/signup.ts @@ -170,9 +170,13 @@ export async function signup( // }); const token = generateSessionToken(); - await createSession(token, userId); + const sess = await createSession(token, userId); const isSecure = req.protocol === "https"; - const cookie = serializeSessionCookie(token, isSecure); + const cookie = serializeSessionCookie( + token, + isSecure, + new Date(sess.expiresAt) + ); res.appendHeader("Set-Cookie", cookie); if (config.getRawConfig().flags?.require_email_verification) { diff --git a/server/routers/badger/exchangeSession.ts b/server/routers/badger/exchangeSession.ts index 093dfbb9..ad8eb976 100644 --- a/server/routers/badger/exchangeSession.ts +++ b/server/routers/badger/exchangeSession.ts @@ -102,6 +102,8 @@ export async function exchangeSession( const token = generateSessionToken(); + let expiresAt: number | null = null; + if (requestSession.userSessionId) { const [res] = await db .select() @@ -118,6 +120,7 @@ export async function exchangeSession( expiresAt: res.expiresAt, sessionLength: SESSION_COOKIE_EXPIRES }); + expiresAt = res.expiresAt; } } else if (requestSession.accessTokenId) { const [res] = await db @@ -140,8 +143,12 @@ export async function exchangeSession( expiresAt: res.expiresAt, sessionLength: res.sessionLength }); + expiresAt = res.expiresAt; } } else { + const expires = new Date( + Date.now() + SESSION_COOKIE_EXPIRES + ).getTime(); await createResourceSession({ token, resourceId: resource.resourceId, @@ -152,11 +159,10 @@ export async function exchangeSession( whitelistId: requestSession.whitelistId, accessTokenId: requestSession.accessTokenId, doNotExtend: false, - expiresAt: new Date( - Date.now() + SESSION_COOKIE_EXPIRES - ).getTime(), + expiresAt: expires, sessionLength: RESOURCE_SESSION_COOKIE_EXPIRES }); + expiresAt = expires; } const cookieName = `${config.getRawConfig().server.session_cookie_name}`; @@ -164,7 +170,8 @@ export async function exchangeSession( cookieName, resource.fullDomain!, token, - !resource.ssl + !resource.ssl, + expiresAt ? new Date(expiresAt) : undefined ); logger.debug(JSON.stringify("Exchange cookie: " + cookie)); diff --git a/server/routers/badger/verifySession.ts b/server/routers/badger/verifySession.ts index 86ba0629..35617f37 100644 --- a/server/routers/badger/verifySession.ts +++ b/server/routers/badger/verifySession.ts @@ -384,7 +384,7 @@ async function createAccessTokenSession( tokenItem: ResourceAccessToken ) { const token = generateSessionToken(); - await createResourceSession({ + const sess = await createResourceSession({ resourceId: resource.resourceId, token, accessTokenId: tokenItem.accessTokenId, @@ -397,7 +397,8 @@ async function createAccessTokenSession( cookieName, resource.fullDomain!, token, - !resource.ssl + !resource.ssl, + new Date(sess.expiresAt) ); res.appendHeader("Set-Cookie", cookie); logger.debug("Access token is valid, creating new session"); diff --git a/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx b/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx index 74e2cf8f..ea76ddc6 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/connectivity/page.tsx @@ -39,6 +39,7 @@ import { import { Table, TableBody, + TableCaption, TableCell, TableContainer, TableHead, @@ -562,67 +563,65 @@ export default function ReverseProxyTargets(props: { )} /> - - - - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => ( - - {header.isPlaceholder - ? null - : flexRender( - header.column - .columnDef.header, - header.getContext() - )} - +
+ + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef + .header, + header.getContext() + )} + + ))} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + ))} - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map((row) => ( - - {row - .getVisibleCells() - .map((cell) => ( - - {flexRender( - cell.column - .columnDef.cell, - cell.getContext() - )} - - ))} - - )) - ) : ( - - - No targets. Add a target using the - form. - - - )} - -
-
-

- Adding more than one target above will enable load - balancing. -

+ )) + ) : ( + + + No targets. Add a target using the form. + + + )} + + + Adding more than one target above will enable load + balancing. + +