@cocreate/file-server 1.14.1 → 1.15.0
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 +7 -0
- package/package.json +1 -1
- package/src/index.js +161 -186
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [1.15.0](https://github.com/CoCreate-app/CoCreate-file-server/compare/v1.14.1...v1.15.0) (2023-12-09)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* updated to be used by lazyloader default ([ff8f720](https://github.com/CoCreate-app/CoCreate-file-server/commit/ff8f720ea51c20c6c5f9d44182351180ad320e6a))
|
|
7
|
+
|
|
1
8
|
## [1.14.1](https://github.com/CoCreate-app/CoCreate-file-server/compare/v1.14.0...v1.14.1) (2023-11-25)
|
|
2
9
|
|
|
3
10
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -25,222 +25,197 @@ const { URL } = require('url');
|
|
|
25
25
|
const organizations = new Map();
|
|
26
26
|
|
|
27
27
|
class CoCreateFileSystem {
|
|
28
|
-
constructor(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
server.on('request', async (req, res) => {
|
|
33
|
-
try {
|
|
34
|
-
const valideUrl = new URL(`http://${req.headers.host}${req.url}`);
|
|
35
|
-
const hostname = valideUrl.hostname;
|
|
36
|
-
|
|
37
|
-
let organization = organizations.get(hostname);
|
|
38
|
-
if (!organization) {
|
|
39
|
-
let org = await crud.send({
|
|
40
|
-
method: 'object.read',
|
|
41
|
-
array: 'organizations',
|
|
42
|
-
$filter: {
|
|
43
|
-
query: [
|
|
44
|
-
{ key: "host", value: [hostname], operator: "$in" }
|
|
45
|
-
]
|
|
46
|
-
},
|
|
47
|
-
organization_id: process.env.organization_id
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
if (!org || !org.object || !org.object[0]) {
|
|
51
|
-
if (!hostNotFound)
|
|
52
|
-
hostNotFound = await getDefaultFile('/hostNotFound.html')
|
|
53
|
-
return sendResponse(hostNotFound.object[0].src, 404, { 'Content-Type': 'text/html', 'storage': organization.storage })
|
|
54
|
-
} else {
|
|
55
|
-
organization = { _id: org.object[0]._id, storage: !!org.object[0].storage }
|
|
56
|
-
organizations.set(hostname, organization)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
28
|
+
constructor(render) {
|
|
29
|
+
this.render = render
|
|
30
|
+
}
|
|
59
31
|
|
|
60
|
-
|
|
32
|
+
async send(req, res, crud, organization, valideUrl) {
|
|
33
|
+
try {
|
|
34
|
+
const organization_id = organization._id
|
|
35
|
+
const hostname = valideUrl.hostname;
|
|
61
36
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
37
|
+
res.setHeader('organization', organization_id)
|
|
38
|
+
res.setHeader('storage', organization.storage);
|
|
39
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
40
|
+
res.setHeader('Access-Control-Allow-Methods', '');
|
|
41
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
67
42
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
43
|
+
let parameters = valideUrl.searchParams;
|
|
44
|
+
if (parameters.size) {
|
|
45
|
+
console.log('parameters', parameters)
|
|
46
|
+
}
|
|
72
47
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
48
|
+
let pathname = valideUrl.pathname;
|
|
49
|
+
if (pathname.endsWith('/')) {
|
|
50
|
+
pathname += "index.html";
|
|
51
|
+
} else {
|
|
52
|
+
let directory = pathname.split("/").slice(-1)[0];
|
|
53
|
+
if (!directory.includes('.'))
|
|
54
|
+
pathname += "/index.html";
|
|
55
|
+
}
|
|
81
56
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
57
|
+
let active = crud.wsManager.organizations.get(organization_id)
|
|
58
|
+
if (active === false) {
|
|
59
|
+
let balanceFalse = await getDefaultFile('/balanceFalse.html')
|
|
60
|
+
return sendResponse(balanceFalse.object[0].src, 403, { 'Content-Type': 'text/html', 'Account-Balance': 'false', 'storage': organization.storage })
|
|
61
|
+
}
|
|
87
62
|
|
|
88
|
-
|
|
63
|
+
let data = {
|
|
64
|
+
method: 'object.read',
|
|
65
|
+
array: 'files',
|
|
66
|
+
$filter: {
|
|
67
|
+
query: [
|
|
68
|
+
{ key: "host", value: [hostname, '*'], operator: "$in" },
|
|
69
|
+
{ key: "pathname", value: pathname, operator: "$eq" }
|
|
70
|
+
],
|
|
71
|
+
limit: 1
|
|
72
|
+
},
|
|
73
|
+
organization_id
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let file
|
|
77
|
+
if (pathname.startsWith('/dist') || pathname.startsWith('/admin') || ['/403.html', '/404.html', '/offline.html', '/manifest.webmanifest', '/service-worker.js'].includes(pathname))
|
|
78
|
+
file = await getDefaultFile(pathname)
|
|
79
|
+
else
|
|
80
|
+
file = await crud.send(data);
|
|
81
|
+
|
|
82
|
+
if (!file || !file.object || !file.object[0]) {
|
|
83
|
+
let pageNotFound = await getDefaultFile('/404.html')
|
|
84
|
+
return sendResponse(pageNotFound.object[0].src, 404, { 'Content-Type': 'text/html' })
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
file = file.object[0]
|
|
88
|
+
if (!file['public'] || file['public'] === "false") {
|
|
89
|
+
let pageForbidden = await getDefaultFile('/403.html')
|
|
90
|
+
return sendResponse(pageForbidden.object[0].src, 403, { 'Content-Type': 'text/html' })
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let src;
|
|
94
|
+
if (file['src'])
|
|
95
|
+
src = file['src'];
|
|
96
|
+
else {
|
|
97
|
+
let fileSrc = await crud.send({
|
|
89
98
|
method: 'object.read',
|
|
90
|
-
array: '
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
{ key: "host", value: [hostname, '*'], operator: "$in" },
|
|
94
|
-
{ key: "pathname", value: pathname, operator: "$eq" }
|
|
95
|
-
],
|
|
96
|
-
limit: 1
|
|
99
|
+
array: file['array'],
|
|
100
|
+
object: {
|
|
101
|
+
_id: file._id
|
|
97
102
|
},
|
|
98
103
|
organization_id
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (pathname.startsWith('/dist') || pathname.startsWith('/admin') || ['/403.html', '/404.html', '/offline.html', '/manifest.webmanifest', '/service-worker.js'].includes(pathname))
|
|
103
|
-
file = await getDefaultFile(pathname)
|
|
104
|
-
else
|
|
105
|
-
file = await crud.send(data);
|
|
104
|
+
});
|
|
105
|
+
src = fileSrc[file['name']];
|
|
106
|
+
}
|
|
106
107
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
if (!src) {
|
|
109
|
+
let pageNotFound = await getDefaultFile('/404.html')
|
|
110
|
+
return sendResponse(pageNotFound.object[0].src, 404, { 'Content-Type': 'text/html' })
|
|
111
|
+
}
|
|
111
112
|
|
|
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
113
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
array: file['array'],
|
|
125
|
-
object: {
|
|
126
|
-
_id: file._id
|
|
127
|
-
},
|
|
128
|
-
organization_id
|
|
129
|
-
});
|
|
130
|
-
src = fileSrc[file['name']];
|
|
131
|
-
}
|
|
114
|
+
if (file.modified || file.created) {
|
|
115
|
+
let modifiedOn = file.modified.on || file.created.on
|
|
116
|
+
if (modifiedOn instanceof Date)
|
|
117
|
+
modifiedOn = modifiedOn.toISOString()
|
|
118
|
+
res.setHeader('Last-Modified', modifiedOn);
|
|
119
|
+
}
|
|
132
120
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
121
|
+
let contentType = file['content-type'] || 'text/html';
|
|
122
|
+
if (/^[A-Za-z0-9+/]+[=]{0,2}$/.test(src)) {
|
|
123
|
+
src = src.replace(/^data:image\/(png|jpeg|jpg);base64,/, '');
|
|
124
|
+
src = Buffer.from(src, 'base64');
|
|
125
|
+
} else if (contentType === 'text/html') {
|
|
126
|
+
try {
|
|
127
|
+
src = await this.render.HTML(src, organization_id);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.warn('server-render: ' + err.message)
|
|
136
130
|
}
|
|
131
|
+
}
|
|
137
132
|
|
|
133
|
+
sendResponse(src, 200, { 'Content-Type': contentType })
|
|
138
134
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
135
|
+
function sendResponse(src, statusCode, headers) {
|
|
136
|
+
crud.wsManager.emit("setBandwidth", {
|
|
137
|
+
type: 'out',
|
|
138
|
+
data: src,
|
|
139
|
+
organization_id
|
|
140
|
+
});
|
|
145
141
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
src = Buffer.from(src, 'base64');
|
|
150
|
-
} else if (contentType === 'text/html') {
|
|
151
|
-
try {
|
|
152
|
-
src = await render.HTML(src, organization_id);
|
|
153
|
-
} catch (err) {
|
|
154
|
-
console.warn('server-render: ' + err.message)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
142
|
+
res.writeHead(statusCode, headers);
|
|
143
|
+
return res.end(src);
|
|
144
|
+
}
|
|
157
145
|
|
|
158
|
-
|
|
146
|
+
async function getDefaultFile(fileName) {
|
|
147
|
+
data.$filter.query[1].value = fileName
|
|
148
|
+
let defaultFile
|
|
149
|
+
if (fileName !== '/hostNotFound.html')
|
|
150
|
+
defaultFile = await crud.send(data);
|
|
159
151
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
152
|
+
if (defaultFile && defaultFile.object && defaultFile.object[0] && defaultFile.object[0].src) {
|
|
153
|
+
return defaultFile
|
|
154
|
+
} else {
|
|
155
|
+
data.$filter.query[0].value = ['*']
|
|
156
|
+
data.organization_id = process.env.organization_id
|
|
157
|
+
|
|
158
|
+
if (fileName.startsWith('/admin'))
|
|
159
|
+
data.$filter.query[1].value = '/superadmin' + fileName.replace('/admin', '')
|
|
160
|
+
|
|
161
|
+
defaultFile = await crud.send(data)
|
|
162
|
+
|
|
163
|
+
if (fileName !== '/hostNotFound.html') {
|
|
164
|
+
crud.wsManager.emit("setBandwidth", {
|
|
165
|
+
type: 'out',
|
|
166
|
+
data,
|
|
167
|
+
organization_id
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
crud.wsManager.emit("setBandwidth", {
|
|
171
|
+
type: 'in',
|
|
172
|
+
data: defaultFile,
|
|
173
|
+
organization_id
|
|
174
|
+
});
|
|
175
|
+
}
|
|
166
176
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
177
|
+
if (defaultFile && defaultFile.object && defaultFile.object[0] && defaultFile.object[0].src) {
|
|
178
|
+
if (fileName.startsWith('/admin')) {
|
|
179
|
+
data.object[0].directory = 'admin'
|
|
180
|
+
data.object[0].path = '/admin' + data.object[0].path.replace('/superadmin', '')
|
|
181
|
+
data.object[0].pathname = fileName
|
|
182
|
+
}
|
|
170
183
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
184
|
+
crud.send({
|
|
185
|
+
method: 'object.create',
|
|
186
|
+
array: 'files',
|
|
187
|
+
object: defaultFile.object[0],
|
|
188
|
+
organization_id
|
|
189
|
+
})
|
|
176
190
|
|
|
177
|
-
if (defaultFile && defaultFile.object && defaultFile.object[0] && defaultFile.object[0].src) {
|
|
178
191
|
return defaultFile
|
|
179
192
|
} else {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
crud.wsManager.emit("setBandwidth", {
|
|
196
|
-
type: 'in',
|
|
197
|
-
data: defaultFile,
|
|
198
|
-
organization_id
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (defaultFile && defaultFile.object && defaultFile.object[0] && defaultFile.object[0].src) {
|
|
203
|
-
if (fileName.startsWith('/admin')) {
|
|
204
|
-
data.object[0].directory = 'admin'
|
|
205
|
-
data.object[0].path = '/admin' + data.object[0].path.replace('/superadmin', '')
|
|
206
|
-
data.object[0].pathname = fileName
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
crud.send({
|
|
210
|
-
method: 'object.create',
|
|
211
|
-
array: 'files',
|
|
212
|
-
object: defaultFile.object[0],
|
|
213
|
-
organization_id
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
return defaultFile
|
|
217
|
-
} else {
|
|
218
|
-
switch (fileName) {
|
|
219
|
-
case '/403.html':
|
|
220
|
-
defaultFile.object = [{ src: `${pathname} access not allowed for ${organization_id}` }]
|
|
221
|
-
break;
|
|
222
|
-
case '/404.html':
|
|
223
|
-
defaultFile.object = [{ src: `${pathname} could not be found for ${organization_id}` }];
|
|
224
|
-
break;
|
|
225
|
-
case '/balanceFalse.html':
|
|
226
|
-
defaultFile.object = [{ src: 'This organizations account balance has fallen bellow 0: ' }];
|
|
227
|
-
break;
|
|
228
|
-
case '/hostNotFound.html':
|
|
229
|
-
defaultFile.object = [{ src: 'An organization could not be found using the host: ' + hostname + ' in platformDB: ' + process.env.organization_id }];
|
|
230
|
-
break;
|
|
231
|
-
}
|
|
232
|
-
return defaultFile
|
|
193
|
+
switch (fileName) {
|
|
194
|
+
case '/403.html':
|
|
195
|
+
defaultFile.object = [{ src: `${pathname} access not allowed for ${organization_id}` }]
|
|
196
|
+
break;
|
|
197
|
+
case '/404.html':
|
|
198
|
+
defaultFile.object = [{ src: `${pathname} could not be found for ${organization_id}` }];
|
|
199
|
+
break;
|
|
200
|
+
case '/balanceFalse.html':
|
|
201
|
+
defaultFile.object = [{ src: 'This organizations account balance has fallen bellow 0: ' }];
|
|
202
|
+
break;
|
|
203
|
+
case '/hostNotFound.html':
|
|
204
|
+
defaultFile.object = [{ src: 'An organization could not be found using the host: ' + hostname + ' in platformDB: ' + process.env.organization_id }];
|
|
205
|
+
break;
|
|
233
206
|
}
|
|
207
|
+
return defaultFile
|
|
234
208
|
}
|
|
235
209
|
}
|
|
210
|
+
}
|
|
236
211
|
|
|
237
212
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
})
|
|
213
|
+
} catch (error) {
|
|
214
|
+
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
215
|
+
res.end('Invalid host format');
|
|
216
|
+
}
|
|
243
217
|
}
|
|
218
|
+
|
|
244
219
|
}
|
|
245
220
|
|
|
246
221
|
module.exports = CoCreateFileSystem;
|