securequ 1.1.5 → 1.1.7

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.
Files changed (49) hide show
  1. package/client/Base.d.ts +18 -18
  2. package/client/Base.js +147 -1
  3. package/client/Base.js.map +1 -1
  4. package/client/Base.mjs +147 -1
  5. package/client/Base.mjs.map +1 -1
  6. package/client/index.d.ts +8 -8
  7. package/client/index.js +139 -1
  8. package/client/index.js.map +1 -1
  9. package/client/index.mjs +139 -1
  10. package/client/index.mjs.map +1 -1
  11. package/client/types.d.ts +34 -34
  12. package/include/File.js +60 -1
  13. package/include/File.js.map +1 -1
  14. package/include/File.mjs +60 -1
  15. package/include/File.mjs.map +1 -1
  16. package/include/FileScaner.js +95 -1
  17. package/include/FileScaner.js.map +1 -1
  18. package/include/FileScaner.mjs +95 -1
  19. package/include/FileScaner.mjs.map +1 -1
  20. package/include/compress.d.ts +9 -9
  21. package/include/compress.js +19 -1
  22. package/include/compress.js.map +1 -1
  23. package/include/compress.mjs +19 -1
  24. package/include/compress.mjs.map +1 -1
  25. package/include/crypto.d.ts +15 -15
  26. package/include/crypto.js +55 -1
  27. package/include/crypto.js.map +1 -1
  28. package/include/crypto.mjs +55 -1
  29. package/include/crypto.mjs.map +1 -1
  30. package/index.js +1 -1
  31. package/index.mjs +1 -1
  32. package/package.json +1 -1
  33. package/readme.md +312 -312
  34. package/server/Base.d.ts +20 -20
  35. package/server/Base.js +102 -1
  36. package/server/Base.js.map +1 -1
  37. package/server/Base.mjs +102 -1
  38. package/server/Base.mjs.map +1 -1
  39. package/server/Router.d.ts +7 -7
  40. package/server/Router.js +30 -1
  41. package/server/Router.js.map +1 -1
  42. package/server/Router.mjs +30 -1
  43. package/server/Router.mjs.map +1 -1
  44. package/server/index.d.ts +5 -5
  45. package/server/index.js +179 -1
  46. package/server/index.js.map +1 -1
  47. package/server/index.mjs +179 -1
  48. package/server/index.mjs.map +1 -1
  49. package/server/types.d.ts +72 -72
package/client/Base.d.ts CHANGED
@@ -1,23 +1,23 @@
1
1
  import { SecurequClientConfig, HandshakeInfo, HttpRequestInit, SecurequClientResponse } from './types.js';
2
2
 
3
- declare class Base {
4
- protected config: SecurequClientConfig;
5
- protected loadingHandshake: boolean;
6
- protected secret_length: number;
7
- protected handshakeInfo: HandshakeInfo | null;
8
- readonly CONTENT_TYPE = "application/octet-stream";
9
- constructor(config: SecurequClientConfig);
10
- protected hooksCall(hook: keyof NonNullable<SecurequClientConfig['hooks']>, ...args: any[]): any;
11
- protected getSecret(): Promise<{
12
- full: string;
13
- secret: string;
14
- hash: string;
15
- }>;
16
- protected url(path: string): Promise<URL>;
17
- protected getHeaders(path: string, init?: HttpRequestInit): Promise<any>;
18
- protected awaitForHandshake(): Promise<void>;
19
- handshake(): Promise<void>;
20
- protected fetch(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse>;
3
+ declare class Base {
4
+ protected config: SecurequClientConfig;
5
+ protected loadingHandshake: boolean;
6
+ protected secret_length: number;
7
+ protected handshakeInfo: HandshakeInfo | null;
8
+ readonly CONTENT_TYPE = "application/octet-stream";
9
+ constructor(config: SecurequClientConfig);
10
+ protected hooksCall(hook: keyof NonNullable<SecurequClientConfig['hooks']>, ...args: any[]): any;
11
+ protected getSecret(): Promise<{
12
+ full: string;
13
+ secret: string;
14
+ hash: string;
15
+ }>;
16
+ protected url(path: string): Promise<URL>;
17
+ protected getHeaders(path: string, init?: HttpRequestInit): Promise<any>;
18
+ protected awaitForHandshake(): Promise<void>;
19
+ handshake(): Promise<void>;
20
+ protected fetch(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse>;
21
21
  }
22
22
 
23
23
  export { Base as default };
package/client/Base.js CHANGED
@@ -1 +1,147 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("../include/crypto.js"),e=require("xanfetch");const s=new Map;exports.default=class{constructor(t){this.loadingHandshake=!1,this.secret_length=0,this.handshakeInfo=null,this.CONTENT_TYPE="application/octet-stream",this.config=Object.assign({},t);const e=new URL(t.url);if(e.search||e.hash)throw new Error(`Invalid config url ${t.url}. Search params or Hash url is not supported in config.url`);if(t.url=`${e.origin}${e.pathname}`,s.has(t.url))throw new Error("Client is Blocked!")}hooksCall(t,...e){if(this.config.hooks&&this.config.hooks[t])return this.config.hooks[t](...e)}async getSecret(){let e=this.config.secret,s=e.substring(0,this.secret_length);return{full:e,secret:s,hash:(await t.default.hash(s)).substring(0,this.secret_length)}}async url(t){const e=await this.getSecret(),s=this.config.url;return"/"===t&&(t=""),(t=(t=(t=t.trim()).startsWith("/")?t.substring(1):t).endsWith("/")?t.substring(0,t.length-1):t)&&(t=`/${t}`),new URL(`${s}/${e.hash}${t}`)}async getHeaders(e,s){var a,n,i;const r=await this.url(e),h=await this.getSecret();let o={};return this.handshakeInfo&&(o["X-SIGNETURE"]=await t.default.encrypt({signeture:null===(a=this.handshakeInfo)||void 0===a?void 0:a.signeture,expire:Date.now()+this.handshakeInfo.timeDiffarenc+1e4},h.secret)||""),o=Object.assign(Object.assign(Object.assign(Object.assign({},null===(i=null===(n=this.config)||void 0===n?void 0:n.defaultOptions)||void 0===i?void 0:i.headers),null==s?void 0:s.headers),o),{"Content-Type":this.CONTENT_TYPE,"X-ORIGIN":r.origin,"X-METHOD":((null==s?void 0:s.method)||"GET").toUpperCase()}),o}async awaitForHandshake(){this.loadingHandshake&&await new Promise(t=>{const e=setInterval(()=>{this.loadingHandshake||(clearInterval(e),t(null))},100)}),this.handshakeInfo||await this.handshake()}async handshake(){await this.hooksCall("beforeHandshake"),this.handshakeInfo=null,this.loadingHandshake=!0;let t=this.config.secret.length,e=3*Math.floor(t/4);this.secret_length=Math.floor(Math.random()*(t-e+1))+e;const s=await this.getSecret(),a=await this.fetch("/",{method:"POST",body:{hash:s.hash,clientTime:(new Date).toISOString(),secret:s.secret}});this.handshakeInfo=a.data,this.loadingHandshake=!1,await this.hooksCall("afterHandshake",this.handshakeInfo)}async fetch(s,a){var n,i;const r="/"!==s&&(null===(n=this.handshakeInfo)||void 0===n?void 0:n.dev),h=await this.getSecret(),o=await this.url(s);let c=Object.fromEntries(o.searchParams.entries());const l=Object.assign({},a);let d=Object.assign({},c);if(Object.keys(c).length>0)for(let t in c)o.searchParams.delete(t);if(null==l?void 0:l.params){for(let t in l.params)d[t]=l.params[t];delete l.params}if(Object.keys(d).length>0)if(r)l.params=d;else{const e=await t.default.encrypt(d,h.secret);o.href=o.href+"?"+encodeURIComponent(e)}const u=Object.assign(Object.assign(Object.assign({method:"GET"},null===(i=this.config)||void 0===i?void 0:i.defaultOptions),l),{headers:await this.getHeaders(s,l)});(null==u?void 0:u.body)&&(u.body=r?JSON.stringify(u.body):await t.default.encryptBuffer(u.body,h.secret));const f=await e(o.href,u);if(r){const t=await f.text(),e=JSON.parse(t);return{success:f.ok,message:f.ok?f.statusText:e,data:f.ok?e:null,code:f.status}}const g=await f.arrayBuffer(),k=await t.default.decryptBuffer(new Uint8Array(g),h.secret);return{success:f.ok,message:f.ok?f.statusText:k||f.statusText,data:f.ok?k:null,code:f.status}}};//# sourceMappingURL=Base.js.map
1
+ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var crypto=require('../include/crypto.js'),xanFetch=require('xanfetch');const Clients = new Map();
2
+ class Base {
3
+ constructor(config) {
4
+ this.loadingHandshake = false;
5
+ this.secret_length = 0;
6
+ this.handshakeInfo = null;
7
+ this.CONTENT_TYPE = "application/octet-stream";
8
+ this.config = Object.assign({}, config);
9
+ const url = new URL(config.url);
10
+ if (url.search || url.hash)
11
+ throw new Error(`Invalid config url ${config.url}. Search params or Hash url is not supported in config.url`);
12
+ config.url = `${url.origin}${url.pathname}`;
13
+ if (Clients.has(config.url)) {
14
+ throw new Error(`Client is Blocked!`);
15
+ }
16
+ }
17
+ hooksCall(hook, ...args) {
18
+ if (this.config.hooks && this.config.hooks[hook]) {
19
+ return this.config.hooks[hook](...args);
20
+ }
21
+ }
22
+ async getSecret() {
23
+ let full = this.config.secret;
24
+ let secret = full.substring(0, this.secret_length);
25
+ let hash = (await crypto.default.hash(secret)).substring(0, this.secret_length);
26
+ return { full, secret, hash };
27
+ }
28
+ async url(path) {
29
+ const secret = await this.getSecret();
30
+ const base = this.config.url;
31
+ if (path === '/')
32
+ path = '';
33
+ path = path.trim();
34
+ path = path.startsWith('/') ? path.substring(1) : path;
35
+ path = path.endsWith('/') ? path.substring(0, path.length - 1) : path;
36
+ if (path)
37
+ path = `/${path}`;
38
+ return new URL(`${base}/${secret.hash}${path}`);
39
+ }
40
+ async getHeaders(path, init) {
41
+ var _a, _b, _c;
42
+ const url = await this.url(path);
43
+ const secret = await this.getSecret();
44
+ let headers = {};
45
+ if (this.handshakeInfo) {
46
+ headers["X-SIGNETURE"] = await crypto.default.encrypt({
47
+ signeture: (_a = this.handshakeInfo) === null || _a === void 0 ? void 0 : _a.signeture,
48
+ expire: Date.now() + this.handshakeInfo.timeDiffarenc + 10000 // 10 seconds
49
+ }, secret.secret) || '';
50
+ }
51
+ headers = Object.assign(Object.assign(Object.assign(Object.assign({}, (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.defaultOptions) === null || _c === void 0 ? void 0 : _c.headers), init === null || init === void 0 ? void 0 : init.headers), headers), { 'Content-Type': this.CONTENT_TYPE, "X-ORIGIN": url.origin, "X-METHOD": ((init === null || init === void 0 ? void 0 : init.method) || 'GET').toUpperCase() });
52
+ return headers;
53
+ }
54
+ async awaitForHandshake() {
55
+ if (this.loadingHandshake) {
56
+ await new Promise((resolve) => {
57
+ const interval = setInterval(() => {
58
+ if (!this.loadingHandshake) {
59
+ clearInterval(interval);
60
+ resolve(null);
61
+ }
62
+ }, 100);
63
+ });
64
+ }
65
+ if (!this.handshakeInfo) {
66
+ await this.handshake();
67
+ }
68
+ }
69
+ async handshake() {
70
+ await this.hooksCall('beforeHandshake');
71
+ this.handshakeInfo = null;
72
+ this.loadingHandshake = true;
73
+ let max = this.config.secret.length;
74
+ let min = Math.floor(max / 4) * 3;
75
+ this.secret_length = Math.floor(Math.random() * (max - min + 1)) + min;
76
+ const secret = await this.getSecret();
77
+ const res = await this.fetch('/', {
78
+ method: 'POST',
79
+ body: {
80
+ hash: secret.hash,
81
+ clientTime: new Date().toISOString(),
82
+ secret: secret.secret,
83
+ }
84
+ });
85
+ this.handshakeInfo = res.data;
86
+ this.loadingHandshake = false;
87
+ await this.hooksCall('afterHandshake', this.handshakeInfo);
88
+ }
89
+ async fetch(path, init) {
90
+ var _a, _b;
91
+ const isDev = path !== '/' && ((_a = this.handshakeInfo) === null || _a === void 0 ? void 0 : _a.dev);
92
+ const secret = await this.getSecret();
93
+ const url = await this.url(path);
94
+ let sparams = Object.fromEntries(url.searchParams.entries());
95
+ const _init = Object.assign({}, init);
96
+ let params = Object.assign({}, sparams);
97
+ if (Object.keys(sparams).length > 0) {
98
+ for (let key in sparams) {
99
+ url.searchParams.delete(key);
100
+ }
101
+ }
102
+ if (_init === null || _init === void 0 ? void 0 : _init.params) {
103
+ for (let key in _init.params) {
104
+ params[key] = _init.params[key];
105
+ }
106
+ delete _init.params;
107
+ }
108
+ if (Object.keys(params).length > 0) {
109
+ if (isDev) {
110
+ _init.params = params;
111
+ }
112
+ else {
113
+ const key = Math.random().toString(36).substring(2, 8);
114
+ const enc = await crypto.default.encrypt({ params, key }, secret.secret);
115
+ url.href = `${url.href}?${key}=${encodeURIComponent(enc)}`;
116
+ }
117
+ }
118
+ const httpOption = Object.assign(Object.assign(Object.assign({ method: "GET" }, (_b = this.config) === null || _b === void 0 ? void 0 : _b.defaultOptions), _init), { headers: await this.getHeaders(path, _init) });
119
+ if (httpOption === null || httpOption === void 0 ? void 0 : httpOption.body) {
120
+ if (isDev) {
121
+ httpOption.body = JSON.stringify(httpOption.body);
122
+ }
123
+ else {
124
+ httpOption.body = await crypto.default.encryptBuffer(httpOption.body, secret.secret);
125
+ }
126
+ }
127
+ const res = await xanFetch(url.href, httpOption);
128
+ if (isDev) {
129
+ const value = await res.text();
130
+ const val = JSON.parse(value);
131
+ return {
132
+ success: res.ok,
133
+ message: res.ok ? res.statusText : val,
134
+ data: res.ok ? val : null,
135
+ code: res.status
136
+ };
137
+ }
138
+ const value = await res.arrayBuffer();
139
+ const val = await crypto.default.decryptBuffer(new Uint8Array(value), secret.secret);
140
+ return {
141
+ success: res.ok,
142
+ message: res.ok ? res.statusText : (val || res.statusText),
143
+ data: res.ok ? val : null,
144
+ code: res.status
145
+ };
146
+ }
147
+ }exports.default=Base;//# sourceMappingURL=Base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Base.js","sources":["../../src/client/Base.ts"],"sourcesContent":["import crypto from \"../include/crypto\";\r\nimport { HandshakeInfo, HttpRequestInit, SecurequClientConfig, SecurequClientResponse } from \"./types\";\r\nimport xanFetch from 'xanfetch'\r\n\r\n\r\nconst Clients = new Map<string, Base>()\r\n\r\nclass Base {\r\n protected config: SecurequClientConfig;\r\n protected loadingHandshake: boolean = false;\r\n protected secret_length: number = 0;\r\n protected handshakeInfo: HandshakeInfo | null = null;\r\n readonly CONTENT_TYPE = \"application/octet-stream\";\r\n\r\n constructor(config: SecurequClientConfig) {\r\n this.config = {\r\n ...config,\r\n }\r\n const url = new URL(config.url)\r\n if (url.search || url.hash) throw new Error(`Invalid config url ${config.url}. Search params or Hash url is not supported in config.url`)\r\n config.url = `${url.origin}${url.pathname}`\r\n\r\n if (Clients.has(config.url)) {\r\n throw new Error(`Client is Blocked!`);\r\n }\r\n }\r\n\r\n protected hooksCall(hook: keyof NonNullable<SecurequClientConfig['hooks']>, ...args: any[]) {\r\n if (this.config.hooks && this.config.hooks[hook]) {\r\n return (this.config.hooks[hook] as Function)(...args)\r\n }\r\n }\r\n\r\n protected async getSecret() {\r\n let full = this.config.secret\r\n let secret = full.substring(0, this.secret_length)\r\n let hash = (await crypto.hash(secret)).substring(0, this.secret_length)\r\n return { full, secret, hash }\r\n }\r\n\r\n protected async url(path: string) {\r\n const secret = await this.getSecret()\r\n const base = this.config.url;\r\n if (path === '/') path = ''\r\n path = path.trim();\r\n path = path.startsWith('/') ? path.substring(1) : path\r\n path = path.endsWith('/') ? path.substring(0, path.length - 1) : path\r\n if (path) path = `/${path}`\r\n return new URL(`${base}/${secret.hash}${path}`);\r\n }\r\n\r\n protected async getHeaders(path: string, init?: HttpRequestInit) {\r\n const url = await this.url(path)\r\n const secret = await this.getSecret()\r\n let headers: any = {};\r\n if (this.handshakeInfo) {\r\n headers[\"X-SIGNETURE\"] = await crypto.encrypt({\r\n signeture: this.handshakeInfo?.signeture,\r\n expire: Date.now() + this.handshakeInfo!.timeDiffarenc + 10000 // 10 seconds\r\n }, secret.secret) || '';\r\n }\r\n\r\n headers = {\r\n ...this.config?.defaultOptions?.headers,\r\n ...init?.headers,\r\n ...headers,\r\n 'Content-Type': this.CONTENT_TYPE,\r\n \"X-ORIGIN\": url.origin,\r\n \"X-METHOD\": (init?.method || 'GET').toUpperCase()\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n protected async awaitForHandshake() {\r\n if (this.loadingHandshake) {\r\n await new Promise((resolve) => {\r\n const interval = setInterval(() => {\r\n if (!this.loadingHandshake) {\r\n clearInterval(interval);\r\n resolve(null);\r\n }\r\n }, 100);\r\n })\r\n }\r\n if (!this.handshakeInfo) {\r\n await this.handshake();\r\n }\r\n }\r\n\r\n async handshake() {\r\n await this.hooksCall('beforeHandshake');\r\n this.handshakeInfo = null;\r\n this.loadingHandshake = true;\r\n\r\n let max = this.config.secret.length\r\n let min = Math.floor(max / 4) * 3\r\n this.secret_length = Math.floor(Math.random() * (max - min + 1)) + min\r\n\r\n const secret = await this.getSecret()\r\n const res = await this.fetch('/', {\r\n method: 'POST',\r\n body: {\r\n hash: secret.hash,\r\n clientTime: new Date().toISOString(),\r\n secret: secret.secret,\r\n }\r\n })\r\n this.handshakeInfo = res.data\r\n this.loadingHandshake = false;\r\n await this.hooksCall('afterHandshake', this.handshakeInfo);\r\n }\r\n\r\n protected async fetch(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse> {\r\n const isDev = path !== '/' && this.handshakeInfo?.dev\r\n const secret = await this.getSecret()\r\n const url = await this.url(path)\r\n let sparams = Object.fromEntries(url.searchParams.entries())\r\n const _init = { ...init }\r\n let params: any = {\r\n ...sparams,\r\n }\r\n\r\n if (Object.keys(sparams).length > 0) {\r\n for (let key in sparams) {\r\n url.searchParams.delete(key)\r\n }\r\n }\r\n\r\n if (_init?.params) {\r\n for (let key in _init.params) {\r\n params[key] = _init.params[key]\r\n }\r\n delete _init.params\r\n }\r\n\r\n if (Object.keys(params).length > 0) {\r\n if (isDev) {\r\n _init.params = params\r\n } else {\r\n const enc = await crypto.encrypt(params, secret.secret)\r\n url.href = url.href + \"?\" + encodeURIComponent(enc)\r\n }\r\n }\r\n\r\n const httpOption: any = {\r\n method: \"GET\",\r\n ...this.config?.defaultOptions,\r\n ..._init,\r\n headers: await this.getHeaders(path, _init)\r\n }\r\n\r\n if (httpOption?.body) {\r\n if (isDev) {\r\n httpOption.body = JSON.stringify(httpOption.body)\r\n } else {\r\n httpOption.body = await crypto.encryptBuffer(httpOption.body, secret.secret);\r\n }\r\n }\r\n const res = await xanFetch(url.href, httpOption)\r\n if (isDev) {\r\n const value = await res.text()\r\n const val = JSON.parse(value)\r\n return {\r\n success: res.ok,\r\n message: res.ok ? res.statusText : val,\r\n data: res.ok ? val : null,\r\n code: res.status\r\n }\r\n }\r\n const value = await res.arrayBuffer()\r\n const val = await crypto.decryptBuffer(new Uint8Array(value), secret.secret) as any\r\n\r\n return {\r\n success: res.ok,\r\n message: res.ok ? res.statusText : (val || res.statusText),\r\n data: res.ok ? val : null,\r\n code: res.status\r\n }\r\n }\r\n\r\n}\r\n\r\nexport default Base;\r\n"],"names":["Object","defineProperty","exports","value","crypto","require","xanFetch","Clients","Map","default","constructor","config","this","loadingHandshake","secret_length","handshakeInfo","CONTENT_TYPE","assign","url","URL","search","hash","Error","origin","pathname","has","hooksCall","hook","args","hooks","getSecret","full","secret","substring","path","base","trim","startsWith","endsWith","length","getHeaders","init","headers","encrypt","signeture","_a","expire","Date","now","timeDiffarenc","_b","defaultOptions","_c","method","toUpperCase","awaitForHandshake","Promise","resolve","interval","setInterval","clearInterval","handshake","max","min","Math","floor","random","res","fetch","body","clientTime","toISOString","data","isDev","dev","sparams","fromEntries","searchParams","entries","_init","params","keys","key","delete","enc","href","encodeURIComponent","httpOption","JSON","stringify","encryptBuffer","text","val","parse","success","ok","message","statusText","code","status","arrayBuffer","decryptBuffer","Uint8Array"],"mappings":"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"}
1
+ {"version":3,"file":"Base.js","sources":["../../src/client/Base.ts"],"sourcesContent":["import crypto from \"../include/crypto\";\nimport { HandshakeInfo, HttpRequestInit, SecurequClientConfig, SecurequClientResponse } from \"./types\";\nimport xanFetch from 'xanfetch'\n\n\nconst Clients = new Map<string, Base>()\n\nclass Base {\n protected config: SecurequClientConfig;\n protected loadingHandshake: boolean = false;\n protected secret_length: number = 0;\n protected handshakeInfo: HandshakeInfo | null = null;\n readonly CONTENT_TYPE = \"application/octet-stream\";\n\n constructor(config: SecurequClientConfig) {\n this.config = {\n ...config,\n }\n const url = new URL(config.url)\n if (url.search || url.hash) throw new Error(`Invalid config url ${config.url}. Search params or Hash url is not supported in config.url`)\n config.url = `${url.origin}${url.pathname}`\n\n if (Clients.has(config.url)) {\n throw new Error(`Client is Blocked!`);\n }\n }\n\n protected hooksCall(hook: keyof NonNullable<SecurequClientConfig['hooks']>, ...args: any[]) {\n if (this.config.hooks && this.config.hooks[hook]) {\n return (this.config.hooks[hook] as Function)(...args)\n }\n }\n\n protected async getSecret() {\n let full = this.config.secret\n let secret = full.substring(0, this.secret_length)\n let hash = (await crypto.hash(secret)).substring(0, this.secret_length)\n return { full, secret, hash }\n }\n\n protected async url(path: string) {\n const secret = await this.getSecret()\n const base = this.config.url;\n if (path === '/') path = ''\n path = path.trim();\n path = path.startsWith('/') ? path.substring(1) : path\n path = path.endsWith('/') ? path.substring(0, path.length - 1) : path\n if (path) path = `/${path}`\n return new URL(`${base}/${secret.hash}${path}`);\n }\n\n protected async getHeaders(path: string, init?: HttpRequestInit) {\n const url = await this.url(path)\n const secret = await this.getSecret()\n let headers: any = {};\n if (this.handshakeInfo) {\n headers[\"X-SIGNETURE\"] = await crypto.encrypt({\n signeture: this.handshakeInfo?.signeture,\n expire: Date.now() + this.handshakeInfo!.timeDiffarenc + 10000 // 10 seconds\n }, secret.secret) || '';\n }\n\n headers = {\n ...this.config?.defaultOptions?.headers,\n ...init?.headers,\n ...headers,\n 'Content-Type': this.CONTENT_TYPE,\n \"X-ORIGIN\": url.origin,\n \"X-METHOD\": (init?.method || 'GET').toUpperCase()\n }\n\n return headers;\n }\n\n protected async awaitForHandshake() {\n if (this.loadingHandshake) {\n await new Promise((resolve) => {\n const interval = setInterval(() => {\n if (!this.loadingHandshake) {\n clearInterval(interval);\n resolve(null);\n }\n }, 100);\n })\n }\n if (!this.handshakeInfo) {\n await this.handshake();\n }\n }\n\n async handshake() {\n await this.hooksCall('beforeHandshake');\n this.handshakeInfo = null;\n this.loadingHandshake = true;\n\n let max = this.config.secret.length\n let min = Math.floor(max / 4) * 3\n this.secret_length = Math.floor(Math.random() * (max - min + 1)) + min\n\n const secret = await this.getSecret()\n const res = await this.fetch('/', {\n method: 'POST',\n body: {\n hash: secret.hash,\n clientTime: new Date().toISOString(),\n secret: secret.secret,\n }\n })\n this.handshakeInfo = res.data\n this.loadingHandshake = false;\n await this.hooksCall('afterHandshake', this.handshakeInfo);\n }\n\n protected async fetch(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse> {\n const isDev = path !== '/' && this.handshakeInfo?.dev\n const secret = await this.getSecret()\n const url = await this.url(path)\n let sparams = Object.fromEntries(url.searchParams.entries())\n const _init = { ...init }\n let params: any = {\n ...sparams,\n }\n\n if (Object.keys(sparams).length > 0) {\n for (let key in sparams) {\n url.searchParams.delete(key)\n }\n }\n\n if (_init?.params) {\n for (let key in _init.params) {\n params[key] = _init.params[key]\n }\n delete _init.params\n }\n\n if (Object.keys(params).length > 0) {\n if (isDev) {\n _init.params = params\n } else {\n const key = Math.random().toString(36).substring(2, 8);\n const enc = await crypto.encrypt({ params, key }, secret.secret)\n url.href = `${url.href}?${key}=${encodeURIComponent(enc)}`\n }\n }\n\n const httpOption: any = {\n method: \"GET\",\n ...this.config?.defaultOptions,\n ..._init,\n headers: await this.getHeaders(path, _init)\n }\n\n if (httpOption?.body) {\n if (isDev) {\n httpOption.body = JSON.stringify(httpOption.body)\n } else {\n httpOption.body = await crypto.encryptBuffer(httpOption.body, secret.secret);\n }\n }\n const res = await xanFetch(url.href, httpOption)\n if (isDev) {\n const value = await res.text()\n const val = JSON.parse(value)\n return {\n success: res.ok,\n message: res.ok ? res.statusText : val,\n data: res.ok ? val : null,\n code: res.status\n }\n }\n const value = await res.arrayBuffer()\n const val = await crypto.decryptBuffer(new Uint8Array(value), secret.secret) as any\n\n return {\n success: res.ok,\n message: res.ok ? res.statusText : (val || res.statusText),\n data: res.ok ? val : null,\n code: res.status\n }\n }\n\n}\n\nexport default Base;\n"],"names":["crypto"],"mappings":"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"}
package/client/Base.mjs CHANGED
@@ -1 +1,147 @@
1
- import t from"../include/crypto.mjs";import e from"xanfetch";const s=new Map;class a{constructor(t){this.loadingHandshake=!1,this.secret_length=0,this.handshakeInfo=null,this.CONTENT_TYPE="application/octet-stream",this.config=Object.assign({},t);const e=new URL(t.url);if(e.search||e.hash)throw new Error(`Invalid config url ${t.url}. Search params or Hash url is not supported in config.url`);if(t.url=`${e.origin}${e.pathname}`,s.has(t.url))throw new Error("Client is Blocked!")}hooksCall(t,...e){if(this.config.hooks&&this.config.hooks[t])return this.config.hooks[t](...e)}async getSecret(){let e=this.config.secret,s=e.substring(0,this.secret_length);return{full:e,secret:s,hash:(await t.hash(s)).substring(0,this.secret_length)}}async url(t){const e=await this.getSecret(),s=this.config.url;return"/"===t&&(t=""),(t=(t=(t=t.trim()).startsWith("/")?t.substring(1):t).endsWith("/")?t.substring(0,t.length-1):t)&&(t=`/${t}`),new URL(`${s}/${e.hash}${t}`)}async getHeaders(e,s){var a,n,i;const r=await this.url(e),h=await this.getSecret();let o={};return this.handshakeInfo&&(o["X-SIGNETURE"]=await t.encrypt({signeture:null===(a=this.handshakeInfo)||void 0===a?void 0:a.signeture,expire:Date.now()+this.handshakeInfo.timeDiffarenc+1e4},h.secret)||""),o=Object.assign(Object.assign(Object.assign(Object.assign({},null===(i=null===(n=this.config)||void 0===n?void 0:n.defaultOptions)||void 0===i?void 0:i.headers),null==s?void 0:s.headers),o),{"Content-Type":this.CONTENT_TYPE,"X-ORIGIN":r.origin,"X-METHOD":((null==s?void 0:s.method)||"GET").toUpperCase()}),o}async awaitForHandshake(){this.loadingHandshake&&await new Promise(t=>{const e=setInterval(()=>{this.loadingHandshake||(clearInterval(e),t(null))},100)}),this.handshakeInfo||await this.handshake()}async handshake(){await this.hooksCall("beforeHandshake"),this.handshakeInfo=null,this.loadingHandshake=!0;let t=this.config.secret.length,e=3*Math.floor(t/4);this.secret_length=Math.floor(Math.random()*(t-e+1))+e;const s=await this.getSecret(),a=await this.fetch("/",{method:"POST",body:{hash:s.hash,clientTime:(new Date).toISOString(),secret:s.secret}});this.handshakeInfo=a.data,this.loadingHandshake=!1,await this.hooksCall("afterHandshake",this.handshakeInfo)}async fetch(s,a){var n,i;const r="/"!==s&&(null===(n=this.handshakeInfo)||void 0===n?void 0:n.dev),h=await this.getSecret(),o=await this.url(s);let c=Object.fromEntries(o.searchParams.entries());const l=Object.assign({},a);let d=Object.assign({},c);if(Object.keys(c).length>0)for(let t in c)o.searchParams.delete(t);if(null==l?void 0:l.params){for(let t in l.params)d[t]=l.params[t];delete l.params}if(Object.keys(d).length>0)if(r)l.params=d;else{const e=await t.encrypt(d,h.secret);o.href=o.href+"?"+encodeURIComponent(e)}const f=Object.assign(Object.assign(Object.assign({method:"GET"},null===(i=this.config)||void 0===i?void 0:i.defaultOptions),l),{headers:await this.getHeaders(s,l)});(null==f?void 0:f.body)&&(f.body=r?JSON.stringify(f.body):await t.encryptBuffer(f.body,h.secret));const u=await e(o.href,f);if(r){const t=await u.text(),e=JSON.parse(t);return{success:u.ok,message:u.ok?u.statusText:e,data:u.ok?e:null,code:u.status}}const g=await u.arrayBuffer(),k=await t.decryptBuffer(new Uint8Array(g),h.secret);return{success:u.ok,message:u.ok?u.statusText:k||u.statusText,data:u.ok?k:null,code:u.status}}}export{a as default};//# sourceMappingURL=Base.mjs.map
1
+ import crypto from'../include/crypto.mjs';import xanFetch from'xanfetch';const Clients = new Map();
2
+ class Base {
3
+ constructor(config) {
4
+ this.loadingHandshake = false;
5
+ this.secret_length = 0;
6
+ this.handshakeInfo = null;
7
+ this.CONTENT_TYPE = "application/octet-stream";
8
+ this.config = Object.assign({}, config);
9
+ const url = new URL(config.url);
10
+ if (url.search || url.hash)
11
+ throw new Error(`Invalid config url ${config.url}. Search params or Hash url is not supported in config.url`);
12
+ config.url = `${url.origin}${url.pathname}`;
13
+ if (Clients.has(config.url)) {
14
+ throw new Error(`Client is Blocked!`);
15
+ }
16
+ }
17
+ hooksCall(hook, ...args) {
18
+ if (this.config.hooks && this.config.hooks[hook]) {
19
+ return this.config.hooks[hook](...args);
20
+ }
21
+ }
22
+ async getSecret() {
23
+ let full = this.config.secret;
24
+ let secret = full.substring(0, this.secret_length);
25
+ let hash = (await crypto.hash(secret)).substring(0, this.secret_length);
26
+ return { full, secret, hash };
27
+ }
28
+ async url(path) {
29
+ const secret = await this.getSecret();
30
+ const base = this.config.url;
31
+ if (path === '/')
32
+ path = '';
33
+ path = path.trim();
34
+ path = path.startsWith('/') ? path.substring(1) : path;
35
+ path = path.endsWith('/') ? path.substring(0, path.length - 1) : path;
36
+ if (path)
37
+ path = `/${path}`;
38
+ return new URL(`${base}/${secret.hash}${path}`);
39
+ }
40
+ async getHeaders(path, init) {
41
+ var _a, _b, _c;
42
+ const url = await this.url(path);
43
+ const secret = await this.getSecret();
44
+ let headers = {};
45
+ if (this.handshakeInfo) {
46
+ headers["X-SIGNETURE"] = await crypto.encrypt({
47
+ signeture: (_a = this.handshakeInfo) === null || _a === void 0 ? void 0 : _a.signeture,
48
+ expire: Date.now() + this.handshakeInfo.timeDiffarenc + 10000 // 10 seconds
49
+ }, secret.secret) || '';
50
+ }
51
+ headers = Object.assign(Object.assign(Object.assign(Object.assign({}, (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.defaultOptions) === null || _c === void 0 ? void 0 : _c.headers), init === null || init === void 0 ? void 0 : init.headers), headers), { 'Content-Type': this.CONTENT_TYPE, "X-ORIGIN": url.origin, "X-METHOD": ((init === null || init === void 0 ? void 0 : init.method) || 'GET').toUpperCase() });
52
+ return headers;
53
+ }
54
+ async awaitForHandshake() {
55
+ if (this.loadingHandshake) {
56
+ await new Promise((resolve) => {
57
+ const interval = setInterval(() => {
58
+ if (!this.loadingHandshake) {
59
+ clearInterval(interval);
60
+ resolve(null);
61
+ }
62
+ }, 100);
63
+ });
64
+ }
65
+ if (!this.handshakeInfo) {
66
+ await this.handshake();
67
+ }
68
+ }
69
+ async handshake() {
70
+ await this.hooksCall('beforeHandshake');
71
+ this.handshakeInfo = null;
72
+ this.loadingHandshake = true;
73
+ let max = this.config.secret.length;
74
+ let min = Math.floor(max / 4) * 3;
75
+ this.secret_length = Math.floor(Math.random() * (max - min + 1)) + min;
76
+ const secret = await this.getSecret();
77
+ const res = await this.fetch('/', {
78
+ method: 'POST',
79
+ body: {
80
+ hash: secret.hash,
81
+ clientTime: new Date().toISOString(),
82
+ secret: secret.secret,
83
+ }
84
+ });
85
+ this.handshakeInfo = res.data;
86
+ this.loadingHandshake = false;
87
+ await this.hooksCall('afterHandshake', this.handshakeInfo);
88
+ }
89
+ async fetch(path, init) {
90
+ var _a, _b;
91
+ const isDev = path !== '/' && ((_a = this.handshakeInfo) === null || _a === void 0 ? void 0 : _a.dev);
92
+ const secret = await this.getSecret();
93
+ const url = await this.url(path);
94
+ let sparams = Object.fromEntries(url.searchParams.entries());
95
+ const _init = Object.assign({}, init);
96
+ let params = Object.assign({}, sparams);
97
+ if (Object.keys(sparams).length > 0) {
98
+ for (let key in sparams) {
99
+ url.searchParams.delete(key);
100
+ }
101
+ }
102
+ if (_init === null || _init === void 0 ? void 0 : _init.params) {
103
+ for (let key in _init.params) {
104
+ params[key] = _init.params[key];
105
+ }
106
+ delete _init.params;
107
+ }
108
+ if (Object.keys(params).length > 0) {
109
+ if (isDev) {
110
+ _init.params = params;
111
+ }
112
+ else {
113
+ const key = Math.random().toString(36).substring(2, 8);
114
+ const enc = await crypto.encrypt({ params, key }, secret.secret);
115
+ url.href = `${url.href}?${key}=${encodeURIComponent(enc)}`;
116
+ }
117
+ }
118
+ const httpOption = Object.assign(Object.assign(Object.assign({ method: "GET" }, (_b = this.config) === null || _b === void 0 ? void 0 : _b.defaultOptions), _init), { headers: await this.getHeaders(path, _init) });
119
+ if (httpOption === null || httpOption === void 0 ? void 0 : httpOption.body) {
120
+ if (isDev) {
121
+ httpOption.body = JSON.stringify(httpOption.body);
122
+ }
123
+ else {
124
+ httpOption.body = await crypto.encryptBuffer(httpOption.body, secret.secret);
125
+ }
126
+ }
127
+ const res = await xanFetch(url.href, httpOption);
128
+ if (isDev) {
129
+ const value = await res.text();
130
+ const val = JSON.parse(value);
131
+ return {
132
+ success: res.ok,
133
+ message: res.ok ? res.statusText : val,
134
+ data: res.ok ? val : null,
135
+ code: res.status
136
+ };
137
+ }
138
+ const value = await res.arrayBuffer();
139
+ const val = await crypto.decryptBuffer(new Uint8Array(value), secret.secret);
140
+ return {
141
+ success: res.ok,
142
+ message: res.ok ? res.statusText : (val || res.statusText),
143
+ data: res.ok ? val : null,
144
+ code: res.status
145
+ };
146
+ }
147
+ }export{Base as default};//# sourceMappingURL=Base.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Base.mjs","sources":["../../src/client/Base.ts"],"sourcesContent":["import crypto from \"../include/crypto\";\r\nimport { HandshakeInfo, HttpRequestInit, SecurequClientConfig, SecurequClientResponse } from \"./types\";\r\nimport xanFetch from 'xanfetch'\r\n\r\n\r\nconst Clients = new Map<string, Base>()\r\n\r\nclass Base {\r\n protected config: SecurequClientConfig;\r\n protected loadingHandshake: boolean = false;\r\n protected secret_length: number = 0;\r\n protected handshakeInfo: HandshakeInfo | null = null;\r\n readonly CONTENT_TYPE = \"application/octet-stream\";\r\n\r\n constructor(config: SecurequClientConfig) {\r\n this.config = {\r\n ...config,\r\n }\r\n const url = new URL(config.url)\r\n if (url.search || url.hash) throw new Error(`Invalid config url ${config.url}. Search params or Hash url is not supported in config.url`)\r\n config.url = `${url.origin}${url.pathname}`\r\n\r\n if (Clients.has(config.url)) {\r\n throw new Error(`Client is Blocked!`);\r\n }\r\n }\r\n\r\n protected hooksCall(hook: keyof NonNullable<SecurequClientConfig['hooks']>, ...args: any[]) {\r\n if (this.config.hooks && this.config.hooks[hook]) {\r\n return (this.config.hooks[hook] as Function)(...args)\r\n }\r\n }\r\n\r\n protected async getSecret() {\r\n let full = this.config.secret\r\n let secret = full.substring(0, this.secret_length)\r\n let hash = (await crypto.hash(secret)).substring(0, this.secret_length)\r\n return { full, secret, hash }\r\n }\r\n\r\n protected async url(path: string) {\r\n const secret = await this.getSecret()\r\n const base = this.config.url;\r\n if (path === '/') path = ''\r\n path = path.trim();\r\n path = path.startsWith('/') ? path.substring(1) : path\r\n path = path.endsWith('/') ? path.substring(0, path.length - 1) : path\r\n if (path) path = `/${path}`\r\n return new URL(`${base}/${secret.hash}${path}`);\r\n }\r\n\r\n protected async getHeaders(path: string, init?: HttpRequestInit) {\r\n const url = await this.url(path)\r\n const secret = await this.getSecret()\r\n let headers: any = {};\r\n if (this.handshakeInfo) {\r\n headers[\"X-SIGNETURE\"] = await crypto.encrypt({\r\n signeture: this.handshakeInfo?.signeture,\r\n expire: Date.now() + this.handshakeInfo!.timeDiffarenc + 10000 // 10 seconds\r\n }, secret.secret) || '';\r\n }\r\n\r\n headers = {\r\n ...this.config?.defaultOptions?.headers,\r\n ...init?.headers,\r\n ...headers,\r\n 'Content-Type': this.CONTENT_TYPE,\r\n \"X-ORIGIN\": url.origin,\r\n \"X-METHOD\": (init?.method || 'GET').toUpperCase()\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n protected async awaitForHandshake() {\r\n if (this.loadingHandshake) {\r\n await new Promise((resolve) => {\r\n const interval = setInterval(() => {\r\n if (!this.loadingHandshake) {\r\n clearInterval(interval);\r\n resolve(null);\r\n }\r\n }, 100);\r\n })\r\n }\r\n if (!this.handshakeInfo) {\r\n await this.handshake();\r\n }\r\n }\r\n\r\n async handshake() {\r\n await this.hooksCall('beforeHandshake');\r\n this.handshakeInfo = null;\r\n this.loadingHandshake = true;\r\n\r\n let max = this.config.secret.length\r\n let min = Math.floor(max / 4) * 3\r\n this.secret_length = Math.floor(Math.random() * (max - min + 1)) + min\r\n\r\n const secret = await this.getSecret()\r\n const res = await this.fetch('/', {\r\n method: 'POST',\r\n body: {\r\n hash: secret.hash,\r\n clientTime: new Date().toISOString(),\r\n secret: secret.secret,\r\n }\r\n })\r\n this.handshakeInfo = res.data\r\n this.loadingHandshake = false;\r\n await this.hooksCall('afterHandshake', this.handshakeInfo);\r\n }\r\n\r\n protected async fetch(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse> {\r\n const isDev = path !== '/' && this.handshakeInfo?.dev\r\n const secret = await this.getSecret()\r\n const url = await this.url(path)\r\n let sparams = Object.fromEntries(url.searchParams.entries())\r\n const _init = { ...init }\r\n let params: any = {\r\n ...sparams,\r\n }\r\n\r\n if (Object.keys(sparams).length > 0) {\r\n for (let key in sparams) {\r\n url.searchParams.delete(key)\r\n }\r\n }\r\n\r\n if (_init?.params) {\r\n for (let key in _init.params) {\r\n params[key] = _init.params[key]\r\n }\r\n delete _init.params\r\n }\r\n\r\n if (Object.keys(params).length > 0) {\r\n if (isDev) {\r\n _init.params = params\r\n } else {\r\n const enc = await crypto.encrypt(params, secret.secret)\r\n url.href = url.href + \"?\" + encodeURIComponent(enc)\r\n }\r\n }\r\n\r\n const httpOption: any = {\r\n method: \"GET\",\r\n ...this.config?.defaultOptions,\r\n ..._init,\r\n headers: await this.getHeaders(path, _init)\r\n }\r\n\r\n if (httpOption?.body) {\r\n if (isDev) {\r\n httpOption.body = JSON.stringify(httpOption.body)\r\n } else {\r\n httpOption.body = await crypto.encryptBuffer(httpOption.body, secret.secret);\r\n }\r\n }\r\n const res = await xanFetch(url.href, httpOption)\r\n if (isDev) {\r\n const value = await res.text()\r\n const val = JSON.parse(value)\r\n return {\r\n success: res.ok,\r\n message: res.ok ? res.statusText : val,\r\n data: res.ok ? val : null,\r\n code: res.status\r\n }\r\n }\r\n const value = await res.arrayBuffer()\r\n const val = await crypto.decryptBuffer(new Uint8Array(value), secret.secret) as any\r\n\r\n return {\r\n success: res.ok,\r\n message: res.ok ? res.statusText : (val || res.statusText),\r\n data: res.ok ? val : null,\r\n code: res.status\r\n }\r\n }\r\n\r\n}\r\n\r\nexport default Base;\r\n"],"names":["crypto","xanFetch","Clients","Map","Base","constructor","config","this","loadingHandshake","secret_length","handshakeInfo","CONTENT_TYPE","Object","assign","url","URL","search","hash","Error","origin","pathname","has","hooksCall","hook","args","hooks","getSecret","full","secret","substring","path","base","trim","startsWith","endsWith","length","getHeaders","init","headers","encrypt","signeture","_a","expire","Date","now","timeDiffarenc","_b","defaultOptions","_c","method","toUpperCase","awaitForHandshake","Promise","resolve","interval","setInterval","clearInterval","handshake","max","min","Math","floor","random","res","fetch","body","clientTime","toISOString","data","isDev","dev","sparams","fromEntries","searchParams","entries","_init","params","keys","key","delete","enc","href","encodeURIComponent","httpOption","JSON","stringify","encryptBuffer","value","text","val","parse","success","ok","message","statusText","code","status","arrayBuffer","decryptBuffer","Uint8Array"],"mappings":"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"}
1
+ {"version":3,"file":"Base.mjs","sources":["../../src/client/Base.ts"],"sourcesContent":["import crypto from \"../include/crypto\";\nimport { HandshakeInfo, HttpRequestInit, SecurequClientConfig, SecurequClientResponse } from \"./types\";\nimport xanFetch from 'xanfetch'\n\n\nconst Clients = new Map<string, Base>()\n\nclass Base {\n protected config: SecurequClientConfig;\n protected loadingHandshake: boolean = false;\n protected secret_length: number = 0;\n protected handshakeInfo: HandshakeInfo | null = null;\n readonly CONTENT_TYPE = \"application/octet-stream\";\n\n constructor(config: SecurequClientConfig) {\n this.config = {\n ...config,\n }\n const url = new URL(config.url)\n if (url.search || url.hash) throw new Error(`Invalid config url ${config.url}. Search params or Hash url is not supported in config.url`)\n config.url = `${url.origin}${url.pathname}`\n\n if (Clients.has(config.url)) {\n throw new Error(`Client is Blocked!`);\n }\n }\n\n protected hooksCall(hook: keyof NonNullable<SecurequClientConfig['hooks']>, ...args: any[]) {\n if (this.config.hooks && this.config.hooks[hook]) {\n return (this.config.hooks[hook] as Function)(...args)\n }\n }\n\n protected async getSecret() {\n let full = this.config.secret\n let secret = full.substring(0, this.secret_length)\n let hash = (await crypto.hash(secret)).substring(0, this.secret_length)\n return { full, secret, hash }\n }\n\n protected async url(path: string) {\n const secret = await this.getSecret()\n const base = this.config.url;\n if (path === '/') path = ''\n path = path.trim();\n path = path.startsWith('/') ? path.substring(1) : path\n path = path.endsWith('/') ? path.substring(0, path.length - 1) : path\n if (path) path = `/${path}`\n return new URL(`${base}/${secret.hash}${path}`);\n }\n\n protected async getHeaders(path: string, init?: HttpRequestInit) {\n const url = await this.url(path)\n const secret = await this.getSecret()\n let headers: any = {};\n if (this.handshakeInfo) {\n headers[\"X-SIGNETURE\"] = await crypto.encrypt({\n signeture: this.handshakeInfo?.signeture,\n expire: Date.now() + this.handshakeInfo!.timeDiffarenc + 10000 // 10 seconds\n }, secret.secret) || '';\n }\n\n headers = {\n ...this.config?.defaultOptions?.headers,\n ...init?.headers,\n ...headers,\n 'Content-Type': this.CONTENT_TYPE,\n \"X-ORIGIN\": url.origin,\n \"X-METHOD\": (init?.method || 'GET').toUpperCase()\n }\n\n return headers;\n }\n\n protected async awaitForHandshake() {\n if (this.loadingHandshake) {\n await new Promise((resolve) => {\n const interval = setInterval(() => {\n if (!this.loadingHandshake) {\n clearInterval(interval);\n resolve(null);\n }\n }, 100);\n })\n }\n if (!this.handshakeInfo) {\n await this.handshake();\n }\n }\n\n async handshake() {\n await this.hooksCall('beforeHandshake');\n this.handshakeInfo = null;\n this.loadingHandshake = true;\n\n let max = this.config.secret.length\n let min = Math.floor(max / 4) * 3\n this.secret_length = Math.floor(Math.random() * (max - min + 1)) + min\n\n const secret = await this.getSecret()\n const res = await this.fetch('/', {\n method: 'POST',\n body: {\n hash: secret.hash,\n clientTime: new Date().toISOString(),\n secret: secret.secret,\n }\n })\n this.handshakeInfo = res.data\n this.loadingHandshake = false;\n await this.hooksCall('afterHandshake', this.handshakeInfo);\n }\n\n protected async fetch(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse> {\n const isDev = path !== '/' && this.handshakeInfo?.dev\n const secret = await this.getSecret()\n const url = await this.url(path)\n let sparams = Object.fromEntries(url.searchParams.entries())\n const _init = { ...init }\n let params: any = {\n ...sparams,\n }\n\n if (Object.keys(sparams).length > 0) {\n for (let key in sparams) {\n url.searchParams.delete(key)\n }\n }\n\n if (_init?.params) {\n for (let key in _init.params) {\n params[key] = _init.params[key]\n }\n delete _init.params\n }\n\n if (Object.keys(params).length > 0) {\n if (isDev) {\n _init.params = params\n } else {\n const key = Math.random().toString(36).substring(2, 8);\n const enc = await crypto.encrypt({ params, key }, secret.secret)\n url.href = `${url.href}?${key}=${encodeURIComponent(enc)}`\n }\n }\n\n const httpOption: any = {\n method: \"GET\",\n ...this.config?.defaultOptions,\n ..._init,\n headers: await this.getHeaders(path, _init)\n }\n\n if (httpOption?.body) {\n if (isDev) {\n httpOption.body = JSON.stringify(httpOption.body)\n } else {\n httpOption.body = await crypto.encryptBuffer(httpOption.body, secret.secret);\n }\n }\n const res = await xanFetch(url.href, httpOption)\n if (isDev) {\n const value = await res.text()\n const val = JSON.parse(value)\n return {\n success: res.ok,\n message: res.ok ? res.statusText : val,\n data: res.ok ? val : null,\n code: res.status\n }\n }\n const value = await res.arrayBuffer()\n const val = await crypto.decryptBuffer(new Uint8Array(value), secret.secret) as any\n\n return {\n success: res.ok,\n message: res.ok ? res.statusText : (val || res.statusText),\n data: res.ok ? val : null,\n code: res.status\n }\n }\n\n}\n\nexport default Base;\n"],"names":[],"mappings":"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"}
package/client/index.d.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  import { HttpRequestInit, SecurequClientResponse } from './types.js';
2
2
  import Base from './Base.js';
3
3
 
4
- declare class SecurequClient extends Base {
5
- send(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse>;
6
- uploadFile(file: File, onProgress?: (p: number) => void): Promise<SecurequClientResponse>;
7
- deleteFile(fileId: string, init?: Omit<HttpRequestInit, 'body' | 'method'>): Promise<SecurequClientResponse>;
8
- get(path: string, init?: Omit<HttpRequestInit, 'body' | 'method'>): Promise<SecurequClientResponse>;
9
- post(path: string, init?: Omit<HttpRequestInit, 'method'>): Promise<SecurequClientResponse>;
10
- put(path: string, init?: Omit<HttpRequestInit, 'method'>): Promise<SecurequClientResponse>;
11
- delete(path: string, init?: Omit<HttpRequestInit, 'method'>): Promise<SecurequClientResponse>;
4
+ declare class SecurequClient extends Base {
5
+ send(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse>;
6
+ uploadFile(file: File, onProgress?: (p: number) => void): Promise<SecurequClientResponse>;
7
+ deleteFile(fileId: string, init?: Omit<HttpRequestInit, 'body' | 'method'>): Promise<SecurequClientResponse>;
8
+ get(path: string, init?: Omit<HttpRequestInit, 'body' | 'method'>): Promise<SecurequClientResponse>;
9
+ post(path: string, init?: Omit<HttpRequestInit, 'method'>): Promise<SecurequClientResponse>;
10
+ put(path: string, init?: Omit<HttpRequestInit, 'method'>): Promise<SecurequClientResponse>;
11
+ delete(path: string, init?: Omit<HttpRequestInit, 'method'>): Promise<SecurequClientResponse>;
12
12
  }
13
13
 
14
14
  export { SecurequClient as default };
package/client/index.js CHANGED
@@ -1 +1,139 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("tslib"),t=require("../include/File.js"),a=require("./Base.js"),i=require("../include/FileScaner.js");class s extends a.default{async send(e,t){await this.awaitForHandshake(),t=await this.hooksCall("beforeRequest",e,t)||t;if("/"===(await this.url(e)).pathname)throw new Error("Path is not allowed");for(let e in null==t?void 0:t.body)(null==t?void 0:t.body[e])instanceof File&&(t.body[e]=await this.uploadFile(t.body[e],null==t?void 0:t.onProgress));const a=await this.fetch(e,t);return["Signeture expired","Request expired"].includes(a.message)?(await this.handshake(),await this.send(e,t)):(await this.hooksCall("afterResponse",a),a)}async uploadFile(a,s){var n,o,l,r,d,h,u;await this.awaitForHandshake();const c=await t.getFileId(a),w=new AbortController;let f=await this.hooksCall("beforeUpload",a,c)||a;const k=null===(d=this.handshakeInfo)||void 0===d?void 0:d.maxFileSize;if(k&&f.size>1024*k)throw new Error(`File size exceeds the limit of ${k/1024} MB`);const p=null===(h=this.handshakeInfo)||void 0===h?void 0:h.chunkSize,y={fileId:c,name:f.name,size:f.size,type:f.type,totalChunks:t.totalChunks(f,p),chunkIndex:0,isFinish:!1},g=async()=>{await this.deleteFile(c),w.abort(),window.removeEventListener("pagehide",g)};window.addEventListener("pagehide",g);try{for(var b,v=!0,m=e.__asyncValues(t.chunkFile(f,p));!(n=(b=await m.next()).done);){r=b.value,v=!1;try{let{chunk:e,chunkIndex:t}=r;if(0===t&&(null===(u=this.handshakeInfo)||void 0===u?void 0:u.checkFileType)&&!i.fileScaner(e))return await g(),{success:!1,message:"Unknown or unsupported file type",data:null,code:0};y.chunkIndex=t,y.isFinish=t+1===y.totalChunks;const n={method:"PUT",signal:w.signal,body:{chunk:e,filemeta:y},onProgress:e=>{if(s){const a=Math.floor((t+1)/y.totalChunks*100),i=Math.floor(e/100/y.totalChunks*100);s(Math.min(a+i,100))}}};await this.hooksCall("beforeUploadChunk",e,y);let o=await this.fetch("/",n);if(!o.success){if(!["Signeture expired","Request expired"].includes(o.message))return await g(),o;await this.handshake(),window.removeEventListener("pagehide",g),o=await this.uploadFile(a,s)}await this.hooksCall("afterUploadChunk",o,y)}finally{v=!0}}}catch(e){o={error:e}}finally{try{v||n||!(l=m.return)||await l.call(m)}finally{if(o)throw o.error}}window.removeEventListener("pagehide",g);const F={success:!0,message:"File uploaded successfully",data:y,code:200};return await this.hooksCall("afterUpload",F,f),F}async deleteFile(e,t){await this.awaitForHandshake();const a=await this.fetch("/",Object.assign(Object.assign({},t),{method:"DELETE",body:{fileId:e}}));return["Signeture expired","Request expired"].includes(a.message)?(await this.handshake(),await this.deleteFile(e,t)):a}async get(e,t){return await this.send(e,t)}async post(e,t){return await this.send(e,Object.assign(Object.assign({},t),{method:"POST"}))}async put(e,t){return await this.send(e,Object.assign(Object.assign({},t),{method:"PUT"}))}async delete(e,t){return await this.send(e,Object.assign(Object.assign({},t),{method:"DELETE"}))}}exports.default=s;//# sourceMappingURL=index.js.map
1
+ 'use strict';Object.defineProperty(exports,'__esModule',{value:true});var tslib=require('tslib'),File$1=require('../include/File.js'),Base=require('./Base.js'),FileScaner=require('../include/FileScaner.js');class SecurequClient extends Base.default {
2
+ async send(path, init) {
3
+ await this.awaitForHandshake();
4
+ init = await this.hooksCall('beforeRequest', path, init) || init;
5
+ const url = await this.url(path);
6
+ if (url.pathname === '/')
7
+ throw new Error("Path is not allowed");
8
+ for (let key in init === null || init === void 0 ? void 0 : init.body) {
9
+ if ((init === null || init === void 0 ? void 0 : init.body[key]) instanceof File) {
10
+ init.body[key] = await this.uploadFile(init.body[key], init === null || init === void 0 ? void 0 : init.onProgress);
11
+ }
12
+ }
13
+ const res = await this.fetch(path, init);
14
+ if (["Signeture expired", "Request expired"].includes(res.message)) {
15
+ await this.handshake();
16
+ return await this.send(path, init);
17
+ }
18
+ await this.hooksCall('afterResponse', res);
19
+ return res;
20
+ }
21
+ async uploadFile(file, onProgress) {
22
+ var _a, e_1, _b, _c;
23
+ var _d, _e, _f;
24
+ await this.awaitForHandshake();
25
+ const fileId = await File$1.getFileId(file);
26
+ const controller = new AbortController();
27
+ let _file = await this.hooksCall('beforeUpload', file, fileId) || file;
28
+ const maxFileSize = (_d = this.handshakeInfo) === null || _d === void 0 ? void 0 : _d.maxFileSize;
29
+ if (maxFileSize && _file.size > maxFileSize * 1024) {
30
+ throw new Error(`File size exceeds the limit of ${maxFileSize / 1024} MB`);
31
+ }
32
+ const chunkSize = (_e = this.handshakeInfo) === null || _e === void 0 ? void 0 : _e.chunkSize;
33
+ // send metadata
34
+ const filemeta = {
35
+ fileId: fileId,
36
+ name: _file.name,
37
+ size: _file.size,
38
+ type: _file.type,
39
+ totalChunks: File$1.totalChunks(_file, chunkSize),
40
+ chunkIndex: 0,
41
+ isFinish: false
42
+ };
43
+ const abort = async () => {
44
+ await this.deleteFile(fileId);
45
+ controller.abort();
46
+ window.removeEventListener("pagehide", abort);
47
+ };
48
+ window.addEventListener("pagehide", abort);
49
+ try {
50
+ for (var _g = true, _h = tslib.__asyncValues(File$1.chunkFile(_file, chunkSize)), _j; _j = await _h.next(), _a = _j.done, !_a;) {
51
+ _c = _j.value;
52
+ _g = false;
53
+ try {
54
+ let { chunk, chunkIndex } = _c;
55
+ if (chunkIndex === 0 && ((_f = this.handshakeInfo) === null || _f === void 0 ? void 0 : _f.checkFileType) && !FileScaner.fileScaner(chunk)) {
56
+ await abort();
57
+ return {
58
+ success: false,
59
+ message: "Unknown or unsupported file type",
60
+ data: null,
61
+ code: 0
62
+ };
63
+ }
64
+ filemeta.chunkIndex = chunkIndex;
65
+ filemeta.isFinish = chunkIndex + 1 === filemeta.totalChunks;
66
+ const info = {
67
+ method: 'PUT',
68
+ signal: controller.signal,
69
+ body: {
70
+ chunk,
71
+ filemeta
72
+ },
73
+ onProgress: (p) => {
74
+ if (onProgress) {
75
+ const totalProgress = Math.floor(((chunkIndex + 1) / filemeta.totalChunks) * 100);
76
+ const currentProgress = Math.floor((p / 100) / filemeta.totalChunks * 100);
77
+ onProgress(Math.min(totalProgress + currentProgress, 100));
78
+ }
79
+ }
80
+ };
81
+ await this.hooksCall('beforeUploadChunk', chunk, filemeta);
82
+ let res = await this.fetch('/', info);
83
+ if (!res.success) {
84
+ if (["Signeture expired", "Request expired"].includes(res.message)) {
85
+ await this.handshake();
86
+ window.removeEventListener("pagehide", abort);
87
+ res = await this.uploadFile(file, onProgress);
88
+ }
89
+ else {
90
+ await abort();
91
+ return res;
92
+ }
93
+ }
94
+ await this.hooksCall('afterUploadChunk', res, filemeta);
95
+ }
96
+ finally {
97
+ _g = true;
98
+ }
99
+ }
100
+ }
101
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
102
+ finally {
103
+ try {
104
+ if (!_g && !_a && (_b = _h.return)) await _b.call(_h);
105
+ }
106
+ finally { if (e_1) throw e_1.error; }
107
+ }
108
+ window.removeEventListener("pagehide", abort);
109
+ const info = {
110
+ success: true,
111
+ message: 'File uploaded successfully',
112
+ data: filemeta,
113
+ code: 200
114
+ };
115
+ await this.hooksCall('afterUpload', info, _file);
116
+ return info;
117
+ }
118
+ async deleteFile(fileId, init) {
119
+ await this.awaitForHandshake();
120
+ const res = await this.fetch('/', Object.assign(Object.assign({}, init), { method: 'DELETE', body: { fileId } }));
121
+ if (["Signeture expired", "Request expired"].includes(res.message)) {
122
+ await this.handshake();
123
+ return await this.deleteFile(fileId, init);
124
+ }
125
+ return res;
126
+ }
127
+ async get(path, init) {
128
+ return await this.send(path, init);
129
+ }
130
+ async post(path, init) {
131
+ return await this.send(path, Object.assign(Object.assign({}, init), { method: "POST" }));
132
+ }
133
+ async put(path, init) {
134
+ return await this.send(path, Object.assign(Object.assign({}, init), { method: "PUT" }));
135
+ }
136
+ async delete(path, init) {
137
+ return await this.send(path, Object.assign(Object.assign({}, init), { method: "DELETE" }));
138
+ }
139
+ }exports.default=SecurequClient;//# sourceMappingURL=index.js.map