insite-cookie 2.0.0 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bun.lockb CHANGED
Binary file
@@ -1,7 +1,5 @@
1
- import type { WithUser } from "insite-subscriptions-server/ws";
2
- import type { InSiteWebSocketServerClient } from "insite-ws/server";
3
1
  import type { AbilitiesSchema } from "insite-users-server";
4
- import type { UsersServer } from "insite-users-server-ws";
2
+ import type { UsersServer, WSSCWithUser } from "insite-users-server-ws";
5
3
  import { parseCookie } from "./parse";
6
4
  import type { Cookie, CookieOptions } from "./types";
7
5
  export type Options<AS extends AbilitiesSchema> = {
@@ -15,8 +13,8 @@ export declare class CookieSetter<AS extends AbilitiesSchema> {
15
13
  usersServer: UsersServer<AS>;
16
14
  domain: string | undefined;
17
15
  maxAge: number;
18
- set(wssc: WithUser<InSiteWebSocketServerClient, AS>, cookie: Cookie, options: CookieOptions): void;
19
- unset(wssc: WithUser<InSiteWebSocketServerClient, AS>, names: string[]): void;
16
+ set(wssc: WSSCWithUser<AS>, cookie: Cookie, options: CookieOptions): void;
17
+ unset(wssc: WSSCWithUser<AS>, names: string[]): void;
20
18
  static parse: typeof parseCookie;
21
19
  }
22
20
  //# sourceMappingURL=Setter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Setter.d.ts","sourceRoot":"","sources":["../../src/server/Setter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAKrD,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,eAAe,IAAI;IACjD,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,qBAAa,YAAY,CAAC,EAAE,SAAS,eAAe;;gBACvC,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC;IAYxD,WAAW,kBAAC;IACZ,MAAM,qBAAC;IACP,MAAM,SAAC;IAEP,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,2BAA2B,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa;IAU3F,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,2BAA2B,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;IAoCtE,MAAM,CAAC,KAAK,qBAAe;CAE3B"}
1
+ {"version":3,"file":"Setter.d.ts","sourceRoot":"","sources":["../../src/server/Setter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAExE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAKrD,MAAM,MAAM,OAAO,CAAC,EAAE,SAAS,eAAe,IAAI;IACjD,WAAW,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAGF,qBAAa,YAAY,CAAC,EAAE,SAAS,eAAe;;gBACvC,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC;IAYxD,WAAW,kBAAC;IACZ,MAAM,qBAAC;IACP,MAAM,SAAC;IAEP,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa;IAUlE,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;IAoC7C,MAAM,CAAC,KAAK,qBAAe;CAE3B"}
@@ -1,2 +1,2 @@
1
- import{getWithTimeout as f}from"@nesvet/n";import{InSiteServerMiddleware as d}from"insite-http";var n=new Map;var S=class r extends d{constructor(e={}){super();let{requestRegExp:s=/^\/cookie\/?\?/}=e;this.listeners={GET:[[s,this.#e]]}}#e=(e,s)=>{let[,t]=e.url.split("?");return t&&n.has(t)?s.writeHead(200,{"Content-Type":"text/plain; charset=utf-8","Set-Cookie":r.cookify(...f(n,t))}).end():!1};static make({name:e,value:s,maxAge:t,expiresAt:o,domain:a,path:m="/",secure:k=!0,httpOnly:l=!0,sameSite:u="Strict"}){let i=[`${e}=${s}`];return t!==void 0?i.push(`Max-Age=${t}`):o&&i.push(`Max-Age=${Math.round((o.getTime()-Date.now())/1e3)}`),a&&i.push(`Domain=${a}`),m&&i.push(`Path=${m}`),k&&i.push("Secure"),l&&i.push("HttpOnly"),u&&i.push(`SameSite=${u}`),i.join("; ")}static cookify(e,s){return Object.entries(e).map(([t,o])=>this.make({name:t,value:o,...s}))}};function p(r){return r?r.split(/;\s*/).reduce((e,s)=>{let[t,o]=s.split(/=/);try{e[t]=JSON.parse(o)}catch{e[t]=o}return e},{}):{}}import g from"node:crypto";import{random as C,setWithTimeout as y}from"@nesvet/n";var h={set:"~setcookie"};var x=2e3,c=class{constructor({usersServer:e,domain:s,maxAge:t}){this.usersServer=e,this.domain=s??process.env.INSITE_HOST,this.maxAge=t??this.usersServer.users.sessions.collection.expireAfterSeconds,this.usersServer.wss.on("client-connect",this.#t),this.usersServer.wss.on("client-session",this.#s)}#e=new WeakMap;usersServer;domain;maxAge;set(e,s,t){let o=`${Math.round(performance.now()*Number.MAX_SAFE_INTEGER).toString(36)}$${g.randomBytes(C(4,8)).toString("hex")}`;y(n,o,[s,t],x),e.sendMessage(h.set,o)}unset(e,s){this.set(e,s.reduce((t,o)=>(t[o]="",t),{}),{maxAge:0})}#t=(e,s)=>{if(this.#e.set(e,null),s.headers.cookie){let{sessionId:t=null}=p(s.headers.cookie);this.#e.set(e,t),t&&this.usersServer.setSession(e,t,!0)}};#s=e=>{this.#e.get(e)!==e.session?._id&&(this.#e.set(e,e.session?._id??null),e.isOpen&&e.session?this.set(e,{sessionId:e.session._id},{domain:this.domain,maxAge:this.maxAge}):this.unset(e,["sessionId"]))};static parse=p};export{c as CookieSetter,S as InSiteCookieMiddleware,p as parseCookie};
1
+ import{getWithTimeout as f}from"@nesvet/n";import{InSiteServerMiddleware as l}from"insite-http";var n=new Map;var u=class r extends l{constructor(e={}){super();let{requestRegExp:s=/^\/cookie\/?\?/}=e;this.listeners={GET:[[s,this.#e]]}}#e=(e,s)=>{let[,t]=e.url.split("?");return t&&n.has(t)?s.writeHead(200,{"Content-Type":"text/plain; charset=utf-8","Set-Cookie":r.cookify(...f(n,t))}).end():!1};static make({name:e,value:s,maxAge:t,expiresAt:o,domain:a,path:m="/",secure:k=!0,httpOnly:d=!0,sameSite:h="Strict"}){let i=[`${e}=${s}`];return t!==void 0?i.push(`Max-Age=${t}`):o&&i.push(`Max-Age=${Math.round((o.getTime()-Date.now())/1e3)}`),a&&i.push(`Domain=${a}`),m&&i.push(`Path=${m}`),k&&i.push("Secure"),d&&i.push("HttpOnly"),h&&i.push(`SameSite=${h}`),i.join("; ")}static cookify(e,s){return Object.entries(e).map(([t,o])=>this.make({name:t,value:o,...s}))}};function p(r){return r?r.split(/;\s*/).reduce((e,s)=>{let[t,o]=s.split(/=/);try{e[t]=JSON.parse(o)}catch{e[t]=o}return e},{}):{}}import g from"node:crypto";import{random as C,setWithTimeout as x}from"@nesvet/n";var S={set:"~setcookie"};var y=2e3,c=class{constructor({usersServer:e,domain:s,maxAge:t}){this.usersServer=e,this.domain=s??process.env.INSITE_HOST,this.maxAge=t??this.usersServer.users.sessions.collection.expireAfterSeconds,this.usersServer.wss.on("client-connect",this.#t),this.usersServer.wss.on("client-session",this.#s)}#e=new WeakMap;usersServer;domain;maxAge;set(e,s,t){let o=`${Math.round(performance.now()*Number.MAX_SAFE_INTEGER).toString(36)}$${g.randomBytes(C(4,8)).toString("hex")}`;x(n,o,[s,t],y),e.sendMessage(S.set,o)}unset(e,s){this.set(e,s.reduce((t,o)=>(t[o]="",t),{}),{maxAge:0})}#t=(e,s)=>{if(this.#e.set(e,null),s.headers.cookie){let{sessionId:t=null}=p(s.headers.cookie);this.#e.set(e,t),t&&this.usersServer.setSession(e,t,!0)}};#s=e=>{this.#e.get(e)!==e.session?._id&&(this.#e.set(e,e.session?._id??null),e.isOpen&&e.session?this.set(e,{sessionId:e.session._id},{domain:this.domain,maxAge:this.maxAge}):this.unset(e,["sessionId"]))};static parse=p};export{c as CookieSetter,u as InSiteCookieMiddleware,p as parseCookie};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/server/Middleware.ts", "../../src/server/tokenMap.ts", "../../src/server/parse.ts", "../../src/server/Setter.ts", "../../src/common.ts"],
4
- "sourcesContent": ["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { getWithTimeout } from \"@nesvet/n\";\nimport { InSiteServerMiddleware } from \"insite-http\";\nimport { tokenMap } from \"./tokenMap\";\nimport type { Cookie, CookieOptions } from \"./types\";\n\n\ntype Options = {\n\trequestRegExp?: RegExp;\n};\n\nexport type { Options as CookieMiddlewareOptions };\n\ntype MakeArg = {\n\tname: keyof Cookie;\n\tvalue: Cookie[keyof Cookie];\n} & CookieOptions;\n\n\nexport class InSiteCookieMiddleware extends InSiteServerMiddleware {\n\tconstructor(options: Options = {}) {\n\t\tsuper();\n\t\t\n\t\tconst {\n\t\t\trequestRegExp = /^\\/cookie\\/?\\?/\n\t\t} = options;\n\t\t\n\t\tthis.listeners = { GET: [\n\t\t\t[ requestRegExp, this.#handler ]\n\t\t] };\n\t\t\n\t}\n\t\n\t#handler = (request: IncomingMessage, response: ServerResponse) => {\n\t\tconst [ , token ] = request.url!.split(\"?\");\n\t\t\n\t\tif (token && tokenMap.has(token))\n\t\t\treturn response.writeHead(200, {\n\t\t\t\t\"Content-Type\": \"text/plain; charset=utf-8\",\n\t\t\t\t\"Set-Cookie\": InSiteCookieMiddleware.cookify(...getWithTimeout(tokenMap, token)!)\n\t\t\t}).end();\n\t\t\n\t\t\n\t\treturn false;\n\t};\n\t\n\t\n\tstatic make({ name, value, maxAge, expiresAt, domain, path = \"/\", secure = true, httpOnly = true, sameSite = \"Strict\" }: MakeArg) {\n\t\tconst cookie = [ `${name}=${value}` ];\n\t\t\n\t\tif (maxAge !== undefined)\n\t\t\tcookie.push(`Max-Age=${maxAge}`);\n\t\telse if (expiresAt)\n\t\t\tcookie.push(`Max-Age=${Math.round((expiresAt.getTime() - Date.now()) / 1000)}`);\n\t\t\n\t\tif (domain)\n\t\t\tcookie.push(`Domain=${domain}`);\n\t\t\n\t\tif (path)\n\t\t\tcookie.push(`Path=${path}`);\n\t\t\n\t\tif (secure)\n\t\t\tcookie.push(\"Secure\");\n\t\t\n\t\tif (httpOnly)\n\t\t\tcookie.push(\"HttpOnly\");\n\t\t\n\t\tif (sameSite)\n\t\t\tcookie.push(`SameSite=${sameSite}`);\n\t\t\n\t\treturn cookie.join(\"; \");\n\t}\n\t\n\tstatic cookify(cookie: Cookie, options: CookieOptions) {\n\t\treturn Object.entries(cookie).map(([ name, value ]) => this.make({ name, value, ...options }));\n\t}\n\t\n}\n", "import type { Cookie, CookieOptions } from \"./types\";\n\n\nexport const tokenMap = new Map<string, [ cookie: Cookie, options: CookieOptions ]>();\n", "export function parseCookie(cookie: string) {\n\treturn cookie ? cookie.split(/;\\s*/).reduce((object, keyEqValue) => {\n\t\tconst [ key, value ] = keyEqValue.split(/=/);\n\t\t\n\t\ttry {\n\t\t\tobject[key] = JSON.parse(value);\n\t\t} catch {\n\t\t\tobject[key] = value;\n\t\t}\n\t\t\n\t\treturn object;\n\t}, {} as Record<string, unknown>) : {};\n}\n", "import crypto from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport type { WithUser } from \"insite-subscriptions-server/ws\";\nimport type { InSiteWebSocketServerClient } from \"insite-ws/server\";\nimport { random, setWithTimeout } from \"@nesvet/n\";\nimport type { AbilitiesSchema } from \"insite-users-server\";\nimport type { UsersServer } from \"insite-users-server-ws\";\nimport { headers } from \"../common\";\nimport { parseCookie } from \"./parse\";\nimport { tokenMap } from \"./tokenMap\";\nimport type { Cookie, CookieOptions } from \"./types\";\n\n\nconst cookieTokenTimeout = 2000;\n\nexport type Options<AS extends AbilitiesSchema> = {\n\tusersServer: UsersServer<AS>;\n\tdomain?: string;\n\tmaxAge?: number;\n};\n\n\nexport class CookieSetter<AS extends AbilitiesSchema> {\n\tconstructor({ usersServer, domain, maxAge }: Options<AS>) {\n\t\tthis.usersServer = usersServer;\n\t\tthis.domain = domain ?? process.env.INSITE_HOST;\n\t\tthis.maxAge = maxAge ?? this.usersServer.users.sessions.collection.expireAfterSeconds;\n\t\t\n\t\tthis.usersServer.wss.on(\"client-connect\", this.#handleClientConnect);\n\t\tthis.usersServer.wss.on(\"client-session\", this.#handleClientSession);\n\t\t\n\t}\n\t\n\t#wsSessionIdMap = new WeakMap<WithUser<InSiteWebSocketServerClient, AS>, null | string>();\n\t\n\tusersServer;\n\tdomain;\n\tmaxAge;\n\t\n\tset(wssc: WithUser<InSiteWebSocketServerClient, AS>, cookie: Cookie, options: CookieOptions) {\n\t\t\n\t\tconst token = `${Math.round(performance.now() * Number.MAX_SAFE_INTEGER).toString(36)}$${crypto.randomBytes(random(4, 8)).toString(\"hex\")}`;\n\t\t\n\t\tsetWithTimeout(tokenMap, token, [ cookie, options ], cookieTokenTimeout);\n\t\t\n\t\twssc.sendMessage(headers.set, token);\n\t\t\n\t}\n\t\n\tunset(wssc: WithUser<InSiteWebSocketServerClient, AS>, names: string[]) {\n\t\tthis.set(wssc, names.reduce((cookie, name) => {\n\t\t\tcookie[name] = \"\";\n\t\t\t\n\t\t\treturn cookie;\n\t\t}, {} as Cookie), { maxAge: 0 });\n\t\t\n\t}\n\t\n\t#handleClientConnect = (wssc: WithUser<InSiteWebSocketServerClient, AS>, request: IncomingMessage) => {\n\t\tthis.#wsSessionIdMap.set(wssc, null);\n\t\t\n\t\tif (request.headers.cookie) {\n\t\t\tconst { sessionId = null } = parseCookie(request.headers.cookie) as { sessionId: null | string };\n\t\t\t\n\t\t\tthis.#wsSessionIdMap.set(wssc, sessionId);\n\t\t\t\n\t\t\tif (sessionId)\n\t\t\t\tthis.usersServer.setSession(wssc, sessionId, true);\n\t\t}\n\t\t\n\t};\n\t\n\t#handleClientSession = (wssc: WithUser<InSiteWebSocketServerClient, AS>) => {\n\t\tif (this.#wsSessionIdMap.get(wssc) !== wssc.session?._id) {\n\t\t\tthis.#wsSessionIdMap.set(wssc, wssc.session?._id ?? null);\n\t\t\t\n\t\t\tif (wssc.isOpen && wssc.session)\n\t\t\t\tthis.set(wssc, { sessionId: wssc.session._id }, { domain: this.domain, maxAge: this.maxAge });\n\t\t\telse\n\t\t\t\tthis.unset(wssc, [ \"sessionId\" ]);\n\t\t}\n\t\t\n\t};\n\t\n\t\n\tstatic parse = parseCookie;\n\t\n}\n", "export const headers = {\n\tset: \"~setcookie\"\n};\n\nexport type Method = \"GET\" | \"POST\";\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { getWithTimeout } from \"@nesvet/n\";\nimport { InSiteServerMiddleware } from \"insite-http\";\nimport { tokenMap } from \"./tokenMap\";\nimport type { Cookie, CookieOptions } from \"./types\";\n\n\ntype Options = {\n\trequestRegExp?: RegExp;\n};\n\nexport type { Options as CookieMiddlewareOptions };\n\ntype MakeArg = {\n\tname: keyof Cookie;\n\tvalue: Cookie[keyof Cookie];\n} & CookieOptions;\n\n\nexport class InSiteCookieMiddleware extends InSiteServerMiddleware {\n\tconstructor(options: Options = {}) {\n\t\tsuper();\n\t\t\n\t\tconst {\n\t\t\trequestRegExp = /^\\/cookie\\/?\\?/\n\t\t} = options;\n\t\t\n\t\tthis.listeners = { GET: [\n\t\t\t[ requestRegExp, this.#handler ]\n\t\t] };\n\t\t\n\t}\n\t\n\t#handler = (request: IncomingMessage, response: ServerResponse) => {\n\t\tconst [ , token ] = request.url!.split(\"?\");\n\t\t\n\t\tif (token && tokenMap.has(token))\n\t\t\treturn response.writeHead(200, {\n\t\t\t\t\"Content-Type\": \"text/plain; charset=utf-8\",\n\t\t\t\t\"Set-Cookie\": InSiteCookieMiddleware.cookify(...getWithTimeout(tokenMap, token)!)\n\t\t\t}).end();\n\t\t\n\t\t\n\t\treturn false;\n\t};\n\t\n\t\n\tstatic make({ name, value, maxAge, expiresAt, domain, path = \"/\", secure = true, httpOnly = true, sameSite = \"Strict\" }: MakeArg) {\n\t\tconst cookie = [ `${name}=${value}` ];\n\t\t\n\t\tif (maxAge !== undefined)\n\t\t\tcookie.push(`Max-Age=${maxAge}`);\n\t\telse if (expiresAt)\n\t\t\tcookie.push(`Max-Age=${Math.round((expiresAt.getTime() - Date.now()) / 1000)}`);\n\t\t\n\t\tif (domain)\n\t\t\tcookie.push(`Domain=${domain}`);\n\t\t\n\t\tif (path)\n\t\t\tcookie.push(`Path=${path}`);\n\t\t\n\t\tif (secure)\n\t\t\tcookie.push(\"Secure\");\n\t\t\n\t\tif (httpOnly)\n\t\t\tcookie.push(\"HttpOnly\");\n\t\t\n\t\tif (sameSite)\n\t\t\tcookie.push(`SameSite=${sameSite}`);\n\t\t\n\t\treturn cookie.join(\"; \");\n\t}\n\t\n\tstatic cookify(cookie: Cookie, options: CookieOptions) {\n\t\treturn Object.entries(cookie).map(([ name, value ]) => this.make({ name, value, ...options }));\n\t}\n\t\n}\n", "import type { Cookie, CookieOptions } from \"./types\";\n\n\nexport const tokenMap = new Map<string, [ cookie: Cookie, options: CookieOptions ]>();\n", "export function parseCookie(cookie: string) {\n\treturn cookie ? cookie.split(/;\\s*/).reduce((object, keyEqValue) => {\n\t\tconst [ key, value ] = keyEqValue.split(/=/);\n\t\t\n\t\ttry {\n\t\t\tobject[key] = JSON.parse(value);\n\t\t} catch {\n\t\t\tobject[key] = value;\n\t\t}\n\t\t\n\t\treturn object;\n\t}, {} as Record<string, unknown>) : {};\n}\n", "import crypto from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport { random, setWithTimeout } from \"@nesvet/n\";\nimport type { AbilitiesSchema } from \"insite-users-server\";\nimport type { UsersServer, WSSCWithUser } from \"insite-users-server-ws\";\nimport { headers } from \"../common\";\nimport { parseCookie } from \"./parse\";\nimport { tokenMap } from \"./tokenMap\";\nimport type { Cookie, CookieOptions } from \"./types\";\n\n\nconst cookieTokenTimeout = 2000;\n\nexport type Options<AS extends AbilitiesSchema> = {\n\tusersServer: UsersServer<AS>;\n\tdomain?: string;\n\tmaxAge?: number;\n};\n\n\nexport class CookieSetter<AS extends AbilitiesSchema> {\n\tconstructor({ usersServer, domain, maxAge }: Options<AS>) {\n\t\tthis.usersServer = usersServer;\n\t\tthis.domain = domain ?? process.env.INSITE_HOST;\n\t\tthis.maxAge = maxAge ?? this.usersServer.users.sessions.collection.expireAfterSeconds;\n\t\t\n\t\tthis.usersServer.wss.on(\"client-connect\", this.#handleClientConnect);\n\t\tthis.usersServer.wss.on(\"client-session\", this.#handleClientSession);\n\t\t\n\t}\n\t\n\t#wsSessionIdMap = new WeakMap<WSSCWithUser<AS>, null | string>();\n\t\n\tusersServer;\n\tdomain;\n\tmaxAge;\n\t\n\tset(wssc: WSSCWithUser<AS>, cookie: Cookie, options: CookieOptions) {\n\t\t\n\t\tconst token = `${Math.round(performance.now() * Number.MAX_SAFE_INTEGER).toString(36)}$${crypto.randomBytes(random(4, 8)).toString(\"hex\")}`;\n\t\t\n\t\tsetWithTimeout(tokenMap, token, [ cookie, options ], cookieTokenTimeout);\n\t\t\n\t\twssc.sendMessage(headers.set, token);\n\t\t\n\t}\n\t\n\tunset(wssc: WSSCWithUser<AS>, names: string[]) {\n\t\tthis.set(wssc, names.reduce((cookie, name) => {\n\t\t\tcookie[name] = \"\";\n\t\t\t\n\t\t\treturn cookie;\n\t\t}, {} as Cookie), { maxAge: 0 });\n\t\t\n\t}\n\t\n\t#handleClientConnect = (wssc: WSSCWithUser<AS>, request: IncomingMessage) => {\n\t\tthis.#wsSessionIdMap.set(wssc, null);\n\t\t\n\t\tif (request.headers.cookie) {\n\t\t\tconst { sessionId = null } = parseCookie(request.headers.cookie) as { sessionId: null | string };\n\t\t\t\n\t\t\tthis.#wsSessionIdMap.set(wssc, sessionId);\n\t\t\t\n\t\t\tif (sessionId)\n\t\t\t\tthis.usersServer.setSession(wssc, sessionId, true);\n\t\t}\n\t\t\n\t};\n\t\n\t#handleClientSession = (wssc: WSSCWithUser<AS>) => {\n\t\tif (this.#wsSessionIdMap.get(wssc) !== wssc.session?._id) {\n\t\t\tthis.#wsSessionIdMap.set(wssc, wssc.session?._id ?? null);\n\t\t\t\n\t\t\tif (wssc.isOpen && wssc.session)\n\t\t\t\tthis.set(wssc, { sessionId: wssc.session._id }, { domain: this.domain, maxAge: this.maxAge });\n\t\t\telse\n\t\t\t\tthis.unset(wssc, [ \"sessionId\" ]);\n\t\t}\n\t\t\n\t};\n\t\n\t\n\tstatic parse = parseCookie;\n\t\n}\n", "export const headers = {\n\tset: \"~setcookie\"\n};\n\nexport type Method = \"GET\" | \"POST\";\n"],
5
+ "mappings": "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",
6
6
  "names": ["getWithTimeout", "InSiteServerMiddleware", "tokenMap", "InSiteCookieMiddleware", "_InSiteCookieMiddleware", "InSiteServerMiddleware", "options", "requestRegExp", "#handler", "request", "response", "token", "tokenMap", "getWithTimeout", "name", "value", "maxAge", "expiresAt", "domain", "path", "secure", "httpOnly", "sameSite", "cookie", "parseCookie", "cookie", "object", "keyEqValue", "key", "value", "crypto", "random", "setWithTimeout", "headers", "cookieTokenTimeout", "CookieSetter", "usersServer", "domain", "maxAge", "#handleClientConnect", "#handleClientSession", "#wsSessionIdMap", "wssc", "cookie", "options", "token", "crypto", "random", "setWithTimeout", "tokenMap", "headers", "names", "name", "request", "sessionId", "parseCookie"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "insite-cookie",
3
- "version": "2.0.0",
3
+ "version": "2.0.3",
4
4
  "description": "Cookie support for inSite",
5
5
  "type": "module",
6
6
  "main": "./dist/server.js",
@@ -29,17 +29,17 @@
29
29
  "license": "MIT",
30
30
  "dependencies": {
31
31
  "@nesvet/n": "^1.1.1",
32
- "insite-http": "^2.0.1",
33
- "insite-ws": "^2.0.9"
32
+ "insite-http": "^2.0.3",
33
+ "insite-ws": "^2.0.12"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@nesvet/conveyer": "^2.2.1",
37
37
  "@nesvet/eslint-config": "^2.0.24",
38
- "@types/node": "^20.14.13",
38
+ "@types/node": "^22.1.0",
39
39
  "@types/ws": "^8.5.12",
40
- "insite-users-server": "^2.0.0",
41
- "insite-users-server-ws": "^2.0.0",
42
- "insite-subscriptions-server": "^2.0.1",
40
+ "insite-users-server": "^2.0.3",
41
+ "insite-users-server-ws": "^2.0.3",
42
+ "insite-subscriptions-server": "^2.0.4",
43
43
  "typescript": "^5.5.4"
44
44
  }
45
45
  }