UNPKG

21.7 kBJavaScriptView Raw
1var express = require('express');
2var Promise = require('bluebird');
3var router = express.Router();
4var _ = require('lodash');
5var middleware = require('../core/middleware');
6var validator = require('validator');
7var accountManager = require('../core/services/account-manager')();
8var Deployments = require('../core/services/deployments');
9var Collaborators = require('../core/services/collaborators');
10var AppManager = require('../core/services/app-manager');
11var PackageManager = require('../core/services/package-manager');
12var AppError = require('../core/app-error');
13var common = require('../core/utils/common');
14var config = require('../core/config');
15const REGEX = /^(\w+)(-android|-ios)$/;
16const REGEX_ANDROID = /^(\w+)(-android)$/;
17const REGEX_IOS = /^(\w+)(-ios)$/;
18var log4js = require('log4js');
19var log = log4js.getLogger("cps:apps");
20
21router.get('/', middleware.checkToken, (req, res, next) => {
22 var uid = req.users.id;
23 var appManager = new AppManager();
24 appManager.listApps(uid)
25 .then((data) => {
26 res.send({apps: data});
27 })
28 .catch((e) => {
29 if (e instanceof AppError.AppError) {
30 res.status(406).send(e.message);
31 } else {
32 next(e);
33 }
34 });
35});
36
37router.get('/:appName/deployments',
38 middleware.checkToken, (req, res, next) => {
39 var uid = req.users.id;
40 var appName = _.trim(req.params.appName);
41 var deployments = new Deployments();
42 accountManager.collaboratorCan(uid, appName)
43 .then((col) => {
44 return deployments.listDeloyments(col.appid);
45 })
46 .then((data) => {
47 res.send({deployments: data});
48 })
49 .catch((e) => {
50 if (e instanceof AppError.AppError) {
51 res.status(406).send(e.message);
52 } else {
53 next(e);
54 }
55 });
56});
57
58router.get('/:appName/deployments/:deploymentName',
59 middleware.checkToken, (req, res, next) => {
60 var uid = req.users.id;
61 var appName = _.trim(req.params.appName);
62 var deploymentName = _.trim(req.params.deploymentName);
63 var deployments = new Deployments();
64 accountManager.collaboratorCan(uid, appName)
65 .then((col) => {
66 return deployments.findDeloymentByName(deploymentName, col.appid)
67 })
68 .then((deploymentInfo) => {
69 if (_.isEmpty(deploymentInfo)) {
70 throw new AppError.AppError("does not find the deployment");
71 }
72 res.send({deployment: deployments.listDeloyment(deploymentInfo)});
73 return true;
74 })
75 .catch((e) => {
76 if (e instanceof AppError.AppError) {
77 res.status(406).send(e.message);
78 } else {
79 next(e);
80 }
81 });
82});
83
84router.post('/:appName/deployments',
85 middleware.checkToken, (req, res, next) => {
86 var uid = req.users.id;
87 var appName = _.trim(req.params.appName);
88 var name = req.body.name;
89 var deployments = new Deployments();
90 accountManager.ownerCan(uid, appName)
91 .then((col) => {
92 return deployments.addDeloyment(name, col.appid, uid);
93 })
94 .then((data) => {
95 res.send({deployment: {name: data.name, key: data.deployment_key}});
96 })
97 .catch((e) => {
98 if (e instanceof AppError.AppError) {
99 res.status(406).send(e.message);
100 } else {
101 next(e);
102 }
103 });
104});
105
106router.get('/:appName/deployments/:deploymentName/metrics',
107 middleware.checkToken, (req, res, next) => {
108 var uid = req.users.id;
109 var appName = _.trim(req.params.appName);
110 var deploymentName = _.trim(req.params.deploymentName);
111 var deployments = new Deployments();
112 var packageManager = new PackageManager();
113 accountManager.collaboratorCan(uid, appName)
114 .then((col) => {
115 return deployments.findDeloymentByName(deploymentName, col.appid)
116 .then((deploymentInfo) => {
117 if (_.isEmpty(deploymentInfo)) {
118 throw new AppError.AppError("does not find the deployment");
119 }
120 return deploymentInfo;
121 })
122 })
123 .then((deploymentInfo) => {
124 return deployments.getAllPackageIdsByDeploymentsId(deploymentInfo.id);
125 })
126 .then((packagesInfos) => {
127 return Promise.reduce(packagesInfos, (result, v) => {
128 return packageManager.getMetricsbyPackageId(v.get('id'))
129 .then((metrics) => {
130 if (metrics) {
131 result[v.get('label')] = {
132 active: metrics.get('active'),
133 downloaded: metrics.get('downloaded'),
134 failed: metrics.get('failed'),
135 installed: metrics.get('installed'),
136 };
137 }
138 return result;
139 });
140 }, {});
141 })
142 .then((rs) => {
143 res.send({"metrics": rs});
144 })
145 .catch((e) => {
146 if (e instanceof AppError.AppError) {
147 res.send({"metrics": null});
148 } else {
149 next(e);
150 }
151 });
152});
153
154router.get('/:appName/deployments/:deploymentName/history',
155 middleware.checkToken, (req, res, next) => {
156 var uid = req.users.id;
157 var appName = _.trim(req.params.appName);
158 var deploymentName = _.trim(req.params.deploymentName);
159 var deployments = new Deployments();
160 accountManager.collaboratorCan(uid, appName)
161 .then((col) => {
162 return deployments.findDeloymentByName(deploymentName, col.appid)
163 .then((deploymentInfo) => {
164 if (_.isEmpty(deploymentInfo)) {
165 throw new AppError.AppError("does not find the deployment");
166 }
167 return deploymentInfo;
168 });
169 })
170 .then((deploymentInfo) => {
171 return deployments.getDeploymentHistory(deploymentInfo.id);
172 })
173 .then((rs) => {
174 res.send({history: rs});
175 })
176 .catch((e) => {
177 if (e instanceof AppError.AppError) {
178 res.status(406).send(e.message);
179 } else {
180 next(e);
181 }
182 });
183});
184
185router.delete('/:appName/deployments/:deploymentName/history',
186 middleware.checkToken, (req, res, next) => {
187 var uid = req.users.id;
188 var appName = _.trim(req.params.appName);
189 var deploymentName = _.trim(req.params.deploymentName);
190 var deployments = new Deployments();
191 accountManager.ownerCan(uid, appName)
192 .then((col) => {
193 return deployments.findDeloymentByName(deploymentName, col.appid)
194 .then((deploymentInfo) => {
195 if (_.isEmpty(deploymentInfo)) {
196 throw new AppError.AppError("does not find the deployment");
197 }
198 return deploymentInfo;
199 });
200 })
201 .then((deploymentInfo) => {
202 return deployments.deleteDeploymentHistory(deploymentInfo.id);
203 })
204 .then((rs) => {
205 res.send("ok");
206 })
207 .catch((e) => {
208 if (e instanceof AppError.AppError) {
209 res.status(406).send(e.message);
210 } else {
211 next(e);
212 }
213 });
214});
215
216router.patch('/:appName/deployments/:deploymentName',
217 middleware.checkToken, (req, res, next) => {
218 var name = req.body.name;
219 var appName = _.trim(req.params.appName);
220 var deploymentName = _.trim(req.params.deploymentName);
221 var uid = req.users.id;
222 var deployments = new Deployments();
223 accountManager.ownerCan(uid, appName)
224 .then((col) => {
225 return deployments.renameDeloymentByName(deploymentName, col.appid, name);
226 })
227 .then((data) => {
228 res.send({deployment: data});
229 })
230 .catch((e) => {
231 if (e instanceof AppError.AppError) {
232 res.status(406).send(e.message);
233 } else {
234 next(e);
235 }
236 });
237});
238
239router.delete('/:appName/deployments/:deploymentName',
240 middleware.checkToken, (req, res, next) => {
241 var appName = _.trim(req.params.appName);
242 var deploymentName = _.trim(req.params.deploymentName);
243 var uid = req.users.id;
244 var deployments = new Deployments();
245 accountManager.ownerCan(uid, appName)
246 .then((col) => {
247 return deployments.deleteDeloymentByName(deploymentName, col.appid);
248 })
249 .then((data) => {
250 res.send({deployment: data});
251 })
252 .catch((e) => {
253 if (e instanceof AppError.AppError) {
254 res.status(406).send(e.message);
255 } else {
256 next(e);
257 }
258 });
259});
260
261router.post('/:appName/deployments/:deploymentName/release',
262 middleware.checkToken, (req, res, next) => {
263 var appName = _.trim(req.params.appName);
264 var deploymentName = _.trim(req.params.deploymentName);
265 var uid = req.users.id;
266 var deployments = new Deployments();
267 var packageManager = new PackageManager();
268 accountManager.collaboratorCan(uid, appName)
269 .then((col) => {
270 log.debug(col);
271 return deployments.findDeloymentByName(deploymentName, col.appid)
272 .then((deploymentInfo) => {
273 if (_.isEmpty(deploymentInfo)) {
274 log.debug(`does not find the deployment`);
275 throw new AppError.AppError("does not find the deployment");
276 }
277 return packageManager.parseReqFile(req)
278 .then((data) => {
279 if (data.package.type != "application/zip") {
280 log.debug(`upload file type is invlidate`, data.package);
281 throw new AppError.AppError("upload file type is invalidate");
282 }
283 log.debug('packageInfo:', data.packageInfo);
284 return packageManager.releasePackage(deploymentInfo.appid, deploymentInfo.id, data.packageInfo, data.package.path, uid)
285 .finally(() => {
286 common.deleteFolderSync(data.package.path);
287 });
288 })
289 .then((packages) => {
290 if (packages) {
291 Promise.delay(2000)
292 .then(() => {
293 packageManager.createDiffPackagesByLastNums(packages.id, _.get(config, 'common.diffNums', 1))
294 .catch((e) => {
295 console.error(e);
296 });
297 });
298 }
299 //clear cache if exists.
300 if (_.get(config, 'common.updateCheckCache', false) !== false) {
301 Promise.delay(2500)
302 .then(() => {
303 var ClientManager = require('../core/services/client-manager');
304 var clientManager = new ClientManager();
305 clientManager.clearUpdateCheckCache(deploymentInfo.deployment_key, '*', '*', '*');
306 });
307 }
308 return null;
309 });
310 });
311 })
312 .then(() => {
313 res.send('{"msg": "succeed"}');
314 })
315 .catch((e) => {
316 if (e instanceof AppError.AppError) {
317 res.status(406).send(e.message);
318 } else {
319 next(e);
320 }
321 });
322});
323
324router.patch('/:appName/deployments/:deploymentName/release',
325 middleware.checkToken, (req, res, next) => {
326 log.debug('req.body', req.body);
327 var appName = _.trim(req.params.appName);
328 var deploymentName = _.trim(req.params.deploymentName);
329 var uid = req.users.id;
330 var deployments = new Deployments();
331 var packageManager = new PackageManager();
332 var label = _.get(req, 'body.packageInfo.label');
333 accountManager.collaboratorCan(uid, appName)
334 .then((col) => {
335 return deployments.findDeloymentByName(deploymentName, col.appid)
336 .then((deploymentInfo) => {
337 if (_.isEmpty(deploymentInfo)) {
338 throw new AppError.AppError("does not find the deployment");
339 }
340 if (label) {
341 return packageManager.findPackageInfoByDeploymentIdAndLabel(deploymentInfo.id, label)
342 .then((data)=>{
343 return [deploymentInfo, data];
344 });
345 } else {
346 var deploymentVersionId = deploymentInfo.last_deployment_version_id;
347 return packageManager.findLatestPackageInfoByDeployVersion(deploymentVersionId)
348 .then((data)=>{
349 return [deploymentInfo, data];
350 });;
351 }
352 })
353 .spread((deploymentInfo, packageInfo)=>{
354 if (!packageInfo) {
355 throw new AppError.AppError("does not find the packageInfo");
356 }
357 return packageManager.modifyReleasePackage(packageInfo.id, _.get(req, 'body.packageInfo'))
358 .then(()=>{
359 //clear cache if exists.
360 if (_.get(config, 'common.updateCheckCache', false) !== false) {
361 Promise.delay(2500)
362 .then(() => {
363 var ClientManager = require('../core/services/client-manager');
364 var clientManager = new ClientManager();
365 clientManager.clearUpdateCheckCache(deploymentInfo.deployment_key, '*', '*', '*');
366 });
367 }
368 });
369 });
370 }).then((data) => {
371 res.send("");
372 })
373 .catch((e) => {
374 if (e instanceof AppError.AppError) {
375 res.status(406).send(e.message);
376 } else {
377 next(e);
378 }
379 });
380});
381
382
383router.post('/:appName/deployments/:sourceDeploymentName/promote/:destDeploymentName',
384 middleware.checkToken, (req, res, next) => {
385 log.debug('req.body:', req.body);
386 var appName = _.trim(req.params.appName);
387 var sourceDeploymentName = _.trim(req.params.sourceDeploymentName);
388 var destDeploymentName = _.trim(req.params.destDeploymentName);
389 var uid = req.users.id;
390 var packageManager = new PackageManager();
391 var deployments = new Deployments();
392 accountManager.collaboratorCan(uid, appName)
393 .then((col) => {
394 var appId = col.appid;
395 return Promise.all([
396 deployments.findDeloymentByName(sourceDeploymentName, appId),
397 deployments.findDeloymentByName(destDeploymentName, appId)
398 ])
399 .spread((sourceDeploymentInfo, destDeploymentInfo) => {
400 if (!sourceDeploymentInfo) {
401 throw new AppError.AppError(`${sourceDeploymentName} does not exist.`);
402 }
403 if (!destDeploymentInfo) {
404 throw new AppError.AppError(`${destDeploymentName} does not exist.`);
405 }
406 //clear cache if exists.
407 if (_.get(config, 'common.updateCheckCache', false) !== false) {
408 Promise.delay(2500)
409 .then(() => {
410 var ClientManager = require('../core/services/client-manager');
411 var clientManager = new ClientManager();
412 clientManager.clearUpdateCheckCache(destDeploymentInfo.deployment_key, '*', '*', '*');
413 });
414 }
415 return [sourceDeploymentInfo.id, destDeploymentInfo.id];
416 })
417 .spread((sourceDeploymentId, destDeploymentId) => {
418 return packageManager.promotePackage(sourceDeploymentId, destDeploymentId, req.body);
419 });
420 })
421 .then((packages) => {
422 if (packages) {
423 Promise.delay(2000)
424 .then(() => {
425 packageManager.createDiffPackagesByLastNums(packages.id, _.get(config, 'common.diffNums', 1))
426 .catch((e) => {
427 console.log(e);
428 });
429 });
430 }
431 return packages;
432 })
433 .then((packages) => {
434 res.send({package:packages});
435 })
436 .catch((e) => {
437 if (e instanceof AppError.AppError) {
438 res.status(406).send(e.message);
439 } else {
440 next(e);
441 }
442 });
443});
444
445var rollbackCb = function (req, res, next) {
446 var appName = _.trim(req.params.appName);
447 var deploymentName = _.trim(req.params.deploymentName);
448 var uid = req.users.id;
449 var targetLabel = _.trim(_.get(req, 'params.label'));
450 var deployments = new Deployments();
451 var packageManager = new PackageManager();
452 accountManager.collaboratorCan(uid, appName)
453 .then((col) => {
454 return deployments.findDeloymentByName(deploymentName, col.appid);
455 })
456 .then((dep) => {
457 //clear cache if exists.
458 if (_.get(config, 'common.updateCheckCache', false) !== false) {
459 Promise.delay(2500)
460 .then(() => {
461 var ClientManager = require('../core/services/client-manager');
462 var clientManager = new ClientManager();
463 clientManager.clearUpdateCheckCache(dep.deployment_key, '*', '*', '*');
464 });
465 }
466 return packageManager.rollbackPackage(dep.last_deployment_version_id, targetLabel, uid);
467 })
468 .then(() => {
469 res.send('ok');
470 })
471 .catch((e) => {
472 if (e instanceof AppError.AppError) {
473 res.status(406).send(e.message);
474 } else {
475 next(e);
476 }
477 });
478};
479
480router.post('/:appName/deployments/:deploymentName/rollback',
481 middleware.checkToken, rollbackCb);
482
483router.post('/:appName/deployments/:deploymentName/rollback/:label',
484 middleware.checkToken, rollbackCb);
485
486router.get('/:appName/collaborators',
487 middleware.checkToken, (req, res, next) => {
488 var appName = _.trim(req.params.appName);
489 var uid = req.users.id;
490 var collaborators = new Collaborators();
491 accountManager.collaboratorCan(uid, appName)
492 .then((col) => {
493 return collaborators.listCollaborators(col.appid);
494 })
495 .then((data) => {
496 rs = _.reduce(data, (result, value, key) => {
497 if (_.eq(key, req.users.email)) {
498 value.isCurrentAccount = true;
499 }else {
500 value.isCurrentAccount = false;
501 }
502 result[key] = value;
503 return result;
504 },{});
505 res.send({collaborators: rs});
506 })
507 .catch((e) => {
508 if (e instanceof AppError.AppError) {
509 res.status(406).send(e.message);
510 } else {
511 next(e);
512 }
513 });
514});
515
516router.post('/:appName/collaborators/:email',
517 middleware.checkToken, (req, res, next) => {
518 var appName = _.trim(req.params.appName);
519 var email = _.trim(req.params.email);
520 var uid = req.users.id;
521 if (!validator.isEmail(email)){
522 return res.status(406).send("Invalid Email!");
523 }
524 var collaborators = new Collaborators();
525 accountManager.ownerCan(uid, appName)
526 .then((col) => {
527 return accountManager.findUserByEmail(email)
528 .then((data) => {
529 return collaborators.addCollaborator(col.appid, data.id);
530 });
531 })
532 .then((data) => {
533 res.send(data);
534 })
535 .catch((e) => {
536 if (e instanceof AppError.AppError) {
537 res.status(406).send(e.message);
538 } else {
539 next(e);
540 }
541 });
542});
543
544router.delete('/:appName/collaborators/:email',
545 middleware.checkToken, (req, res, next) => {
546 var appName = _.trim(req.params.appName);
547 var email = _.trim(decodeURI(req.params.email));
548 var uid = req.users.id;
549 if (!validator.isEmail(email)){
550 return res.status(406).send("Invalid Email!");
551 }
552 var collaborators = new Collaborators();
553 accountManager.ownerCan(uid, appName)
554 .then((col) => {
555 return accountManager.findUserByEmail(email)
556 .then((data) => {
557 if (_.eq(data.id, uid)) {
558 throw new AppError.AppError("can't delete yourself!");
559 } else {
560 return collaborators.deleteCollaborator(col.appid, data.id);
561 }
562 });
563 })
564 .then(() => {
565 res.send("");
566 })
567 .catch((e) => {
568 if (e instanceof AppError.AppError) {
569 res.status(406).send(e.message);
570 } else {
571 next(e);
572 }
573 });
574});
575
576router.delete('/:appName',
577 middleware.checkToken, (req, res, next) => {
578 var appName = _.trim(req.params.appName);
579 var uid = req.users.id;
580 var appManager = new AppManager();
581 accountManager.ownerCan(uid, appName)
582 .then((col) => {
583 return appManager.deleteApp(col.appid);
584 })
585 .then((data) => {
586 res.send(data);
587 })
588 .catch((e) => {
589 if (e instanceof AppError.AppError) {
590 res.status(406).send(e.message);
591 } else {
592 next(e);
593 }
594 });
595});
596
597router.patch('/:appName',
598 middleware.checkToken, (req, res, next) => {
599 var newAppName = _.trim(req.body.name);
600 var appName = _.trim(req.params.appName);
601 var uid = req.users.id;
602 if (_.isEmpty(newAppName)) {
603 return res.status(406).send("Please input name!");
604 } else {
605 var appManager = new AppManager();
606 return accountManager.ownerCan(uid, appName)
607 .then((col) => {
608 return appManager.findAppByName(uid, newAppName)
609 .then((appInfo) => {
610 if (!_.isEmpty(appInfo)){
611 throw new AppError.AppError(newAppName + " Exist!");
612 }
613 return appManager.modifyApp(col.appid, {name: newAppName});
614 });
615 })
616 .then(() => {
617 res.send("");
618 })
619 .catch((e) => {
620 if (e instanceof AppError.AppError) {
621 res.status(406).send(e.message);
622 } else {
623 next(e);
624 }
625 });
626 }
627});
628
629router.post('/:appName/transfer/:email',
630 middleware.checkToken, (req, res, next) => {
631 var appName = _.trim(req.params.appName);
632 var email = _.trim(req.params.email);
633 var uid = req.users.id;
634 if (!validator.isEmail(email)){
635 return res.status(406).send("Invalid Email!");
636 }
637 return accountManager.ownerCan(uid, appName)
638 .then((col) => {
639 return accountManager.findUserByEmail(email)
640 .then((data) => {
641 if (_.eq(data.id, uid)) {
642 throw new AppError.AppError("You can't transfer to yourself!");
643 }
644 var appManager = new AppManager();
645 return appManager.transferApp(col.appid, uid, data.id);
646 });
647 })
648 .then((data) => {
649 res.send(data);
650 })
651 .catch((e) => {
652 if (e instanceof AppError.AppError) {
653 res.status(406).send(e.message);
654 } else {
655 next(e);
656 }
657 });
658});
659
660router.post('/', middleware.checkToken, (req, res, next) => {
661 log.debug("addApp params:",req.body);
662 var constName = require('../core/const');
663 var appName = req.body.name;
664 if (_.isEmpty(appName)) {
665 return res.status(406).send("Please input name!");
666 }
667 var osName = _.toLower(req.body.os);
668 var os;
669 if (osName == _.toLower(constName.IOS_NAME)) {
670 os = constName.IOS;
671 } else if (osName == _.toLower(constName.ANDROID_NAME)) {
672 os = constName.ANDROID;
673 } else if (osName == _.toLower(constName.WINDOWS_NAME)) {
674 os = constName.WINDOWS;
675 } else {
676 return res.status(406).send("Please input os [iOS|Android|Windows]!");
677 }
678 var platformName = _.toLower(req.body.platform);
679 var platform;
680 if (platformName == _.toLower(constName.REACT_NATIVE_NAME)) {
681 platform = constName.REACT_NATIVE;
682 } else if (platformName == _.toLower(constName.CORDOVA_NAME)) {
683 platform = constName.CORDOVA;
684 } else {
685 return res.status(406).send("Please input platform [React-Native|Cordova]!");
686 }
687 var manuallyProvisionDeployments = req.body.manuallyProvisionDeployments;
688 var uid = req.users.id;
689 var appManager = new AppManager();
690
691 appManager.findAppByName(uid, appName)
692 .then((appInfo) => {
693 if (!_.isEmpty(appInfo)){
694 throw new AppError.AppError(appName + " Exist!");
695 }
696 return appManager.addApp(uid, appName, os, platform, req.users.identical)
697 .then(() => {
698 return {name: appName, collaborators: {[req.users.email]: {permission: "Owner"}}};
699 });
700 })
701 .then((data) => {
702 res.send({app: data});
703 })
704 .catch((e) => {
705 if (e instanceof AppError.AppError) {
706 res.status(406).send(e.message);
707 } else {
708 next(e);
709 }
710 });
711});
712
713module.exports = router;