diff --git a/src/context.ts b/src/context.ts index c31a751..c67d71e 100644 --- a/src/context.ts +++ b/src/context.ts @@ -27,6 +27,18 @@ export class ContextSession { this.store = this.opts.ContextStore ? new this.opts.ContextStore(ctx) : this.opts.store; } + /** + * modify cookie options based on request's domain + */ + modifyOptsForRequest(options: SessionOptions) { + const opts = { ...options }; + const ctx = this.ctx; + if (typeof opts.domain === 'function') { + opts.domain = opts.domain(ctx, ctx.session); + } + return opts; + } + /** * internal logic of `ctx.session` * @return {Session} session object @@ -128,7 +140,7 @@ export class ContextSession { debug('decode %j error: %s', cookie, err); if (err instanceof Error && !(err instanceof SyntaxError)) { // clean this cookie to ensure next request won't throw again - ctx.cookies.set(opts.key, '', opts); + ctx.cookies.set(opts.key, '', this.modifyOptsForRequest(opts)); // `ctx.onerror` will unset all headers, and set those specified in err Reflect.set(err, 'headers', { 'set-cookie': ctx.response.get('set-cookie'), @@ -291,7 +303,7 @@ export class ContextSession { const opts = { ...this.opts, expires: COOKIE_EXP_DATE, - maxAge: false, + maxAge: 0, }; const ctx = this.ctx; const key = opts.key; @@ -300,7 +312,7 @@ export class ContextSession { if (externalKey) { await this.store!.destroy(externalKey, { ctx }); } - ctx.cookies.set(key, '', opts); + ctx.cookies.set(key, '', this.modifyOptsForRequest(opts)); } /** @@ -340,7 +352,7 @@ export class ContextSession { if (opts.externalKey) { opts.externalKey.set(this.ctx, externalKey); } else { - this.ctx.cookies.set(key, externalKey, opts); + this.ctx.cookies.set(key, externalKey, this.modifyOptsForRequest(opts)); } return; } @@ -350,6 +362,6 @@ export class ContextSession { const base64String = opts.encode(sessionData); debug('save session data json base64 format: %s to cookie key: %s with options: %j', base64String, key, opts); - this.ctx.cookies.set(key, base64String, opts); + this.ctx.cookies.set(key, base64String, this.modifyOptsForRequest(opts)); } } diff --git a/src/index.ts b/src/index.ts index 74ec11a..d6a4c9f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -157,6 +157,11 @@ export const SessionOptions = z.object({ .args(z.any(), z.any()) .returns(z.void()) .optional(), + /** + * Restrict the cookie domain with either a static string or a function that + * return a string. + */ + domain: z.union([ z.string(), z.function().args(z.any(), z.any()).returns(z.string()) ]).optional(), }); const DEFAULT_SESSION_OPTIONS = SessionOptions.parse({}); diff --git a/src/util.ts b/src/util.ts index 39f0806..321d272 100644 --- a/src/util.ts +++ b/src/util.ts @@ -24,3 +24,4 @@ export default { CookieDateEpoch: 'Thu, 01 Jan 1970 00:00:00 GMT', }; + diff --git a/tsconfig.json b/tsconfig.json index ff41b73..f24859b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,6 @@ "noImplicitAny": true, "target": "ES2022", "module": "NodeNext", - "moduleResolution": "NodeNext" + "moduleResolution": "NodeNext", } }