fix: (again) login with http not working after having already logged in with https #398

Massimo Melina committed Dec 16, 2023 at 23:58 UTC 91423106e3fb16c28d56b1aa8b99c696905ffbe3
2 files changed +15 -9
src/index.ts
+4 -2
@@ -23,6 +23,7 @@ import { selfCheckMiddleware } from './selfCheck'
23 import { acmeMiddleware } from './acme'
24 import './geo'
25 import { geoFilter } from './geo'
26 +import events from './events'
27
28 ok(_.intersection(Object.keys(frontEndApis), Object.keys(adminApis)).length === 0) // they share same endpoints, don't clash
29
@@ -30,9 +31,9 @@ process.title = 'HFS ' + VERSION
31 const keys = process.env.COOKIE_SIGN_KEYS?.split(',')
32 || [randomId(30)] // randomness at start gives some extra security, btu also invalidates existing sessions
33 export const app = new Koa({ keys })
33 -app.use(someSecurity)
34 +app.use(sessionMiddleware)
35 + .use(someSecurity)
36 .use(acmeMiddleware)
35 - .use(sessionMiddleware)
37 .use(prepareState)
38 .use(geoFilter)
39 .use(selfCheckMiddleware)
@@ -45,6 +46,7 @@ app.use(someSecurity)
46 .use(mount(API_URI, apiMiddleware({ ...frontEndApis, ...adminApis })))
47 .use(serveGuiAndSharedFiles)
48 .on('error', errorHandler)
49 +events.emit('app', app)
50
51 function errorHandler(err:Error & { code:string, path:string }) {
52 const { code } = err
src/middlewares.ts
+11 -7
@@ -30,6 +30,7 @@ import { defineConfig } from './config'
30 import { sendErrorPage } from './errorPages'
31 import session from 'koa-session'
32 import { app } from './index'
33 +import events from './events'
34
35 const forceHttps = defineConfig('force_https', true)
36 const ignoreProxies = defineConfig('ignore_proxies', false)
@@ -251,10 +252,13 @@ export const paramsDecoder: Koa.Middleware = async (ctx, next) => {
252 await next()
253 }
254
254 -export const sessionMiddleware: Koa.Middleware = (ctx, next) =>
255 - session({
256 - key: 'hfs_$id' + (ctx.secure ? '' : '_http'), // once https cookie is created, http cannot
257 - signed: true,
258 - rolling: true,
259 - sameSite: 'lax'
260 - }, app)(ctx, next)
\ No newline at end of file
255 +// once https cookie is created, http cannot do the same. The solution is to use 2 different cookies.
256 +// But koa-session doesn't support 2 cookies, so I made this hacky solution: keep track of the options object, to modify the key at run-time.
257 +let internalSessionMw: any
258 +let options: any
259 +events.on('app', () => // wait for app to be defined
260 + internalSessionMw = session(options = { signed: true, rolling: true, sameSite: 'lax' } as const, app) )
261 +export const sessionMiddleware: Koa.Middleware = (ctx, next) => {
262 + options.key = 'hfs_' + ctx.protocol
263 + return internalSessionMw(ctx, next)
264 +}
\ No newline at end of file