@cocreate/file-server 1.18.0 → 1.18.2

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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [1.18.2](https://github.com/CoCreate-app/CoCreate-file-server/compare/v1.18.1...v1.18.2) (2025-04-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * query attributes ([007e1fc](https://github.com/CoCreate-app/CoCreate-file-server/commit/007e1fcff257caca077a507563a2f63307b74c93))
7
+
8
+ ## [1.18.1](https://github.com/CoCreate-app/CoCreate-file-server/compare/v1.18.0...v1.18.1) (2024-12-22)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * pass url to render.HTML ([c5827c3](https://github.com/CoCreate-app/CoCreate-file-server/commit/c5827c3247998014d2717b0ff426e98c9dffc145))
14
+
1
15
  # [1.18.0](https://github.com/CoCreate-app/CoCreate-file-server/compare/v1.17.1...v1.18.0) (2024-11-04)
2
16
 
3
17
 
package/docs/index.html CHANGED
@@ -1,228 +1,228 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1" />
7
- <title>CoCreate-file-server Documentation | CoCreateJS</title>
8
- <link
9
- rel="icon"
10
- type="image/png"
11
- sizes="32x32"
12
- href="https://cocreate.app/images/favicon.ico" />
13
- <meta
14
- name="description"
15
- content="A simple HTML5 and pure javascript component. Easy configuration using data-attributes and highly styleable." />
16
- <meta
17
- name="keywords"
18
- content="helper classes, utility classes, css framework, css library, inline style classes" />
19
- <meta name="robots" content="index,follow" />
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <title>CoCreate-file-server Documentation | CoCreateJS</title>
8
+ <link
9
+ rel="icon"
10
+ type="image/png"
11
+ sizes="32x32"
12
+ href="https://cocreate.app/images/favicon.ico" />
13
+ <meta
14
+ name="description"
15
+ content="A simple HTML5 and pure javascript component. Easy configuration using data-attributes and highly styleable." />
16
+ <meta
17
+ name="keywords"
18
+ content="helper classes, utility classes, css framework, css library, inline style classes" />
19
+ <meta name="robots" content="index,follow" />
20
20
 
21
- <!-- CoCreate CSS CDN -->
22
- </head>
21
+ <!-- CoCreate CSS CDN -->
22
+ </head>
23
23
 
24
- <body>
25
- <div array="" object="" key="" id="cocreate-file-server">
26
- <div
27
- class="display:flex flex-wrap:wrap justify-content:space-between margin:10px">
28
- <div class="display:flex align-items:center">
29
- <h2>CoCreate-file-server</h2>
30
- </div>
31
- <div
32
- class="display:flex align-items:center font-size:20px"
33
- share-height="600"
34
- share-width="500"
35
- share-media="https://via.placeholder.com/300/09f/fff.png">
36
- <a
37
- href="https://github.com/CoCreate-app/CoCreate-file-server"
38
- target="_blank"
39
- class="margin-right:15px"
40
- ><i class="fab fa-github"></i
41
- ></a>
42
- <a
43
- class="margin-right:15px share"
44
- share-network="twitter"
45
- title="Share on twitter"
46
- ><i class="fab fa-twitter"></i
47
- ></a>
48
- <a
49
- class="margin-right:15px share"
50
- share-network="facebook"
51
- title="Share on Facebook"
52
- ><i class="fab fa-facebook"></i
53
- ></a>
54
- <a
55
- class="margin-right:15px share"
56
- share-network="instagram"
57
- title="Share on instagram"
58
- ><i class="fab fa-instagram"></i
59
- ></a>
60
- <a
61
- class="margin-right:15px share"
62
- share-network="share"
63
- title="Share on share"
64
- ><i class="fas fa-share-alt"></i
65
- ></a>
66
- </div>
67
- </div>
68
- <h1 class="max-width:500px margin:20px_10px">
69
- A simple HTML5, CSS and pure javascript component. Easy
70
- configuration using data-attributes and highly styleable.
71
- </h1>
72
- <div id="file-server-section" class="display:flex flex-wrap:wrap">
73
- <div class="flex-grow:1 width:300px padding:20px_10px">
74
- <h2
75
- class="border-bottom:1px_solid_lightgrey padding:5px_0px">
76
- Install
77
- </h2>
78
- <pre
79
- class="margin-top:15px"><code class="language-javascript">npm install cocreate-file-server</code></pre>
80
- <p class="padding:10px_0px">Or you can use cdn link:</p>
81
- <pre><code class="language-javascript">https://cdn.cocreate.app/js/CoCreate-file-server.min.js</code></pre>
24
+ <body>
25
+ <div array="" object="" key="" id="cocreate-file-server">
26
+ <div
27
+ class="display:flex flex-wrap:wrap justify-content:space-between margin:10px">
28
+ <div class="display:flex align-items:center">
29
+ <h2>CoCreate-file-server</h2>
30
+ </div>
31
+ <div
32
+ class="display:flex align-items:center font-size:20px"
33
+ share-height="600"
34
+ share-width="500"
35
+ share-media="https://via.placeholder.com/300/09f/fff.png">
36
+ <a
37
+ href="https://github.com/CoCreate-app/CoCreate-file-server"
38
+ target="_blank"
39
+ class="margin-right:15px"
40
+ ><i class="fab fa-github"></i
41
+ ></a>
42
+ <a
43
+ class="margin-right:15px share"
44
+ share-network="twitter"
45
+ title="Share on twitter"
46
+ ><i class="fab fa-twitter"></i
47
+ ></a>
48
+ <a
49
+ class="margin-right:15px share"
50
+ share-network="facebook"
51
+ title="Share on Facebook"
52
+ ><i class="fab fa-facebook"></i
53
+ ></a>
54
+ <a
55
+ class="margin-right:15px share"
56
+ share-network="instagram"
57
+ title="Share on instagram"
58
+ ><i class="fab fa-instagram"></i
59
+ ></a>
60
+ <a
61
+ class="margin-right:15px share"
62
+ share-network="share"
63
+ title="Share on share"
64
+ ><i class="fas fa-share-alt"></i
65
+ ></a>
66
+ </div>
67
+ </div>
68
+ <h1 class="max-width:500px margin:20px_10px">
69
+ A simple HTML5, CSS and pure javascript component. Easy
70
+ configuration using data-attributes and highly styleable.
71
+ </h1>
72
+ <div id="file-server-section" class="display:flex flex-wrap:wrap">
73
+ <div class="flex-grow:1 width:300px padding:20px_10px">
74
+ <h2
75
+ class="border-bottom:1px_solid_lightgrey padding:5px_0px">
76
+ Install
77
+ </h2>
78
+ <pre
79
+ class="margin-top:15px"><code class="language-javascript">npm install cocreate-file-server</code></pre>
80
+ <p class="padding:10px_0px">Or you can use cdn link:</p>
81
+ <pre><code class="language-javascript">https://cdn.cocreate.app/js/CoCreate-file-server.min.js</code></pre>
82
82
 
83
- <h2
84
- class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
85
- Usage
86
- </h2>
87
- <p class="padding:10px_0px">file-server usage content</p>
88
- <pre><code class="language-html">&lt;div&gt;&lt;/div&gt;</code></pre>
83
+ <h2
84
+ class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
85
+ Usage
86
+ </h2>
87
+ <p class="padding:10px_0px">file-server usage content</p>
88
+ <pre><code class="language-html">&lt;div&gt;&lt;/div&gt;</code></pre>
89
89
 
90
- <h2
91
- class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
92
- Reference
93
- </h2>
94
- <p class="padding:10px_0px">
95
- This is file-server reference content
96
- </p>
97
- <pre><code class="language-javascript">&lt;div&gt;&lt;/div&gt;</code></pre>
98
- <p class="padding:10px_0px">
99
- This is file-server reference content
100
- </p>
90
+ <h2
91
+ class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
92
+ Reference
93
+ </h2>
94
+ <p class="padding:10px_0px">
95
+ This is file-server reference content
96
+ </p>
97
+ <pre><code class="language-javascript">&lt;div&gt;&lt;/div&gt;</code></pre>
98
+ <p class="padding:10px_0px">
99
+ This is file-server reference content
100
+ </p>
101
101
 
102
- <h2
103
- class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
104
- Attributes
105
- </h2>
106
- <ul class="list-style-type:none">
107
- <li
108
- class="padding:15px_0px border-bottom:1px_solid_lightgrey">
109
- <h4>
110
- <span>file-server</span>
111
- <span class="cocreate-badge success"
112
- >string</span
113
- >
114
- <span class="cocreate-badge warning"
115
- >optional</span
116
- >
117
- </h4>
118
- <p>file-server-attribute</p>
119
- </li>
120
- <li
121
- class="padding:15px_0px border-bottom:1px_solid_lightgrey">
122
- <h4>
123
- <span>file-server</span>
124
- <span class="cocreate-badge success"
125
- >string</span
126
- >
127
- <span class="cocreate-badge warning"
128
- >optional</span
129
- >
130
- </h4>
131
- <p>file-server-attribute</p>
132
- </li>
133
- </ul>
134
- </div>
102
+ <h2
103
+ class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
104
+ Attributes
105
+ </h2>
106
+ <ul class="list-style-type:none">
107
+ <li
108
+ class="padding:15px_0px border-bottom:1px_solid_lightgrey">
109
+ <h4>
110
+ <span>file-server</span>
111
+ <span class="cocreate-badge success"
112
+ >string</span
113
+ >
114
+ <span class="cocreate-badge warning"
115
+ >optional</span
116
+ >
117
+ </h4>
118
+ <p>file-server-attribute</p>
119
+ </li>
120
+ <li
121
+ class="padding:15px_0px border-bottom:1px_solid_lightgrey">
122
+ <h4>
123
+ <span>file-server</span>
124
+ <span class="cocreate-badge success"
125
+ >string</span
126
+ >
127
+ <span class="cocreate-badge warning"
128
+ >optional</span
129
+ >
130
+ </h4>
131
+ <p>file-server-attribute</p>
132
+ </li>
133
+ </ul>
134
+ </div>
135
135
 
136
- <div
137
- class="flex-grow:1 width:300px padding:0px_10px margin:20px_0px border-bottom:1px_solid_lightgrey">
138
- <!-- SandBox -->
139
- <h2
140
- class="border-bottom:1px_solid_lightgrey padding:5px_0px">
141
- Demo
142
- </h2>
143
- <div
144
- class="position:sticky top:0 padding:10px_0px height:100vh">
145
- <!-- SandBox -->
146
- <div
147
- class="display:flex flex-direction:column position:relative overflow:hidden card border-radius:2px width:auto height:600px margin-top:20px"
148
- id="playground">
149
- <div
150
- id="demo-code"
151
- resizable
152
- class="position:relative height:50%">
153
- <textarea
154
- type="code"
155
- lang="html"
156
- array="demos"
157
- object=""
158
- key="demo"
159
- save="false"
160
- id="demo"
161
- class="height:100% width:100% outline:none border:none resize:none padding:5px"></textarea>
162
- <div
163
- resize="bottom"
164
- class="background:lightgrey"></div>
165
- </div>
136
+ <div
137
+ class="flex-grow:1 width:300px padding:0px_10px margin:20px_0px border-bottom:1px_solid_lightgrey">
138
+ <!-- SandBox -->
139
+ <h2
140
+ class="border-bottom:1px_solid_lightgrey padding:5px_0px">
141
+ Demo
142
+ </h2>
143
+ <div
144
+ class="position:sticky top:0 padding:10px_0px height:100vh">
145
+ <!-- SandBox -->
146
+ <div
147
+ class="display:flex flex-direction:column position:relative overflow:hidden card border-radius:2px width:auto height:600px margin-top:20px"
148
+ id="playground">
149
+ <div
150
+ id="demo-code"
151
+ resizable
152
+ class="position:relative height:50%">
153
+ <textarea
154
+ type="code"
155
+ lang="html"
156
+ array="demos"
157
+ object=""
158
+ key="demo"
159
+ save="false"
160
+ id="demo"
161
+ class="height:100% width:100% outline:none border:none resize:none padding:5px"></textarea>
162
+ <div
163
+ resize="bottom"
164
+ class="background:lightgrey"></div>
165
+ </div>
166
166
 
167
- <div
168
- id="demo-preview"
169
- class="position:relative overflow:auto background-color:white">
170
- <div
171
- get-value="#demo"
172
- class="padding:20px"></div>
173
- </div>
167
+ <div
168
+ id="demo-preview"
169
+ class="position:relative overflow:auto background-color:white">
170
+ <div
171
+ get-value="#demo"
172
+ class="padding:20px"></div>
173
+ </div>
174
174
 
175
- <div
176
- class="font-size:20px position:absolute top:10px right:10px opacity:0.6">
177
- <a
178
- class="margin-right:10px"
179
- id="eye"
180
- show="#eye-slash"
181
- hide="#eye, #demo-preview"
182
- toggle="code-height"
183
- toggle-selector="#demo-code"
184
- ><i class="far fa-eye"></i
185
- ></a>
186
- <a
187
- class="margin-right:10px"
188
- hidden
189
- id="eye-slash"
190
- show="#eye, #demo-preview"
191
- hide="#eye-slash"
192
- toggle="code-height"
193
- toggle-selector="#demo-code"
194
- ><i class="fas fa-eye-slash"></i
195
- ></a>
196
- <a
197
- class="margin-right:10px"
198
- id="code"
199
- show="#code-slash"
200
- hide="#code, #demo-code"
201
- ><i class="fa fa-code"></i
202
- ></a>
203
- <a
204
- class="margin-right:10px"
205
- hidden
206
- id="code-slash"
207
- show="#code, #demo-code"
208
- hide="#code-slash"
209
- ><i class="fas fa-code"></i
210
- ></a>
211
- <a
212
- class="margin-right:5px"
213
- fullscreen
214
- target="#playground"
215
- ><i class="fas fa-expand"></i
216
- ></a>
217
- </div>
218
- </div>
219
- <!-- End SandBox -->
220
- </div>
221
- </div>
222
- </div>
223
- </div>
175
+ <div
176
+ class="font-size:20px position:absolute top:10px right:10px opacity:0.6">
177
+ <a
178
+ class="margin-right:10px"
179
+ id="eye"
180
+ show="#eye-slash"
181
+ hide="#eye, #demo-preview"
182
+ toggle="code-height"
183
+ toggle-query="#demo-code"
184
+ ><i class="far fa-eye"></i
185
+ ></a>
186
+ <a
187
+ class="margin-right:10px"
188
+ hidden
189
+ id="eye-slash"
190
+ show="#eye, #demo-preview"
191
+ hide="#eye-slash"
192
+ toggle="code-height"
193
+ toggle-query="#demo-code"
194
+ ><i class="fas fa-eye-slash"></i
195
+ ></a>
196
+ <a
197
+ class="margin-right:10px"
198
+ id="code"
199
+ show="#code-slash"
200
+ hide="#code, #demo-code"
201
+ ><i class="fa fa-code"></i
202
+ ></a>
203
+ <a
204
+ class="margin-right:10px"
205
+ hidden
206
+ id="code-slash"
207
+ show="#code, #demo-code"
208
+ hide="#code-slash"
209
+ ><i class="fas fa-code"></i
210
+ ></a>
211
+ <a
212
+ class="margin-right:5px"
213
+ fullscreen
214
+ target="#playground"
215
+ ><i class="fas fa-expand"></i
216
+ ></a>
217
+ </div>
218
+ </div>
219
+ <!-- End SandBox -->
220
+ </div>
221
+ </div>
222
+ </div>
223
+ </div>
224
224
 
225
- <!--CoCreateJS-->
226
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
227
- </body>
225
+ <!--CoCreateJS-->
226
+ <script src="https://CoCreate.app/dist/CoCreate.js"></script>
227
+ </body>
228
228
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/file-server",
3
- "version": "1.18.0",
3
+ "version": "1.18.2",
4
4
  "description": "A simple file-server component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "file-server",
package/src/index.js CHANGED
@@ -21,250 +21,312 @@
21
21
  // For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app.
22
22
 
23
23
  class CoCreateFileSystem {
24
- constructor(render, sitemap) {
25
- this.render = render
26
- this.sitemap = sitemap
27
- }
28
-
29
- async send(req, res, crud, organization, valideUrl) {
30
- try {
31
- const hostname = valideUrl.hostname;
32
-
33
- let data = {
34
- method: 'object.read',
35
- host: hostname,
36
- array: 'files',
37
- $filter: {
38
- query: {
39
- host: { $in: [hostname, '*'] }
40
- },
41
- limit: 1
42
- }
43
- }
44
-
45
- let organization_id
46
- if (!organization || organization.error) {
47
- let hostNotFound = await getDefaultFile('/hostNotFound.html')
48
- return sendResponse(hostNotFound.object[0].src, 404, { 'Content-Type': 'text/html' })
49
- }
50
-
51
- organization_id = organization._id
52
- data.organization_id = organization_id
53
-
54
- res.setHeader('organization', organization_id)
55
- res.setHeader('storage', !!organization.storage);
56
- res.setHeader('Access-Control-Allow-Origin', '*');
57
- res.setHeader('Access-Control-Allow-Methods', '');
58
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
59
-
60
- let active = crud.wsManager.organizations.get(organization_id)
61
- if (active === false) {
62
- let balanceFalse = await getDefaultFile('/balanceFalse.html')
63
- return sendResponse(balanceFalse.object[0].src, 403, { 'Content-Type': 'text/html', 'Account-Balance': 'false', 'storage': organization.storage })
64
- }
65
-
66
- let parameters = valideUrl.searchParams;
67
- if (parameters.size) {
68
- console.log('parameters', parameters)
69
- }
70
-
71
- let pathname = valideUrl.pathname;
72
-
73
- if (pathname.endsWith('/')) {
74
- pathname += "index.html";
75
- } else if (!pathname.startsWith('/.well-known/acme-challenge')) {
76
- let directory = pathname.split("/").slice(-1)[0];
77
- if (!directory.includes('.'))
78
- pathname += "/index.html";
79
- }
80
-
81
- data.$filter.query.pathname = pathname
82
-
83
- let file
84
- if (pathname.startsWith('/dist') || pathname.startsWith('/admin') || ['/403.html', '/404.html', '/offline.html', '/manifest.webmanifest', '/service-worker.js'].includes(pathname))
85
- file = await getDefaultFile(pathname)
86
- else
87
- file = await crud.send(data);
88
-
89
- if (!file || !file.object || !file.object[0]) {
90
- pathname = valideUrl.pathname
91
- let lastIndex = pathname.lastIndexOf('/');
92
- let wildcardPath = pathname.substring(0, lastIndex + 1);
93
- let wildcard = pathname.substring(lastIndex + 1);
94
-
95
- if (wildcard.includes('.')) {
96
- let fileLastIndex = wildcard.lastIndexOf('.');
97
- let fileExtension = wildcard.substring(fileLastIndex);
98
- wildcard = wildcardPath + '*' + fileExtension; // Create wildcard for file name
99
- } else {
100
- wildcard = wildcardPath + '*/index.html'; // Append '*' if it's just a path or folder
101
- }
102
-
103
- data.$filter.query.pathname = wildcard
104
- file = await crud.send(data);
105
- }
106
-
107
- if (!file || !file.object || !file.object[0]) {
108
- let pageNotFound = await getDefaultFile('/404.html')
109
- return sendResponse(pageNotFound.object[0].src, 404, { 'Content-Type': 'text/html' })
110
- }
111
-
112
- file = file.object[0]
113
- if (!file['public'] || file['public'] === "false") {
114
- let pageForbidden = await getDefaultFile('/403.html')
115
- return sendResponse(pageForbidden.object[0].src, 403, { 'Content-Type': 'text/html' })
116
- }
117
-
118
- let src;
119
- if (file['src'])
120
- src = file['src'];
121
- else {
122
- let fileSrc = await crud.send({
123
- method: 'object.read',
124
- host: hostname,
125
- array: file['array'],
126
- object: {
127
- _id: file._id
128
- },
129
- organization_id
130
- });
131
- src = fileSrc[file['name']];
132
- }
133
-
134
- if (!src) {
135
- let pageNotFound = await getDefaultFile('/404.html')
136
- return sendResponse(pageNotFound.object[0].src, 404, { 'Content-Type': 'text/html' })
137
- }
138
-
139
-
140
- let modifiedOn = file.modified || file.created
141
- if (modifiedOn) {
142
- modifiedOn = modifiedOn.on
143
- if (modifiedOn instanceof Date)
144
- modifiedOn = modifiedOn.toISOString()
145
- res.setHeader('Last-Modified', modifiedOn);
146
- }
147
-
148
- let contentType = file['content-type'] || 'text/html';
149
-
150
- if (/^data:image\/[a-zA-Z0-9+.-]+;base64,([A-Za-z0-9+/]+={0,2})$/.test(src)) {
151
- src = src.replace(/^data:image\/(png|jpeg|jpg);base64,/, '');
152
- src = Buffer.from(src, 'base64');
153
- } else if (/^([A-Za-z0-9+/]+={0,2})$/.test(src)) {
154
- src = Buffer.from(src, 'base64');
155
- } else if (contentType === 'text/html') {
156
- try {
157
- src = await this.render.HTML(src, organization_id);
158
- } catch (err) {
159
- console.warn('server-side-render: ' + err.message)
160
- }
161
- } else if (contentType === 'text/xml' || contentType === 'application/xml') {
162
- const protocol = 'https://' // || req.headers['x-forwarded-proto'] || req.protocol;
163
- src = src.replaceAll('{{$host}}', `${protocol}${hostname}`)
164
- }
165
-
166
- sendResponse(src, 200, { 'Content-Type': contentType })
167
- this.sitemap.check(file, hostname);
168
-
169
- function sendResponse(src, statusCode, headers) {
170
- try {
171
- if (src instanceof Uint8Array) {
172
- src = Buffer.from(src);
173
- } else if (Buffer.isBuffer(src)) {
174
- console.log('buffer')
175
- return
176
- } else if (typeof src === 'object') {
177
- src = JSON.stringify(src);
178
- }
179
-
180
- if (organization_id)
181
- crud.wsManager.emit("setBandwidth", {
182
- type: 'out',
183
- data: src,
184
- organization_id
185
- });
186
- res.writeHead(statusCode, headers);
187
- return res.end(src);
188
- } catch (error) {
189
- console.log(error)
190
- }
191
- }
192
-
193
- async function getDefaultFile(fileName) {
194
- data.$filter.query.pathname = fileName
195
- // data.$filter.query.$or[0] = { pathname: fileName }
196
- let defaultFile
197
- if (fileName !== '/hostNotFound.html')
198
- defaultFile = await crud.send(data);
199
-
200
- if (defaultFile && defaultFile.object && defaultFile.object[0] && defaultFile.object[0].src) {
201
- return defaultFile
202
- } else {
203
- data.$filter.query.host.$in = ['*']
204
- data.organization_id = process.env.organization_id
205
-
206
- if (fileName.startsWith('/admin'))
207
- data.$filter.query.pathname = '/superadmin' + fileName.replace('/admin', '')
208
-
209
- defaultFile = await crud.send(data)
210
-
211
- if (fileName !== '/hostNotFound.html') {
212
- crud.wsManager.emit("setBandwidth", {
213
- type: 'out',
214
- data,
215
- organization_id
216
- });
217
-
218
- crud.wsManager.emit("setBandwidth", {
219
- type: 'in',
220
- data: defaultFile,
221
- organization_id
222
- });
223
- }
224
-
225
- if (defaultFile && defaultFile.object && defaultFile.object[0] && defaultFile.object[0].src) {
226
- if (fileName.startsWith('/admin')) {
227
- data.object[0].directory = 'admin'
228
- data.object[0].path = '/admin' + data.object[0].path.replace('/superadmin', '')
229
- data.object[0].pathname = fileName
230
- }
231
-
232
- crud.send({
233
- method: 'object.create',
234
- host: hostname,
235
- array: 'files',
236
- object: defaultFile.object[0],
237
- organization_id
238
- })
239
-
240
- return defaultFile
241
- } else {
242
- switch (fileName) {
243
- case '/403.html':
244
- defaultFile.object = [{ src: `${pathname} access not allowed for ${organization_id}` }]
245
- break;
246
- case '/404.html':
247
- defaultFile.object = [{ src: `${pathname} could not be found for ${organization_id}` }];
248
- break;
249
- case '/balanceFalse.html':
250
- defaultFile.object = [{ src: 'This organizations account balance has fallen bellow 0: ' }];
251
- break;
252
- case '/hostNotFound.html':
253
- defaultFile.object = [{ src: 'An organization could not be found using the host: ' + hostname + ' in platformDB: ' + process.env.organization_id }];
254
- break;
255
- }
256
- return defaultFile
257
- }
258
- }
259
- }
260
-
261
-
262
- } catch (error) {
263
- res.writeHead(400, { 'Content-Type': 'text/plain' });
264
- res.end('Invalid host format');
265
- }
266
- }
267
-
24
+ constructor(render, sitemap) {
25
+ this.render = render;
26
+ this.sitemap = sitemap;
27
+ }
28
+
29
+ async send(req, res, crud, organization, valideUrl) {
30
+ try {
31
+ const hostname = valideUrl.hostname;
32
+
33
+ let data = {
34
+ method: "object.read",
35
+ host: hostname,
36
+ array: "files",
37
+ $filter: {
38
+ query: {
39
+ host: { $in: [hostname, "*"] }
40
+ },
41
+ limit: 1
42
+ }
43
+ };
44
+
45
+ let organization_id;
46
+ if (!organization || organization.error) {
47
+ let hostNotFound = await getDefaultFile("/hostNotFound.html");
48
+ return sendResponse(hostNotFound.object[0].src, 404, {
49
+ "Content-Type": "text/html"
50
+ });
51
+ }
52
+
53
+ organization_id = organization._id;
54
+ data.organization_id = organization_id;
55
+
56
+ res.setHeader("organization", organization_id);
57
+ res.setHeader("storage", !!organization.storage);
58
+ res.setHeader("Access-Control-Allow-Origin", "*");
59
+ res.setHeader("Access-Control-Allow-Methods", "");
60
+ res.setHeader(
61
+ "Access-Control-Allow-Headers",
62
+ "Content-Type, Authorization"
63
+ );
64
+
65
+ let active = crud.wsManager.organizations.get(organization_id);
66
+ if (active === false) {
67
+ let balanceFalse = await getDefaultFile("/balanceFalse.html");
68
+ return sendResponse(balanceFalse.object[0].src, 403, {
69
+ "Content-Type": "text/html",
70
+ "Account-Balance": "false",
71
+ storage: organization.storage
72
+ });
73
+ }
74
+
75
+ let parameters = valideUrl.searchParams;
76
+ if (parameters.size) {
77
+ console.log("parameters", parameters);
78
+ }
79
+
80
+ let pathname = valideUrl.pathname;
81
+
82
+ if (pathname.endsWith("/")) {
83
+ pathname += "index.html";
84
+ } else if (!pathname.startsWith("/.well-known/acme-challenge")) {
85
+ let directory = pathname.split("/").slice(-1)[0];
86
+ if (!directory.includes(".")) pathname += "/index.html";
87
+ }
88
+
89
+ data.$filter.query.pathname = pathname;
90
+
91
+ let file;
92
+ if (
93
+ pathname.startsWith("/dist") ||
94
+ pathname.startsWith("/admin") ||
95
+ [
96
+ "/403.html",
97
+ "/404.html",
98
+ "/offline.html",
99
+ "/manifest.webmanifest",
100
+ "/service-worker.js"
101
+ ].includes(pathname)
102
+ )
103
+ file = await getDefaultFile(pathname);
104
+ else file = await crud.send(data);
105
+
106
+ if (!file || !file.object || !file.object[0]) {
107
+ pathname = valideUrl.pathname;
108
+ let lastIndex = pathname.lastIndexOf("/");
109
+ let wildcardPath = pathname.substring(0, lastIndex + 1);
110
+ let wildcard = pathname.substring(lastIndex + 1);
111
+
112
+ if (wildcard.includes(".")) {
113
+ let fileLastIndex = wildcard.lastIndexOf(".");
114
+ let fileExtension = wildcard.substring(fileLastIndex);
115
+ wildcard = wildcardPath + "*" + fileExtension; // Create wildcard for file name
116
+ } else {
117
+ wildcard = wildcardPath + "*/index.html"; // Append '*' if it's just a path or folder
118
+ }
119
+
120
+ data.$filter.query.pathname = wildcard;
121
+ file = await crud.send(data);
122
+ }
123
+
124
+ if (!file || !file.object || !file.object[0]) {
125
+ let pageNotFound = await getDefaultFile("/404.html");
126
+ return sendResponse(pageNotFound.object[0].src, 404, {
127
+ "Content-Type": "text/html"
128
+ });
129
+ }
130
+
131
+ file = file.object[0];
132
+ if (!file["public"] || file["public"] === "false") {
133
+ let pageForbidden = await getDefaultFile("/403.html");
134
+ return sendResponse(pageForbidden.object[0].src, 403, {
135
+ "Content-Type": "text/html"
136
+ });
137
+ }
138
+
139
+ let src;
140
+ if (file["src"]) src = file["src"];
141
+ else {
142
+ let fileSrc = await crud.send({
143
+ method: "object.read",
144
+ host: hostname,
145
+ array: file["array"],
146
+ object: {
147
+ _id: file._id
148
+ },
149
+ organization_id
150
+ });
151
+ src = fileSrc[file["name"]];
152
+ }
153
+
154
+ if (!src) {
155
+ let pageNotFound = await getDefaultFile("/404.html");
156
+ return sendResponse(pageNotFound.object[0].src, 404, {
157
+ "Content-Type": "text/html"
158
+ });
159
+ }
160
+
161
+ let modifiedOn = file.modified || file.created;
162
+ if (modifiedOn) {
163
+ modifiedOn = modifiedOn.on;
164
+ if (modifiedOn instanceof Date)
165
+ modifiedOn = modifiedOn.toISOString();
166
+ res.setHeader("Last-Modified", modifiedOn);
167
+ }
168
+
169
+ let contentType = file["content-type"] || "text/html";
170
+
171
+ if (
172
+ /^data:image\/[a-zA-Z0-9+.-]+;base64,([A-Za-z0-9+/]+={0,2})$/.test(
173
+ src
174
+ )
175
+ ) {
176
+ src = src.replace(/^data:image\/(png|jpeg|jpg);base64,/, "");
177
+ src = Buffer.from(src, "base64");
178
+ } else if (/^([A-Za-z0-9+/]+={0,2})$/.test(src)) {
179
+ src = Buffer.from(src, "base64");
180
+ } else if (contentType === "text/html") {
181
+ try {
182
+ src = await this.render.HTML(
183
+ src,
184
+ organization_id,
185
+ valideUrl
186
+ );
187
+ } catch (err) {
188
+ console.warn("server-side-render: " + err.message);
189
+ }
190
+ } else if (
191
+ contentType === "text/xml" ||
192
+ contentType === "application/xml"
193
+ ) {
194
+ const protocol = "https://"; // || req.headers['x-forwarded-proto'] || req.protocol;
195
+ src = src.replaceAll("{{$host}}", `${protocol}${hostname}`);
196
+ }
197
+
198
+ sendResponse(src, 200, { "Content-Type": contentType });
199
+ this.sitemap.check(file, hostname);
200
+
201
+ function sendResponse(src, statusCode, headers) {
202
+ try {
203
+ if (src instanceof Uint8Array) {
204
+ src = Buffer.from(src);
205
+ } else if (Buffer.isBuffer(src)) {
206
+ console.log("buffer");
207
+ return;
208
+ } else if (typeof src === "object") {
209
+ src = JSON.stringify(src);
210
+ }
211
+
212
+ if (organization_id)
213
+ crud.wsManager.emit("setBandwidth", {
214
+ type: "out",
215
+ data: src,
216
+ organization_id
217
+ });
218
+ res.writeHead(statusCode, headers);
219
+ return res.end(src);
220
+ } catch (error) {
221
+ console.log(error);
222
+ }
223
+ }
224
+
225
+ async function getDefaultFile(fileName) {
226
+ data.$filter.query.pathname = fileName;
227
+ // data.$filter.query.$or[0] = { pathname: fileName }
228
+ let defaultFile;
229
+ if (fileName !== "/hostNotFound.html")
230
+ defaultFile = await crud.send(data);
231
+
232
+ if (
233
+ defaultFile &&
234
+ defaultFile.object &&
235
+ defaultFile.object[0] &&
236
+ defaultFile.object[0].src
237
+ ) {
238
+ return defaultFile;
239
+ } else {
240
+ data.$filter.query.host.$in = ["*"];
241
+ data.organization_id = process.env.organization_id;
242
+
243
+ if (fileName.startsWith("/admin"))
244
+ data.$filter.query.pathname =
245
+ "/superadmin" + fileName.replace("/admin", "");
246
+
247
+ defaultFile = await crud.send(data);
248
+
249
+ if (fileName !== "/hostNotFound.html") {
250
+ crud.wsManager.emit("setBandwidth", {
251
+ type: "out",
252
+ data,
253
+ organization_id
254
+ });
255
+
256
+ crud.wsManager.emit("setBandwidth", {
257
+ type: "in",
258
+ data: defaultFile,
259
+ organization_id
260
+ });
261
+ }
262
+
263
+ if (
264
+ defaultFile &&
265
+ defaultFile.object &&
266
+ defaultFile.object[0] &&
267
+ defaultFile.object[0].src
268
+ ) {
269
+ if (fileName.startsWith("/admin")) {
270
+ data.object[0].directory = "admin";
271
+ data.object[0].path =
272
+ "/admin" +
273
+ data.object[0].path.replace("/superadmin", "");
274
+ data.object[0].pathname = fileName;
275
+ }
276
+
277
+ crud.send({
278
+ method: "object.create",
279
+ host: hostname,
280
+ array: "files",
281
+ object: defaultFile.object[0],
282
+ organization_id
283
+ });
284
+
285
+ return defaultFile;
286
+ } else {
287
+ switch (fileName) {
288
+ case "/403.html":
289
+ defaultFile.object = [
290
+ {
291
+ src: `${pathname} access not allowed for ${organization_id}`
292
+ }
293
+ ];
294
+ break;
295
+ case "/404.html":
296
+ defaultFile.object = [
297
+ {
298
+ src: `${pathname} could not be found for ${organization_id}`
299
+ }
300
+ ];
301
+ break;
302
+ case "/balanceFalse.html":
303
+ defaultFile.object = [
304
+ {
305
+ src: "This organizations account balance has fallen bellow 0: "
306
+ }
307
+ ];
308
+ break;
309
+ case "/hostNotFound.html":
310
+ defaultFile.object = [
311
+ {
312
+ src:
313
+ "An organization could not be found using the host: " +
314
+ hostname +
315
+ " in platformDB: " +
316
+ process.env.organization_id
317
+ }
318
+ ];
319
+ break;
320
+ }
321
+ return defaultFile;
322
+ }
323
+ }
324
+ }
325
+ } catch (error) {
326
+ res.writeHead(400, { "Content-Type": "text/plain" });
327
+ res.end("Invalid host format");
328
+ }
329
+ }
268
330
  }
269
331
 
270
332
  module.exports = CoCreateFileSystem;