blixify-server 0.1.65 → 0.1.67

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.
@@ -1 +1,80 @@
1
- "use strict";var __awaiter=this&&this.__awaiter||function(e,c,d,u){return new(d=d||Promise)(function(i,t){function o(e){try{r(u.next(e))}catch(e){t(e)}}function n(e){try{r(u.throw(e))}catch(e){t(e)}}function r(e){var t;e.done?i(e.value):((t=e.value)instanceof d?t:new d(function(e){e(t)})).then(o,n)}r((u=u.apply(e,c||[])).next())})};Object.defineProperty(exports,"__esModule",{value:!0}),exports.SecurityMiddleware=void 0;class SecurityMiddleware{constructor(e,t,i,o){this.checkAuthentication=e=>__awaiter(this,void 0,void 0,function*(){return""}),this.checkOrgId=e=>__awaiter(this,void 0,void 0,function*(){return""}),this.checkRole=e=>__awaiter(this,void 0,void 0,function*(){return""}),this.checkAPIToken=e=>__awaiter(this,void 0,void 0,function*(){return!1}),this.checkAuthentication=e,this.checkOrgId=t,this.checkRole=i,this.checkAPIToken=o}init(){const n=this;return function(i,e,o){return __awaiter(this,void 0,void 0,function*(){var e,t;delete i.body.bm_userId,delete i.body.bm_userOrg,delete i.body.bm_userRole,delete i.body.bm_apiToken,i.body.userToken&&(e=yield n.checkAuthentication(i.body.userToken))&&(i.body.bm_userId=e,(t=yield n.checkOrgId(e))&&(i.body.bm_userOrg=t),t=yield n.checkRole(e))&&(i.body.bm_userRole=t),i.body.apiToken&&(e=i.body.apiToken,t=yield n.checkAPIToken(e),i.body.bm_apiToken=t),o&&o()})}}}exports.SecurityMiddleware=SecurityMiddleware;
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SecurityMiddleware = void 0;
13
+ /**
14
+ * Security for our server
15
+ * 1. Add Admin Token
16
+ * 2. Add CORS Policy - Protect web browser
17
+ * 3. Basic helmet security configurations
18
+ * 4. Prevent DDOS from rate limiting
19
+ */
20
+ class SecurityMiddleware {
21
+ /* eslint-enable */
22
+ constructor(checkAuthentication, checkOrgId, checkRole, checkAPIToken) {
23
+ /* eslint-disable */
24
+ this.checkAuthentication = (token) => __awaiter(this, void 0, void 0, function* () {
25
+ return "";
26
+ });
27
+ this.checkOrgId = (userId) => __awaiter(this, void 0, void 0, function* () {
28
+ return "";
29
+ });
30
+ this.checkRole = (userId) => __awaiter(this, void 0, void 0, function* () {
31
+ return "";
32
+ });
33
+ this.checkAPIToken = (apiToken) => __awaiter(this, void 0, void 0, function* () {
34
+ return false;
35
+ });
36
+ this.checkAuthentication = checkAuthentication;
37
+ this.checkOrgId = checkOrgId;
38
+ this.checkRole = checkRole;
39
+ this.checkAPIToken = checkAPIToken;
40
+ }
41
+ /**
42
+ * 1. Check User Authentication
43
+ * 2. Check User Role
44
+ * 3. Check API Token
45
+ */
46
+ init() {
47
+ // eslint-disable-next-line
48
+ const wrapper = this;
49
+ const securityMiddleware = function (req, res, next) {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ delete req.body["bm_userId"];
52
+ delete req.body["bm_userOrg"];
53
+ delete req.body["bm_userRole"];
54
+ delete req.body["bm_apiToken"];
55
+ if (req.body.userToken) {
56
+ const userId = yield wrapper.checkAuthentication(req.body.userToken);
57
+ if (userId) {
58
+ req.body["bm_userId"] = userId;
59
+ const userOrgId = yield wrapper.checkOrgId(userId);
60
+ if (userOrgId)
61
+ req.body["bm_userOrg"] = userOrgId;
62
+ const userRole = yield wrapper.checkRole(userId);
63
+ if (userRole)
64
+ req.body["bm_userRole"] = userRole;
65
+ }
66
+ }
67
+ if (req.body.apiToken) {
68
+ const apiToken = req.body.apiToken;
69
+ const valid = yield wrapper.checkAPIToken(apiToken);
70
+ req.body["bm_apiToken"] = valid;
71
+ }
72
+ if (next) {
73
+ next();
74
+ }
75
+ });
76
+ };
77
+ return securityMiddleware;
78
+ }
79
+ }
80
+ exports.SecurityMiddleware = SecurityMiddleware;
@@ -1 +1,396 @@
1
- "use strict";var __awaiter=this&&this.__awaiter||function(e,n,r,l){return new(r=r||Promise)(function(i,t){function s(e){try{a(l.next(e))}catch(e){t(e)}}function o(e){try{a(l.throw(e))}catch(e){t(e)}}function a(e){var t;e.done?i(e.value):((t=e.value)instanceof r?t:new r(function(e){e(t)})).then(s,o)}a((l=l.apply(e,n||[])).next())})},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.UploadWrapper=void 0;const QueryModel_1=require("../model/QueryModel"),axios_1=__importDefault(require("axios")),mime_1=__importDefault(require("mime"));class UploadWrapper{constructor(e,t,i,s,o){this.uploadAdmin="",this.isProd=!1,this.config={baseConfig:[],opsConfig:{read:[],create:[],update:[],delete:[]}},this.storageType="firebase",this.modelChecker=(e,t)=>!(!e.assetCollectionName||!e.assetParentId||!t&&!e.assetFileName),this.initUpload=(d,c,u)=>__awaiter(this,void 0,void 0,function*(){try{const l=d.body.data;if(this.modelChecker(l)&&(d.file||l.downloadLink)){var e=(0,QueryModel_1.checkBaseConfig)(this.config,d),t=(0,QueryModel_1.checkOpsConfig)(this.config,u,d,l);if(e&&t){const n=this.lib.randomUUID();if("aws"===this.storageType){var i,s=(n,r)=>new Promise((o,a)=>__awaiter(this,void 0,void 0,function*(){var e="buffer"===n,t=new this.uploadAdmin.S3;let i;e||(s=d.file.originalname.split(".").pop(),i="mbtiles"===s?"application/vnd.mapbox-vector-tile":mime_1.default.getType(s)||d.file.mimetype);var s={Bucket:`${l.bucketName}/${l.assetCollectionName}/`+l.assetParentId,Key:l.assetFileName,Body:e?r.data:d.file.buffer,ContentType:e?r.headers["content-type"]:i};t.upload(s,function(e){e?a(e):o("aws")})}));l.downloadLink?(i=yield(0,axios_1.default)({method:"GET",url:l.downloadLink,responseType:"arraybuffer"})).data&&(yield s("buffer",i)):yield s("file")}else{const r=this.uploadAdmin.storage().bucket();var o,a=(o,a)=>new Promise((i,s)=>__awaiter(this,void 0,void 0,function*(){var e="buffer"===o,t={contentType:e?a.headers["content-type"]:d.file.mimetype,customMetadata:{"file-name":"buffer"===o?l.assetFileName:d.file.originalname},metadata:{firebaseStorageDownloadTokens:n}},t=r.file(`${l.assetCollectionName}/${l.assetParentId}/`+l.assetFileName).createWriteStream({metadata:t});t.end(e?a.data:d.file.buffer),t.on("error",s),t.on("finish",i)}));l.downloadLink?(o=yield(0,axios_1.default)({method:"GET",url:l.downloadLink,responseType:"arraybuffer"})).data&&(yield a("buffer",o)):yield a("file")}c.send({data:n})}else c.status(400).json({err:"Invalid Security Configuration"})}else c.status(400).json({err:"Invalid Fields"})}catch(e){c.status(400).json({err:e})}}),this.initDelete=(a,n)=>__awaiter(this,void 0,void 0,function*(){try{var e,t,i,s,o=a.body.data;this.modelChecker(o)?(e=(0,QueryModel_1.checkBaseConfig)(this.config,a),t=(0,QueryModel_1.checkOpsConfig)(this.config,"delete",a,o),e&&t?("aws"===this.storageType?(i=new this.uploadAdmin.S3,s={Bucket:`${o.bucketName}/${o.assetCollectionName}/`+o.assetParentId,Key:o.assetFileName},yield i.deleteObject(s).promise()):yield this.uploadAdmin.storage().bucket().file(`${o.assetCollectionName}/${o.assetParentId}/`+o.assetFileName).delete(),n.send({success:!0})):n.status(400).json({err:"Invalid Security Configuration"})):n.status(400).json({err:"Invalid Fields"})}catch(e){n.status(400).json({err:e})}}),this.deleteGoogleFolderContents=a=>__awaiter(this,void 0,void 0,function*(){try{var e={prefix:a.name,autoPaginate:!1},[t]=yield this.uploadAdmin.storage().bucket().getFiles(e),i=[];for(const s of t)i.push(s.delete());for(const o of t)o.name.endsWith("/")&&i.push(this.deleteGoogleFolderContents(o));yield Promise.all(i)}catch(e){}}),this.deleteAWSFolderContent=(o,a)=>__awaiter(this,void 0,void 0,function*(){try{var e=new this.uploadAdmin.S3,t=(yield e.listObjectsV2({Bucket:o,Prefix:a}).promise()).Contents.map(e=>e.Key),i=[];for(const s of t)i.push(e.deleteObject({Bucket:o,Key:s}).promise());yield Promise.all(i)}catch(e){}}),this.initDeleteDirectory=(o,a)=>__awaiter(this,void 0,void 0,function*(){try{var e,t,i,s=o.body.data;this.modelChecker(s,!0)?(e=(0,QueryModel_1.checkBaseConfig)(this.config,o),t=(0,QueryModel_1.checkOpsConfig)(this.config,"delete",o,s),e&&t?("aws"===this.storageType?yield this.deleteAWSFolderContent(""+s.bucketName,`${s.assetCollectionName}/${s.assetParentId}/`):(i=this.uploadAdmin.storage().bucket().file(`${s.assetCollectionName}/${s.assetParentId}/`),yield this.deleteGoogleFolderContents(i)),a.send({success:!0})):a.status(400).json({err:"Invalid Security Configuration"})):a.status(400).json({err:"Invalid Fields"})}catch(e){a.status(400).json({err:e})}}),this.initBatchDeleteDirectory=(o,a)=>__awaiter(this,void 0,void 0,function*(){try{const s=o.body.data;var e,t,i=JSON.parse(s.assetParentId);this.modelChecker(s,!0)?(e=(0,QueryModel_1.checkBaseConfig)(this.config,o),t=(0,QueryModel_1.checkOpsConfig)(this.config,"delete",o,s),e&&t?(yield Promise.all(i.map(t=>__awaiter(this,void 0,void 0,function*(){var e;"aws"===this.storageType?yield this.deleteAWSFolderContent(""+s.bucketName,s.assetCollectionName+`/${t}/`):(e=this.uploadAdmin.storage().bucket().file(s.assetCollectionName+`/${t}/`),yield this.deleteGoogleFolderContents(e))}))),a.send({success:!0})):a.status(400).json({err:"Invalid Security Configuration"})):a.status(400).json({err:"Invalid Fields"})}catch(e){a.status(400).json({err:e})}}),this.initGet=(n,r)=>__awaiter(this,void 0,void 0,function*(){try{const{bucketName:e,assetCollectionName:t,assetParentId:i,fileName:s}=n.params;if("aws"===this.storageType){const o=new this.uploadAdmin.S3,a={Bucket:e,Key:t+`/${i}/`+s};o.headObject(a,e=>__awaiter(this,void 0,void 0,function*(){if(e&&"NotFound"===e.code)r.status(404).send({message:"File not found"});else{var t=yield o.getObject(a).promise(),i=s.split(".").pop();let e;e="mbtiles"===i?"application/vnd.mapbox-vector-tile":mime_1.default.getType(i)||t.ContentType,r.set("Content-Type",e),r.send(t.Body)}}))}}catch(e){r.status(400).json({err:e})}}),this.init=()=>{var e=this.lib.express.Router();return this.lib.cors&&e.use(this.lib.cors()),e.post("/upload",this.lib.multer.single("file"),(e,t)=>{this.initUpload(e,t,"create")}),e.post("/update",this.lib.multer.single("file"),(e,t)=>{this.initUpload(e,t,"update")}),e.post("/delete",this.initDelete),e.post("/deleteDirectory",this.initDeleteDirectory),e.post("/batchDeleteDirectory",this.initBatchDeleteDirectory),e.get("/get/:bucketName/:assetCollectionName/:assetParentId/:fileName",this.initGet),e},this.uploadAdmin=e,this.isProd=t,this.config=i,this.lib=s,this.storageType=null!=o?o:"firebase"}}exports.UploadWrapper=UploadWrapper;
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.UploadWrapper = void 0;
16
+ const QueryModel_1 = require("../model/QueryModel");
17
+ const axios_1 = __importDefault(require("axios"));
18
+ const mime_1 = __importDefault(require("mime"));
19
+ /**
20
+ * @Wrapper
21
+ *
22
+ */
23
+ class UploadWrapper {
24
+ constructor(uploadAdmin, isProd, config, lib, storageType) {
25
+ this.uploadAdmin = "";
26
+ this.isProd = false;
27
+ this.config = {
28
+ baseConfig: [],
29
+ opsConfig: {
30
+ read: [],
31
+ create: [],
32
+ update: [],
33
+ delete: [],
34
+ },
35
+ };
36
+ this.storageType = "firebase";
37
+ this.modelChecker = (obj, isDeleteDirectory) => {
38
+ if (obj.assetCollectionName &&
39
+ obj.assetParentId &&
40
+ (isDeleteDirectory || obj.assetFileName)) {
41
+ return true;
42
+ }
43
+ else {
44
+ return false;
45
+ }
46
+ };
47
+ this.initUpload = (req, res, type) => __awaiter(this, void 0, void 0, function* () {
48
+ try {
49
+ const respData = req.body.data;
50
+ const valid = this.modelChecker(respData) && (req.file || respData.downloadLink);
51
+ if (valid) {
52
+ //INFO : Security Checker
53
+ const validBaseConfig = (0, QueryModel_1.checkBaseConfig)(this.config, req);
54
+ const validOpsConfig = (0, QueryModel_1.checkOpsConfig)(this.config, type, req, respData);
55
+ if (!validBaseConfig || !validOpsConfig) {
56
+ res.status(400).json({ err: "Invalid Security Configuration" });
57
+ return;
58
+ }
59
+ const token = this.lib.randomUUID();
60
+ if (this.storageType === "aws") {
61
+ const s3UploadPromise = (type, response) => {
62
+ return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
63
+ const buffer = type === "buffer";
64
+ const s3 = new this.uploadAdmin.S3();
65
+ let contentType;
66
+ if (!buffer) {
67
+ const extension = req.file.originalname.split(".").pop();
68
+ if (extension === "mbtiles")
69
+ contentType = "application/vnd.mapbox-vector-tile";
70
+ else
71
+ contentType = mime_1.default.getType(extension) || req.file.mimetype;
72
+ }
73
+ const uploadParams = {
74
+ Bucket: `${respData.bucketName}/${respData.assetCollectionName}/${respData.assetParentId}`,
75
+ Key: respData.assetFileName,
76
+ Body: buffer ? response.data : req.file.buffer,
77
+ ContentType: buffer
78
+ ? response.headers["content-type"]
79
+ : contentType,
80
+ };
81
+ s3.upload(uploadParams, function (err) {
82
+ if (err) {
83
+ reject(err);
84
+ }
85
+ else {
86
+ resolve("aws");
87
+ }
88
+ });
89
+ }));
90
+ };
91
+ if (respData.downloadLink) {
92
+ const response = yield (0, axios_1.default)({
93
+ method: "GET",
94
+ url: respData.downloadLink,
95
+ responseType: "arraybuffer",
96
+ });
97
+ if (response.data)
98
+ yield s3UploadPromise("buffer", response);
99
+ }
100
+ else
101
+ yield s3UploadPromise("file");
102
+ res.send({ data: token });
103
+ }
104
+ else {
105
+ const firebaseBucket = this.uploadAdmin.storage().bucket();
106
+ const uploadFilePromise = (type, response) => {
107
+ return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
108
+ const buffer = type === "buffer";
109
+ const uploadMetadata = {
110
+ contentType: buffer
111
+ ? response.headers["content-type"]
112
+ : req.file.mimetype,
113
+ customMetadata: {
114
+ "file-name": type === "buffer"
115
+ ? respData.assetFileName
116
+ : req.file.originalname,
117
+ },
118
+ metadata: {
119
+ firebaseStorageDownloadTokens: token,
120
+ },
121
+ };
122
+ const stream = firebaseBucket
123
+ .file(`${respData.assetCollectionName}/${respData.assetParentId}/${respData.assetFileName}`)
124
+ .createWriteStream({ metadata: uploadMetadata });
125
+ stream.end(buffer ? response.data : req.file.buffer);
126
+ stream.on("error", reject);
127
+ stream.on("finish", resolve);
128
+ }));
129
+ };
130
+ if (respData.downloadLink) {
131
+ const response = yield (0, axios_1.default)({
132
+ method: "GET",
133
+ url: respData.downloadLink,
134
+ responseType: "arraybuffer",
135
+ });
136
+ if (response.data)
137
+ yield uploadFilePromise("buffer", response);
138
+ }
139
+ else
140
+ yield uploadFilePromise("file");
141
+ res.send({ data: token });
142
+ }
143
+ }
144
+ else {
145
+ res.status(400).json({ err: "Invalid Fields" });
146
+ }
147
+ }
148
+ catch (err) {
149
+ res.status(400).json({ err: err });
150
+ }
151
+ });
152
+ this.initDelete = (req, res) => __awaiter(this, void 0, void 0, function* () {
153
+ try {
154
+ const respData = req.body.data;
155
+ const valid = this.modelChecker(respData);
156
+ if (valid) {
157
+ //INFO : Security Checker
158
+ const validBaseConfig = (0, QueryModel_1.checkBaseConfig)(this.config, req);
159
+ const validOpsConfig = (0, QueryModel_1.checkOpsConfig)(this.config, "delete", req, respData);
160
+ if (!validBaseConfig || !validOpsConfig) {
161
+ res.status(400).json({ err: "Invalid Security Configuration" });
162
+ return;
163
+ }
164
+ if (this.storageType === "aws") {
165
+ const s3 = new this.uploadAdmin.S3();
166
+ const params = {
167
+ Bucket: `${respData.bucketName}/${respData.assetCollectionName}/${respData.assetParentId}`,
168
+ Key: respData.assetFileName,
169
+ };
170
+ yield s3.deleteObject(params).promise();
171
+ }
172
+ else {
173
+ const firebaseBucket = this.uploadAdmin.storage().bucket();
174
+ yield firebaseBucket
175
+ .file(`${respData.assetCollectionName}/${respData.assetParentId}/${respData.assetFileName}`)
176
+ .delete();
177
+ }
178
+ res.send({ success: true });
179
+ }
180
+ else {
181
+ res.status(400).json({ err: "Invalid Fields" });
182
+ }
183
+ }
184
+ catch (err) {
185
+ res.status(400).json({ err: err });
186
+ }
187
+ });
188
+ this.deleteGoogleFolderContents = (folderRef) => __awaiter(this, void 0, void 0, function* () {
189
+ try {
190
+ const listOptions = {
191
+ prefix: folderRef.name,
192
+ autoPaginate: false,
193
+ };
194
+ const [files] = yield this.uploadAdmin
195
+ .storage()
196
+ .bucket()
197
+ .getFiles(listOptions);
198
+ const deletionPromises = [];
199
+ for (const file of files) {
200
+ deletionPromises.push(file.delete());
201
+ }
202
+ for (const file of files) {
203
+ const isPrefix = file.name.endsWith("/");
204
+ if (isPrefix) {
205
+ deletionPromises.push(this.deleteGoogleFolderContents(file));
206
+ }
207
+ }
208
+ yield Promise.all(deletionPromises);
209
+ }
210
+ catch (error) { }
211
+ });
212
+ this.deleteAWSFolderContent = (bucketName, directoryPrefix) => __awaiter(this, void 0, void 0, function* () {
213
+ try {
214
+ const s3 = new this.uploadAdmin.S3();
215
+ const data = yield s3
216
+ .listObjectsV2({ Bucket: bucketName, Prefix: directoryPrefix })
217
+ .promise();
218
+ const files = data.Contents.map((obj) => obj.Key);
219
+ const deletionPromises = [];
220
+ for (const file of files) {
221
+ deletionPromises.push(s3.deleteObject({ Bucket: bucketName, Key: file }).promise());
222
+ }
223
+ yield Promise.all(deletionPromises);
224
+ }
225
+ catch (error) { }
226
+ });
227
+ this.initDeleteDirectory = (req, res) => __awaiter(this, void 0, void 0, function* () {
228
+ try {
229
+ const respData = req.body.data;
230
+ const valid = this.modelChecker(respData, true);
231
+ if (valid) {
232
+ //INFO : Security Checker
233
+ const validBaseConfig = (0, QueryModel_1.checkBaseConfig)(this.config, req);
234
+ const validOpsConfig = (0, QueryModel_1.checkOpsConfig)(this.config, "delete", req, respData);
235
+ if (!validBaseConfig || !validOpsConfig) {
236
+ res.status(400).json({ err: "Invalid Security Configuration" });
237
+ return;
238
+ }
239
+ if (this.storageType === "aws") {
240
+ yield this.deleteAWSFolderContent(`${respData.bucketName}`, `${respData.assetCollectionName}/${respData.assetParentId}/`);
241
+ }
242
+ else {
243
+ const folderRef = this.uploadAdmin
244
+ .storage()
245
+ .bucket()
246
+ .file(`${respData.assetCollectionName}/${respData.assetParentId}/`);
247
+ yield this.deleteGoogleFolderContents(folderRef);
248
+ }
249
+ res.send({ success: true });
250
+ }
251
+ else {
252
+ res.status(400).json({ err: "Invalid Fields" });
253
+ }
254
+ }
255
+ catch (err) {
256
+ res.status(400).json({ err: err });
257
+ }
258
+ });
259
+ this.initBatchDeleteDirectory = (req, res) => __awaiter(this, void 0, void 0, function* () {
260
+ try {
261
+ const respData = req.body.data;
262
+ const assetParentIds = JSON.parse(respData.assetParentId);
263
+ const valid = this.modelChecker(respData, true);
264
+ if (valid) {
265
+ //INFO : Security Checker
266
+ const validBaseConfig = (0, QueryModel_1.checkBaseConfig)(this.config, req);
267
+ const validOpsConfig = (0, QueryModel_1.checkOpsConfig)(this.config, "delete", req, respData);
268
+ if (!validBaseConfig || !validOpsConfig) {
269
+ res.status(400).json({ err: "Invalid Security Configuration" });
270
+ return;
271
+ }
272
+ yield Promise.all(assetParentIds.map((eachId) => __awaiter(this, void 0, void 0, function* () {
273
+ if (this.storageType === "aws") {
274
+ yield this.deleteAWSFolderContent(`${respData.bucketName}`, `${respData.assetCollectionName}/${eachId}/`);
275
+ }
276
+ else {
277
+ const folderRef = this.uploadAdmin
278
+ .storage()
279
+ .bucket()
280
+ .file(`${respData.assetCollectionName}/${eachId}/`);
281
+ yield this.deleteGoogleFolderContents(folderRef);
282
+ }
283
+ })));
284
+ res.send({ success: true });
285
+ }
286
+ else {
287
+ res.status(400).json({ err: "Invalid Fields" });
288
+ }
289
+ }
290
+ catch (err) {
291
+ res.status(400).json({ err: err });
292
+ }
293
+ });
294
+ this.initGet = (req, res) => __awaiter(this, void 0, void 0, function* () {
295
+ //TODO: add FB initGet
296
+ try {
297
+ const { bucketName, assetCollectionName, assetParentId, fileName } = req.params;
298
+ if (this.storageType === "aws") {
299
+ const s3 = new this.uploadAdmin.S3();
300
+ const params = {
301
+ Bucket: bucketName,
302
+ Key: `${assetCollectionName}/${assetParentId}/${fileName}`,
303
+ };
304
+ s3.headObject(params, (err) => __awaiter(this, void 0, void 0, function* () {
305
+ if (err && err.code === "NotFound") {
306
+ res.status(404).send({ message: "File not found" });
307
+ }
308
+ else {
309
+ const resp = yield s3.getObject(params).promise();
310
+ const extension = fileName.split(".").pop();
311
+ let contentType;
312
+ if (extension === "mbtiles") {
313
+ contentType = "application/vnd.mapbox-vector-tile";
314
+ }
315
+ else {
316
+ contentType = mime_1.default.getType(extension) || resp.ContentType;
317
+ }
318
+ res.set("Content-Type", contentType);
319
+ res.send(resp.Body);
320
+ }
321
+ }));
322
+ }
323
+ }
324
+ catch (error) {
325
+ res.status(400).json({ err: error });
326
+ }
327
+ });
328
+ this.init = () => {
329
+ const router = this.lib.express.Router();
330
+ if (this.lib.cors) {
331
+ router.use(this.lib.cors());
332
+ }
333
+ /**
334
+ * @Input :
335
+ * assetCollectionName - string
336
+ * assetFileName - string
337
+ * assetParentId - string
338
+ * file? - File
339
+ * downloadLink? - Asset Download link instead of file
340
+ * bucketName? - Optional, only required for Google Storage & AWS S3
341
+ */
342
+ router.post("/upload", this.lib.multer.single("file"), (req, res) => {
343
+ this.initUpload(req, res, "create");
344
+ });
345
+ /**
346
+ * @Input :
347
+ * assetCollectionName - string
348
+ * assetFileName - string
349
+ * assetParentId - string
350
+ * file? - File
351
+ * downloadLink? - Asset Download link instead of file
352
+ * bucketName? - Optional, only required for Google Storage & AWS S3
353
+ */
354
+ router.post("/update", this.lib.multer.single("file"), (req, res) => {
355
+ this.initUpload(req, res, "update");
356
+ });
357
+ /**
358
+ * @Input :
359
+ * assetCollectionName - string
360
+ * assetFileName - string
361
+ * assetParentId - string
362
+ * bucketName? - Optional, only required for Google Storage & AWS S3
363
+ */
364
+ router.post("/delete", this.initDelete);
365
+ /**
366
+ * @Input :
367
+ * assetCollectionName - string
368
+ * assetParentId - string
369
+ * bucketName? - Optional, only required for Google Storage & AWS S3
370
+ */
371
+ router.post("/deleteDirectory", this.initDeleteDirectory);
372
+ /**
373
+ * @Input :
374
+ * assetCollectionName - string
375
+ * assetParentId - string[]
376
+ * bucketName? - Optional, only required for Google Storage & AWS S3
377
+ */
378
+ router.post("/batchDeleteDirectory", this.initBatchDeleteDirectory);
379
+ /**
380
+ * @Input :
381
+ * bucketName - string
382
+ * assetCollectionName - string
383
+ * assetParentId - string
384
+ * fileName - string
385
+ */
386
+ router.get("/get/:bucketName/:assetCollectionName/:assetParentId/:fileName", this.initGet);
387
+ return router;
388
+ };
389
+ this.uploadAdmin = uploadAdmin;
390
+ this.isProd = isProd;
391
+ this.config = config;
392
+ this.lib = lib;
393
+ this.storageType = storageType !== null && storageType !== void 0 ? storageType : "firebase";
394
+ }
395
+ }
396
+ exports.UploadWrapper = UploadWrapper;
@@ -1 +1,21 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.compareUpdatedFields=void 0;const uuid_1=require("uuid"),compareUpdatedFields=(d,t)=>{const s={};return Object.keys(d).forEach(e=>{d[e]&&(0,uuid_1.validate)(d[e])&&(s[e]=d[e])}),Object.keys(t).forEach(e=>{t[e]!==d[e]&&(s[e]=t[e])}),{workflowUpdateFields:Object.assign({},s),updatedFields:s}};exports.compareUpdatedFields=compareUpdatedFields;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compareUpdatedFields = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const compareUpdatedFields = (prevData, currentData) => {
6
+ const updatedFields = {};
7
+ Object.keys(prevData).forEach((key) => {
8
+ if (prevData[key] && (0, uuid_1.validate)(prevData[key]))
9
+ updatedFields[key] = prevData[key];
10
+ });
11
+ Object.keys(currentData).forEach((key) => {
12
+ if (currentData[key] !== prevData[key]) {
13
+ updatedFields[key] = currentData[key];
14
+ }
15
+ });
16
+ return {
17
+ workflowUpdateFields: Object.assign({}, updatedFields),
18
+ updatedFields,
19
+ };
20
+ };
21
+ exports.compareUpdatedFields = compareUpdatedFields;
@@ -1 +1,118 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.checkOpsConfig=exports.checkBaseConfig=void 0;const checkBaseConfig=(e,r)=>{let a=!0;return 0<e.baseConfig.length&&e.baseConfig.map(e=>{switch(e.type){case"domain":r.headers.referer||(a=!1);break;case"android":r.headers["x-android-package"]||(a=!1);break;case"androidSHA":r.headers["x-android-cert"]||(a=!1);break;case"ios":r.headers["x-ios-bundle-identifier"]||(a=!1);break;case"api":r.body.bm_apiToken||(a=!1);break;case"auth":r.body.bm_userId||(a=!1);break;case"role":r.body.bm_userRole!==e.value&&(a=!1)}}),a},checkOpsConfig=(exports.checkBaseConfig=checkBaseConfig,(e,r,a,s)=>{let o=!1,i;return 0<(i="read"===r?e.opsConfig.read:"create"===r?e.opsConfig.create:"update"===r?e.opsConfig.update:e.opsConfig.delete).length?i.map(e=>{switch(e.type){case"auth":a.body.bm_userId&&(o=!0);break;case"doc":if(a.body.bm_userId){const r=JSON.stringify(a.body.bm_userId);Array.isArray(e.value)?e.value.map(e=>{r===JSON.stringify(s[e])&&(o=!0)}):r===JSON.stringify(s[e.value])&&(o=!0)}break;case"org":a.body.bm_userOrg&&!Array.isArray(e.value)&&JSON.stringify(a.body.bm_userOrg)===JSON.stringify(s[e.value])&&(o=!0);break;case"role":a.body.bm_userRole&&a.body.bm_userRole===e.value&&(o=!0)}}):o=!0,o});exports.checkOpsConfig=checkOpsConfig;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkOpsConfig = exports.checkBaseConfig = void 0;
4
+ /**
5
+ *
6
+ * Doc is not supported for Base Config
7
+ * @param config
8
+ * @param req
9
+ * @returns
10
+ */
11
+ const checkBaseConfig = (config, req) => {
12
+ let validBaseConfig = true;
13
+ if (config.baseConfig.length > 0) {
14
+ config.baseConfig.map((eachConfig) => {
15
+ switch (eachConfig.type) {
16
+ case "domain":
17
+ if (!req.headers["referer"])
18
+ validBaseConfig = false;
19
+ break;
20
+ case "android":
21
+ if (!req.headers["x-android-package"])
22
+ validBaseConfig = false;
23
+ break;
24
+ case "androidSHA":
25
+ if (!req.headers["x-android-cert"])
26
+ validBaseConfig = false;
27
+ break;
28
+ case "ios":
29
+ if (!req.headers["x-ios-bundle-identifier"])
30
+ validBaseConfig = false;
31
+ break;
32
+ case "api":
33
+ if (!req.body["bm_apiToken"])
34
+ validBaseConfig = false;
35
+ break;
36
+ case "auth":
37
+ if (!req.body["bm_userId"])
38
+ validBaseConfig = false;
39
+ break;
40
+ case "role":
41
+ if (req.body["bm_userRole"] !== eachConfig.value)
42
+ validBaseConfig = false;
43
+ break;
44
+ case "org":
45
+ case "doc":
46
+ break;
47
+ }
48
+ });
49
+ }
50
+ return validBaseConfig;
51
+ };
52
+ exports.checkBaseConfig = checkBaseConfig;
53
+ /**
54
+ *
55
+ * @param config
56
+ * @param type
57
+ * @param req
58
+ * @param doc
59
+ * @returns
60
+ */
61
+ const checkOpsConfig = (config, type, req, doc) => {
62
+ let validOpsConfig = false;
63
+ let selectedOpsConfig;
64
+ if (type === "read") {
65
+ selectedOpsConfig = config.opsConfig.read;
66
+ }
67
+ else if (type === "create") {
68
+ selectedOpsConfig = config.opsConfig.create;
69
+ }
70
+ else if (type === "update") {
71
+ selectedOpsConfig = config.opsConfig.update;
72
+ }
73
+ else {
74
+ selectedOpsConfig = config.opsConfig.delete;
75
+ }
76
+ if (selectedOpsConfig.length > 0) {
77
+ selectedOpsConfig.map((eachConfig) => {
78
+ switch (eachConfig.type) {
79
+ case "auth":
80
+ if (req.body["bm_userId"])
81
+ validOpsConfig = true;
82
+ break;
83
+ case "doc":
84
+ if (req.body["bm_userId"]) {
85
+ const compareValue = JSON.stringify(req.body["bm_userId"]);
86
+ if (Array.isArray(eachConfig.value)) {
87
+ eachConfig.value.map((eachValue) => {
88
+ if (compareValue === JSON.stringify(doc[eachValue]))
89
+ validOpsConfig = true;
90
+ });
91
+ }
92
+ else {
93
+ if (compareValue === JSON.stringify(doc[eachConfig.value]))
94
+ validOpsConfig = true;
95
+ }
96
+ }
97
+ break;
98
+ case "org":
99
+ if (req.body["bm_userOrg"] && !Array.isArray(eachConfig.value)) {
100
+ if (JSON.stringify(req.body["bm_userOrg"]) ===
101
+ JSON.stringify(doc[eachConfig.value]))
102
+ validOpsConfig = true;
103
+ }
104
+ break;
105
+ case "role":
106
+ if (req.body["bm_userRole"] &&
107
+ req.body["bm_userRole"] === eachConfig.value)
108
+ validOpsConfig = true;
109
+ break;
110
+ }
111
+ });
112
+ }
113
+ else {
114
+ validOpsConfig = true;
115
+ }
116
+ return validOpsConfig;
117
+ };
118
+ exports.checkOpsConfig = checkOpsConfig;
@@ -1 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blixify-server",
3
- "version": "0.1.65",
3
+ "version": "0.1.67",
4
4
  "license": "MIT",
5
5
  "main": "dist/apis/index.js",
6
6
  "private": false,
@@ -56,7 +56,7 @@
56
56
  "eslint": "^8.16.0",
57
57
  "express": "^4.18.1",
58
58
  "express-rate-limit": "^6.6.0",
59
- "firebase-admin": "^11.10.1",
59
+ "firebase-admin": "^12.2.0",
60
60
  "helmet": "^6.0.0",
61
61
  "husky": "^8.0.2",
62
62
  "mongodb": "^4.11.0",