insite-cookie 1.0.37 → 1.0.40

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 ADDED
Binary file
package/dist/client.js ADDED
@@ -0,0 +1,2 @@
1
+ var u=(e,o,t)=>{if(!o.has(e))throw TypeError("Cannot "+t)};var h=(e,o,t)=>(u(e,o,"read from private field"),t?t.call(e):o.get(e)),i=(e,o,t)=>{if(o.has(e))throw TypeError("Cannot add the same private member more than once");o instanceof WeakSet?o.add(e):o.set(e,t)};var a={set:"~setcookie"};var r,l=class{constructor(o,t={}){i(this,r,o=>{let t=new XMLHttpRequest;t.onload=this.onload,t.onerror=this.onerror,t.open(this.method,`${this.url}?${o}`,!0),t.send(null)});let{method:d="GET",url:c="/cookie",onload:s,onerror:n}=t;this.method=d,this.url=c,s&&(this.onload=s),n&&(this.onerror=n),o.on(`message:${a.set}`,h(this,r))}onload(){this.readyState===4&&this.status!==200&&console.error("Set cookie:",this.statusText)}onerror(){console.error("Set cookie:",this.statusText)}};r=new WeakMap;export{l as CookieSetter};
2
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/common.js", "../src/client/Setter.js"],
4
+ "sourcesContent": ["export const headers = {\n\tset: \"~setcookie\"\n};\n", "import { headers } from \"../common\";\n\n\nexport class CookieSetter {\n\tconstructor(ws, options = {}) {\n\t\t\n\t\tconst {\n\t\t\tmethod = \"GET\",\n\t\t\turl = \"/cookie\",\n\t\t\tonload,\n\t\t\tonerror\n\t\t} = options;\n\t\t\n\t\tthis.method = method;\n\t\tthis.url = url;\n\t\t\n\t\tif (onload)\n\t\t\tthis.onload = onload;\n\t\t\n\t\tif (onerror)\n\t\t\tthis.onerror = onerror;\n\t\t\n\t\tws.on(`message:${headers.set}`, this.#handleSet);\n\t\t\n\t}\n\t\n\t#handleSet = token => {\n\t\tconst xhr = new XMLHttpRequest();\n\t\t\n\t\txhr.onload = this.onload;\n\t\txhr.onerror = this.onerror;\n\t\t\n\t\txhr.open(this.method, `${this.url}?${token}`, true);\n\t\t\n\t\txhr.send(null);\n\t\t\n\t};\n\t\n\tonload() {\n\t\t\n\t\tif (this.readyState === 4 && this.status !== 200)\n\t\t\tconsole.error(\"Set cookie:\", this.statusText);\n\t\t\n\t}\n\t\n\tonerror() {\n\t\t\n\t\tconsole.error(\"Set cookie:\", this.statusText);\n\t\t\n\t}\n\t\n}\n"],
5
+ "mappings": "yQAAO,IAAMA,EAAU,CACtB,IAAK,YACN,ECFA,IAAAC,EAGaC,EAAN,KAAmB,CACzB,YAAYC,EAAIC,EAAU,CAAC,EAAG,CAsB9BC,EAAA,KAAAJ,EAAaK,GAAS,CACrB,IAAMC,EAAM,IAAI,eAEhBA,EAAI,OAAS,KAAK,OAClBA,EAAI,QAAU,KAAK,QAEnBA,EAAI,KAAK,KAAK,OAAQ,GAAG,KAAK,GAAG,IAAID,CAAK,GAAI,EAAI,EAElDC,EAAI,KAAK,IAAI,CAEd,GA9BC,GAAM,CACL,OAAAC,EAAS,MACT,IAAAC,EAAM,UACN,OAAAC,EACA,QAAAC,CACD,EAAIP,EAEJ,KAAK,OAASI,EACd,KAAK,IAAMC,EAEPC,IACH,KAAK,OAASA,GAEXC,IACH,KAAK,QAAUA,GAEhBR,EAAG,GAAG,WAAWS,EAAQ,GAAG,GAAIC,EAAA,KAAKZ,EAAU,CAEhD,CAcA,QAAS,CAEJ,KAAK,aAAe,GAAK,KAAK,SAAW,KAC5C,QAAQ,MAAM,cAAe,KAAK,UAAU,CAE9C,CAEA,SAAU,CAET,QAAQ,MAAM,cAAe,KAAK,UAAU,CAE7C,CAED,EAzBCA,EAAA",
6
+ "names": ["headers", "_handleSet", "CookieSetter", "ws", "options", "__privateAdd", "token", "xhr", "method", "url", "onload", "onerror", "headers", "__privateGet"]
7
+ }
package/dist/server.js ADDED
@@ -0,0 +1,2 @@
1
+ var r=new Map;var l=class s{constructor(e={}){let{requestRegExp:o=/^\/cookie\/?\?/}=e;this.listeners={GET:[[o,this.handler]]}}handler=(e,o)=>{let t=e.url.split("?")[1];if(t&&r.has(t))o.writeHead(200,{"Content-Type":"text/plain; charset=utf-8","Set-Cookie":s.cookify(...r.getWithTimeout(t))}).end();else return!1};static make({name:e,value:o,maxAge:t,expiresAt:i,domain:p,path:u="/",secure:f=!0,httpOnly:k=!0,sameSite:h="Strict"}){let n=[`${e}=${o}`];return t!==void 0?n.push(`Max-Age=${t}`):i&&n.push(`Max-Age=${Math.round((i.getTime()-Date.now())/1e3)}`),p&&n.push(`Domain=${p}`),u&&n.push(`Path=${u}`),f&&n.push("Secure"),k&&n.push("HttpOnly"),h&&n.push(`SameSite=${h}`),n.join("; ")}static cookify(e,o){return Object.entries(e).map(([t,i])=>this.make({name:t,value:i,...o}))}};function a(s){return s?s.split(/;\s*/).reduce((e,o)=>{let[t,i]=o.split(/=/);try{e[t]=JSON.parse(i)}catch{e[t]=i}return e},{}):{}}import S from"node:crypto";var d={set:"~setcookie"};var x=2e3,c=Symbol("cookieSessionId"),m=class s{constructor(e,{users:o,domain:t,maxAge:i}){e.cookieSetter=this,this.domain=t??process.env.INSITE_HOST,this.maxAge=i??o?.sessions.collection.expireAfterSeconds,e.options.WebSocket.prototype.setCookie=s.set,e.options.WebSocket.prototype.unsetCookie=s.unset,o&&(this.users=o,e.on("client-connect",s.handleClientConnect),e.on("client-session",s.handleClientSession))}static set(e,o){let t=`${Math.round(performance.now()*Number.MAX_SAFE_INTEGER).toString(36)}$${S.randomBytes(Math.randomInt(4,8)).toString("hex")}`;r.setWithTimeout(t,[e,o],x),this.sendMessage(d.set,t)}static unset(e){this.setCookie(e.reduce((o,t)=>(o[t]="",o),{}),{maxAge:0})}static parse=a;static handleClientConnect(e,o){if(e[c]=null,o.headers.cookie){let{sessionId:t=null}=a(o.headers.cookie);e[c]=t,t&&e.setSession(t,!0)}}static handleClientSession(e){if(e[c]!==e.session?._id)if(e[c]=e.session?._id,e.isOpen&&e.session){let{domain:o,maxAge:t}=this.cookieSetter;e.setCookie({sessionId:e.session._id},{domain:o,maxAge:t})}else e.unsetCookie(["sessionId"])}};export{l as CookieMiddleware,m as CookieSetter,a as parseCookie};
2
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/server/tokenMap.js", "../src/server/Middleware.js", "../src/server/parse.js", "../src/server/Setter.js", "../src/common.js"],
4
+ "sourcesContent": ["export const tokenMap = new Map();\n", "import { tokenMap } from \"./tokenMap\";\n\n\nclass InSiteCookieMiddleware {\n\tconstructor(options = {}) {\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\thandler = (request, response) => {\n\t\tconst token = request.url.split(\"?\")[1];\n\t\t\n\t\tif (token && tokenMap.has(token))\n\t\t\tresponse.writeHead(200, {\n\t\t\t\t\"Content-Type\": \"text/plain; charset=utf-8\",\n\t\t\t\t\"Set-Cookie\": InSiteCookieMiddleware.cookify(...tokenMap.getWithTimeout(token))\n\t\t\t}).end();\n\t\telse\n\t\t\treturn false;\n\t\t\n\t};\n\t\n\t\n\tstatic make({ name, value, maxAge, expiresAt, domain, path = \"/\", secure = true, httpOnly = true, sameSite = \"Strict\" }) {\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(object, options) {\n\t\treturn Object.entries(object).map(([ name, value ]) => this.make({ name, value, ...options }));\n\t}\n\t\n}\n\nexport { InSiteCookieMiddleware as CookieMiddleware };\n", "export function parseCookie(cookie) {\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}, {}) : {};\n}\n", "import crypto from \"node:crypto\";\nimport { headers } from \"../common\";\nimport { parseCookie } from \"./parse\";\nimport { tokenMap } from \"./tokenMap\";\n\n\nconst cookieTokenTimeout = 2000;\nconst cookieSessionIdSymbol = Symbol(\"cookieSessionId\");\n\n\nexport class CookieSetter {\n\tconstructor(wss, { users, domain, maxAge }) {\n\t\twss.cookieSetter = this;\n\t\t\n\t\tthis.domain = domain ?? process.env.INSITE_HOST;\n\t\tthis.maxAge = maxAge ?? users?.sessions.collection.expireAfterSeconds;\n\t\t\n\t\twss.options.WebSocket.prototype.setCookie = CookieSetter.set;\n\t\twss.options.WebSocket.prototype.unsetCookie = CookieSetter.unset;\n\t\t\n\t\tif (users) {\n\t\t\tthis.users = users;\n\t\t\t\n\t\t\twss.on(\"client-connect\", CookieSetter.handleClientConnect);\n\t\t\twss.on(\"client-session\", CookieSetter.handleClientSession);\n\t\t}\n\t\t\n\t}\n\t\n\t\n\tstatic set(cookie, options) {\n\t\t\n\t\tconst token = `${Math.round(performance.now() * Number.MAX_SAFE_INTEGER).toString(36)}$${crypto.randomBytes(Math.randomInt(4, 8)).toString(\"hex\")}`;\n\t\t\n\t\ttokenMap.setWithTimeout(token, [ cookie, options ], cookieTokenTimeout);\n\t\t\n\t\tthis.sendMessage(headers.set, token);\n\t\t\n\t}\n\t\n\tstatic unset(names) {\n\t\tthis.setCookie(names.reduce((cookie, name) => {\n\t\t\tcookie[name] = \"\";\n\t\t\t\n\t\t\treturn cookie;\n\t\t}, {}), { maxAge: 0 });\n\t\t\n\t}\n\t\n\tstatic parse = parseCookie;\n\t\n\t\n\tstatic handleClientConnect(ws, request) {\n\t\tws[cookieSessionIdSymbol] = null;\n\t\t\n\t\tif (request.headers.cookie) {\n\t\t\tconst { sessionId = null } = parseCookie(request.headers.cookie);\n\t\t\t\n\t\t\tws[cookieSessionIdSymbol] = sessionId;\n\t\t\t\n\t\t\tif (sessionId)\n\t\t\t\tws.setSession(sessionId, true);\n\t\t}\n\t\t\n\t}\n\t\n\tstatic handleClientSession(ws) {\n\t\tif (ws[cookieSessionIdSymbol] !== ws.session?._id) {\n\t\t\tws[cookieSessionIdSymbol] = ws.session?._id;\n\t\t\t\n\t\t\tif (ws.isOpen && ws.session) {\n\t\t\t\tconst { domain, maxAge } = this.cookieSetter;\n\t\t\t\tws.setCookie({ sessionId: ws.session._id }, { domain, maxAge });\n\t\t\t} else\n\t\t\t\tws.unsetCookie([ \"sessionId\" ]);\n\t\t}\n\t\t\n\t}\n\t\n}\n", "export const headers = {\n\tset: \"~setcookie\"\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["tokenMap", "InSiteCookieMiddleware", "_InSiteCookieMiddleware", "options", "requestRegExp", "request", "response", "token", "tokenMap", "name", "value", "maxAge", "expiresAt", "domain", "path", "secure", "httpOnly", "sameSite", "cookie", "object", "parseCookie", "cookie", "object", "keyEqValue", "key", "value", "crypto", "headers", "cookieTokenTimeout", "cookieSessionIdSymbol", "CookieSetter", "_CookieSetter", "wss", "users", "domain", "maxAge", "cookie", "options", "token", "crypto", "tokenMap", "headers", "names", "name", "parseCookie", "ws", "request", "sessionId"]
7
+ }
package/package.json CHANGED
@@ -1,36 +1,36 @@
1
1
  {
2
- "name": "insite-cookie",
3
- "version": "1.0.37",
4
- "description": "Cookie support for inSite",
5
- "type": "module",
6
- "main": "./lib/index.js",
7
- "module": "./lib/index.js",
8
- "exports": {
9
- ".": "./lib/index.js",
10
- "./ws/server": "./lib/ws/server/index.js",
11
- "./ws/client": "./lib/ws/client/index.js",
12
- "./parse": "./lib/parse.js"
13
- },
14
- "packageManager": "yarn@1.22.22",
15
- "scripts": {
16
- "test": "echo \"Error: no test specified\" && exit 1"
17
- },
18
- "repository": {
19
- "type": "git",
20
- "url": "git+https://github.com/nesvet/insite-cookie.git"
21
- },
22
- "keywords": [
23
- "insite",
24
- "cookie",
25
- "client",
26
- "server"
27
- ],
28
- "author": "Eugene Nesvetaev <dev@nesvet.dev> (https://nesvet.dev/)",
29
- "license": "MIT",
30
- "dependencies": {
31
- "insite-ws": "^1"
32
- },
33
- "devDependencies": {
34
- "@nesvet/eslint-config": "^1"
35
- }
2
+ "name": "insite-cookie",
3
+ "version": "1.0.40",
4
+ "description": "Cookie support for inSite",
5
+ "type": "module",
6
+ "main": "./dist/server.js",
7
+ "module": "./dist/server.js",
8
+ "exports": {
9
+ "./server": "./dist/server.js",
10
+ "./client": "./dist/client.js"
11
+ },
12
+ "packageManager": "bun@1.1.8",
13
+ "scripts": {
14
+ "test": "echo \"Error: no test specified\" && exit 1",
15
+ "build": "bun .conveyer.js"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/nesvet/insite-cookie.git"
20
+ },
21
+ "keywords": [
22
+ "insite",
23
+ "cookie",
24
+ "client",
25
+ "server"
26
+ ],
27
+ "author": "Eugene Nesvetaev <dev@nesvet.dev> (https://nesvet.dev/)",
28
+ "license": "MIT",
29
+ "dependencies": {
30
+ "insite-ws": "^1"
31
+ },
32
+ "devDependencies": {
33
+ "@nesvet/conveyer": "^2",
34
+ "@nesvet/eslint-config": "^1"
35
+ }
36
36
  }
package/lib/Middleware.js DELETED
@@ -1,60 +0,0 @@
1
- import { tokenMap } from "./tokenMap";
2
-
3
-
4
- export class CookieMiddleware {
5
- constructor(options = {}) {
6
- const {
7
- requestRegExp = /^\/cookie\/?\?/
8
- } = options;
9
-
10
- this.listeners = { GET: [
11
- [ requestRegExp, this.handler ]
12
- ] };
13
-
14
- }
15
-
16
- handler = (request, response) => {
17
- const token = request.url.split("?")[1];
18
-
19
- if (token && tokenMap.has(token))
20
- response.writeHead(200, {
21
- "Content-Type": "text/plain; charset=utf-8",
22
- "Set-Cookie": CookieMiddleware.cookify(...tokenMap.getWithTimeout(token))
23
- }).end();
24
- else
25
- return false;
26
-
27
- };
28
-
29
-
30
- static make({ name, value, maxAge, expiresAt, domain, path = "/", secure = true, httpOnly = true, sameSite = "Strict" }) {
31
- const cookie = [ `${name}=${value}` ];
32
-
33
- if (maxAge !== undefined)
34
- cookie.push(`Max-Age=${maxAge}`);
35
- else if (expiresAt)
36
- cookie.push(`Max-Age=${Math.round((expiresAt.getTime() - Date.now()) / 1000)}`);
37
-
38
- if (domain)
39
- cookie.push(`Domain=${domain}`);
40
-
41
- if (path)
42
- cookie.push(`Path=${path}`);
43
-
44
- if (secure)
45
- cookie.push("Secure");
46
-
47
- if (httpOnly)
48
- cookie.push("HttpOnly");
49
-
50
- if (sameSite)
51
- cookie.push(`SameSite=${sameSite}`);
52
-
53
- return cookie.join("; ");
54
- }
55
-
56
- static cookify(object, options) {
57
- return Object.entries(object).map(([ name, value ]) => this.make({ name, value, ...options }));
58
- }
59
-
60
- }
package/lib/index.js DELETED
@@ -1,2 +0,0 @@
1
- export * from "./Middleware";
2
- export * from "./parse";
package/lib/parse.js DELETED
@@ -1,13 +0,0 @@
1
- export function parseCookie(cookie) {
2
- return cookie ? cookie.split(/;\s*/).reduce((object, keyEqValue) => {
3
- const [ key, value ] = keyEqValue.split(/=/);
4
-
5
- try {
6
- object[key] = JSON.parse(value);
7
- } catch {
8
- object[key] = value;
9
- }
10
-
11
- return object;
12
- }, {}) : {};
13
- }
package/lib/tokenMap.js DELETED
@@ -1 +0,0 @@
1
- export const tokenMap = new Map();
@@ -1,52 +0,0 @@
1
- import { headers } from "../common";
2
-
3
-
4
- export class CookieSetterClient {
5
- constructor(ws, options = {}) {
6
-
7
- const {
8
- method = "GET",
9
- url = "/cookie",
10
- onload,
11
- onerror
12
- } = options;
13
-
14
- this.method = method;
15
- this.url = url;
16
-
17
- if (onload)
18
- this.onload = onload;
19
-
20
- if (onerror)
21
- this.onerror = onerror;
22
-
23
- ws.on(`message:${headers.set}`, this.#handleSet);
24
-
25
- }
26
-
27
- #handleSet = token => {
28
- const xhr = new XMLHttpRequest();
29
-
30
- xhr.onload = this.onload;
31
- xhr.onerror = this.onerror;
32
-
33
- xhr.open(this.method, `${this.url}?${token}`, true);
34
-
35
- xhr.send(null);
36
-
37
- };
38
-
39
- onload() {
40
-
41
- if (this.readyState === 4 && this.status !== 200)
42
- console.error("Set cookie:", this.statusText);
43
-
44
- }
45
-
46
- onerror() {
47
-
48
- console.error("Set cookie:", this.statusText);
49
-
50
- }
51
-
52
- }
@@ -1 +0,0 @@
1
- export * from "./SetterClient";
package/lib/ws/common.js DELETED
@@ -1,3 +0,0 @@
1
- export const headers = {
2
- set: "~setcookie"
3
- };
@@ -1,80 +0,0 @@
1
- import crypto from "node:crypto";
2
- import { parseCookie } from "../../parse";
3
- import { tokenMap } from "../../tokenMap";
4
- import { headers } from "../common";
5
-
6
-
7
- const cookieTokenTimeout = 2000;
8
- const cookieSessionIdSymbol = Symbol("cookieSessionId");
9
-
10
-
11
- export class CookieSetterServer {
12
- constructor(wss, { users, domain, maxAge }) {
13
- wss.cookieSetter = this;
14
-
15
- this.domain = domain ?? process.env.HOST;
16
- this.maxAge = maxAge ?? users?.sessions.collection.expireAfterSeconds;
17
-
18
- wss.options.WebSocket.prototype.setCookie = CookieSetterServer.set;
19
- wss.options.WebSocket.prototype.unsetCookie = CookieSetterServer.unset;
20
-
21
- if (users) {
22
- this.users = users;
23
-
24
- wss.on("client-connect", CookieSetterServer.handleClientConnect);
25
- wss.on("client-session", CookieSetterServer.handleClientSession);
26
- }
27
-
28
- }
29
-
30
-
31
- static set(cookie, options) {
32
-
33
- const token = `${Math.round(performance.now() * Number.MAX_SAFE_INTEGER).toString(36)}$${crypto.randomBytes(Math.randomInt(4, 8)).toString("hex")}`;
34
-
35
- tokenMap.setWithTimeout(token, [ cookie, options ], cookieTokenTimeout);
36
-
37
- this.sendMessage(headers.set, token);
38
-
39
- }
40
-
41
- static unset(names) {
42
- this.setCookie(names.reduce((cookie, name) => {
43
- cookie[name] = "";
44
-
45
- return cookie;
46
- }, {}), { maxAge: 0 });
47
-
48
- }
49
-
50
- static parse = parseCookie;
51
-
52
-
53
- static handleClientConnect(ws, request) {
54
- ws[cookieSessionIdSymbol] = null;
55
-
56
- if (request.headers.cookie) {
57
- const { sessionId = null } = parseCookie(request.headers.cookie);
58
-
59
- ws[cookieSessionIdSymbol] = sessionId;
60
-
61
- if (sessionId)
62
- ws.setSession(sessionId, true);
63
- }
64
-
65
- }
66
-
67
- static handleClientSession(ws) {
68
- if (ws[cookieSessionIdSymbol] !== ws.session?._id) {
69
- ws[cookieSessionIdSymbol] = ws.session?._id;
70
-
71
- if (ws.isOpen && ws.session) {
72
- const { domain, maxAge } = this.cookieSetter;
73
- ws.setCookie({ sessionId: ws.session._id }, { domain, maxAge });
74
- } else
75
- ws.unsetCookie([ "sessionId" ]);
76
- }
77
-
78
- }
79
-
80
- }
@@ -1 +0,0 @@
1
- export * from "./SetterServer";