app.js 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676
  1. const cookieParser = require('cookie-parser');
  2. const cors = require("cors");
  3. const fs = require("fs");
  4. const globalPath = require("path");
  5. const express = require("express");
  6. const axios = require("axios");
  7. // const SERVER_PORT = process.env.port || process.env.PORT || 53000;
  8. const SERVER_PORT = process.env.port || process.env.PORT || 53000;
  9. // const authProvider = require('./auth/AuthProvider');
  10. const {getFetch, updateFetch} = require('./fetch');
  11. const bodyParser = require('body-parser');
  12. const https = require('https');
  13. const JSZIP = require('jszip');
  14. require('dotenv').config({ path: './env/.env.local' });
  15. const session = require('express-session');
  16. const multer = require('multer');
  17. const XLSX = require('xlsx');
  18. const pptxgen = require('pptxgenjs');
  19. const msal = require('@azure/msal-node');
  20. const FormData = require("form-data");
  21. const {pool, sql} = require('./config/sql.js');
  22. const { v4: uuidv4 } = require('uuid');
  23. const {init} = require('./ext.js');
  24. let POSSIBLE_EXT;
  25. const apiUrl = 'http://192.168.20.99:5050';
  26. const createErrors = require('http-errors');
  27. const gateWayKey = process.env.GATE_WAY_KEY;
  28. const msalConfig = {
  29. auth: {
  30. clientId: process.env.TEAMS_APP_ID,
  31. authority: "https://login.microsoftonline.com/"+process.env.TEAMS_APP_TENANT_ID,
  32. clientSecret: process.env.TEAMS_APP_SECRET,
  33. knownAuthorities: [],
  34. },
  35. cache: {
  36. // your implementation of caching
  37. },
  38. system: {
  39. loggerOptions: { /** logging related options */ }
  40. }
  41. }
  42. const cca = new msal.ConfidentialClientApplication(msalConfig);
  43. const {Document, Packer, Paragraph, TextRun} = require('docx');
  44. const messages = require('dote/src/messages.js');
  45. const { rejects } = require('assert');
  46. let WebSocketServer = require('websocket').server;
  47. // const redirectUri = 'https://localhost:53000/redirect';
  48. const redirectUri = 'https://localhost:53000/redirect';
  49. const storage = multer.diskStorage({
  50. destination: function (req, file, cb) {
  51. cb(null, 'uploads/')
  52. },
  53. filename: function (req, file, cb) {
  54. cb(null, file.originalname) // 원래 파일이름으로 저장
  55. }
  56. })
  57. const upload = multer(storage);
  58. const serverApp = express();
  59. const endPoint = process.env.GRAPH_API_ENDPOINT + 'v1.0';
  60. serverApp.use(session({
  61. secret: process.env.EXPRESS_SESSION_SECRET,
  62. resave: false,
  63. saveUninitialized: true,
  64. cookie: {
  65. httpOnly: true,
  66. secure: true, // set this to true on production
  67. sameSite: 'none',
  68. maxAge: 60 * 60 * 24 * 1000
  69. }
  70. }));
  71. serverApp.set(express.json());
  72. serverApp.use(cookieParser());
  73. serverApp.use(express.urlencoded({ extended: false }));
  74. serverApp.use("/static", express.static(globalPath.join(__dirname, 'static')));
  75. const options = {
  76. key: process.env.SSL_KEY_FILE ? fs.readFileSync(process.env.SSL_KEY_FILE) : undefined,
  77. cert: process.env.SSL_CRT_FILE ? fs.readFileSync(process.env.SSL_CRT_FILE) : undefined,
  78. };
  79. const server = https.createServer(options, serverApp);
  80. let wsServer = new WebSocketServer({
  81. httpServer: server,
  82. ssl : true,
  83. key : process.env.SSL_KEY_FILE ? fs.readFileSync(process.env.SSL_KEY_FILE) : undefined,
  84. cert: process.env.SSL_CRT_FILE ? fs.readFileSync(process.env.SSL_CRT_FILE) : undefined,
  85. });
  86. wsServer.on('request', function(req) {
  87. var connection = req.accept();
  88. connection.on('message', function(message) {
  89. if (message && message.type === 'utf8') {
  90. const { value } = JSON.parse(message.utf8Data);
  91. if (value) {
  92. try {
  93. getPercentageComplete(value, connection);
  94. }
  95. catch (error) {
  96. // console.log(error);
  97. console.log(error.message);
  98. console.log(error.name);
  99. console.log(error.errors);
  100. connection.sendUTF(error);
  101. // return res.json(error);
  102. }
  103. }
  104. }
  105. })
  106. });
  107. async function getPercentageComplete(url, connection) {
  108. const result = await axios.get(url);
  109. if (result && result.data && result.data.percentageComplete >= 0) {
  110. const percent = result.data.percentageComplete;
  111. // console.log(result.data);
  112. connection.sendUTF(Number(percent.toFixed(2)));
  113. if (result.data.percentageComplete !== 100) {
  114. setTimeout(()=>getPercentageComplete(url, connection), 1000);
  115. }
  116. }
  117. }
  118. const corsOption = {
  119. origin: "*",
  120. }
  121. serverApp.use(cors(corsOption));
  122. serverApp.use(bodyParser.json());
  123. serverApp.get("/tab",
  124. // isAuthenticated,
  125. async function (req, res, next) {
  126. POSSIBLE_EXT = await init();
  127. res.sendFile(globalPath.join(__dirname, "/views/hello.html"),
  128. // { idTokenClaims: req.session.account.idTokenClaims }
  129. );
  130. }
  131. );
  132. serverApp.post("/getProfileOnBehalfOf", async (req, res, next) => {
  133. result = await cca.acquireTokenOnBehalfOf({
  134. oboAssertion: req.body.token,
  135. scopes: [".default"]
  136. });
  137. req.session.tokenCache = result.tokenCache;
  138. req.session.accessToken = result.accessToken;
  139. req.session.idToken = result.idToken;
  140. req.session.account = result.account;
  141. req.session.auth = result;
  142. return res.send(result);
  143. })
  144. // function isAuthenticated(req, res, next) {
  145. // if (!req.session.isAuthenticated) {
  146. // return res.redirect('/auth/signin'); // redirect to sign-in route
  147. // }
  148. // next();
  149. // };
  150. // function isAccessToken(req, res, next) {
  151. // if (!req.session.accessToken) {
  152. // return authProvider.acquireToken({
  153. // scopes: ['.default'],
  154. // redirectUri: redirectUri,
  155. // successRedirect: '/api-redirect'
  156. // })(req, res, next);
  157. // }
  158. // next();
  159. // }
  160. // serverApp.get("/auth/signin", authProvider.login({
  161. // scopes: ['.default'],
  162. // redirectUri: redirectUri,
  163. // successRedirect: '/tab'
  164. // }))
  165. // serverApp.post("/redirect", authProvider.handleRedirect());
  166. serverApp.post("/redirect", (req, res, next)=>{
  167. console.log(req);
  168. });
  169. serverApp.get("/redirect", (req, res, next)=>{
  170. console.log(req);
  171. });
  172. serverApp.post("/api-get",
  173. // isAuthenticated,
  174. // isAccessToken,
  175. async (req, res, next) => {
  176. const uri = req.body.api_uri || req.session.apiUri;
  177. let param = {};
  178. if (req.session.param) {
  179. param = req.session.param;
  180. }
  181. try {
  182. const graphResponse = await getFetch(endPoint + uri, req.session.accessToken, param);
  183. res.json(graphResponse);
  184. } catch (error) {
  185. next(error);
  186. }
  187. });
  188. serverApp.get("/api-redirect",
  189. // isAuthenticated,
  190. async function (req, res, next) {
  191. const uri = req.session.apiUri;
  192. let param = {};
  193. if (req.session.param) {
  194. param = req.session.param;
  195. }
  196. try {
  197. const graphResponse = await getFetch(endPoint + uri, req.session.accessToken, param);
  198. res.json(graphResponse);
  199. } catch (error) {
  200. next(error);
  201. }
  202. })
  203. serverApp.get("/post-redirect",
  204. // isAuthenticated,
  205. async function (req, res, next) {
  206. const uri = req.session.apiUri;
  207. let param = {};
  208. if (req.session.param) {
  209. param = req.session.param;
  210. }
  211. try {
  212. const graphResponse = await updateFetch(endPoint + uri, req.session.accessToken, param);
  213. res.json(graphResponse);
  214. } catch (error) {
  215. next(error);
  216. }
  217. }
  218. )
  219. // serverApp.post("/api-update", authProvider.acquireToken({
  220. // scopes: [],
  221. // redirectUri: redirectUri,
  222. // successRedirect: '/post-redirect'
  223. // }));
  224. // serverApp.post("/api-post", authProvider.acquireToken({
  225. // scopes: ['.default'],
  226. // redirectUri: redirectUri,
  227. // successRedirect: '/post-redirect'
  228. // }));
  229. // serverApp.post("/getGroupList", authProvider.acquireToken({
  230. // scopes: ['.default'],
  231. // redirectUri: redirectUri,
  232. // successRedirect: '/group-redirect'
  233. // }));
  234. serverApp.post("/getGroupList", async function (req, res, next) {
  235. try {
  236. // throw new Error('Error');
  237. // const oneDrive = await getFetch(endPoint + "/me/drive/root", req.session.accessToken);
  238. // const sharePointIds = await getFetch(endPoint + "/me/drive/SharePointIds", req.session.accessToken);
  239. // // const publicTeam = await getFetch(endPoint + "/groups?$filter=groupTypes/any(c:c+eq+'Unified')", req.session.accessToken);
  240. // const graphResponse = await getFetch(endPoint + "/me/joinedTeams", req.session.accessToken);
  241. // const sites = await getFetch(endPoint + "/sites/root", req.session.accessToken);
  242. // const sitesSharePoint = await getFetch(endPoint + "/sites/root/SharePointIds", req.session.accessToken);
  243. const options = getOptions(req.session.accessToken);
  244. const uriArr = [
  245. axios.get(endPoint + "/me/drive/root", options),
  246. axios.get(endPoint + "/me/drive/SharePointIds", options),
  247. axios.get(endPoint + "/me/joinedTeams", options),
  248. axios.get(endPoint + "/sites/root", options),
  249. axios.get(endPoint + "/sites/root/SharePointIds", options),
  250. ]
  251. const result = await Promise.all(uriArr);
  252. const oneDrive = result[0].data;
  253. const sharePointIds = result[1].data;
  254. const graphResponse = result[2].data;
  255. const sites = result[3].data;
  256. const sitesSharePoint = result[4].data;
  257. const teams = graphResponse.value;
  258. oneDrive.sharePoint = sharePointIds;
  259. sites.sharePoint = sitesSharePoint;
  260. const resultObj = {
  261. oneDrive : {
  262. teams: oneDrive,
  263. },
  264. joinedTeams : {
  265. teams : teams,
  266. // teams : public,
  267. items : {},
  268. },
  269. sites : {
  270. teams : sites,
  271. },
  272. }
  273. if (teams && teams.length) {
  274. // if (public && public.length) {
  275. // const options = {
  276. // responseType: 'arraybuffer',
  277. // headers: {
  278. // Authorization: `Bearer ${req.session.accessToken}`,
  279. // ConsistencyLevel: 'eventual',
  280. // withCredentials:true,
  281. // },
  282. // };
  283. for (let team of teams) {
  284. // for (let team of public) {
  285. const item = await getFetch(endPoint + "/groups/"+team.id+"/drive/items/root/children", req.session.accessToken);
  286. const sharePoint = await getFetch(endPoint + "/groups/"+team.id+"/drive/SharePointIds", req.session.accessToken);
  287. // const image = await axios.get(endPoint + "/groups/" + team.id + "/photo/$value", options);
  288. // if (image && image.data) {
  289. // team.image = image.data;
  290. // }
  291. if (sharePoint) {
  292. team.sharePoint = sharePoint;
  293. }
  294. if (item && item.value) {
  295. resultObj.joinedTeams.items[team.id] = item.value;
  296. }
  297. }
  298. }
  299. res.json(resultObj);
  300. } catch (error) {
  301. next(error);
  302. }
  303. });
  304. function isAccessTokens(req, res, next) {
  305. if (!req.session.accessToken) {
  306. return authProvider.acquireToken({
  307. scopes: ['.default'],
  308. redirectUri: redirectUri,
  309. successRedirect: req.url
  310. })(req, res, next);
  311. }
  312. next();
  313. }
  314. serverApp.post('/api/makeFolder',
  315. // isAuthenticated,
  316. // isAccessTokens,
  317. async (req, res, next)=>{
  318. const options = getOptions(req.session.accessToken);
  319. const {siteId, path, name} = req.body;
  320. const resultObj = {message:"", success: 'F'};
  321. const param ={
  322. name: name,
  323. folder: { },
  324. '@microsoft.graph.conflictBehavior': 'rename'
  325. }
  326. try{
  327. const sitesInfo = await axios.get(endPoint + "/sites/"+ siteId + path, options);
  328. if (sitesInfo.data && sitesInfo.data.id) {
  329. const itemId = sitesInfo.data.id;
  330. const result = await axios.post(endPoint + "/sites/"+ siteId +"/drive/items/" + itemId +"/children",param, options);
  331. if (result.data) {
  332. resultObj.message = "폴더가 생성되었습니다.<br>폴더명 : "+ name;
  333. resultObj.success = 'S';
  334. }
  335. else {
  336. resultObj.message = "폴더가 생성되지 않았습니다.";
  337. }
  338. }
  339. else {
  340. resultObj.message = "생성할 폴더 경로를 찾을 수 없습니다.";
  341. }
  342. }
  343. catch(error) {
  344. resultObj.message = "폴더 생성 중 오류가 발생하였습니다.<br>" + getErrorMessage(error);
  345. }
  346. res.json(resultObj);
  347. });
  348. function getErrorMessage(error) {
  349. let errorText = "";
  350. if (error.response && error.response.status && error.response.statusText && error.response.data && error.response.data.error) {
  351. // console.log(error.response);
  352. console.log('=============================== Axios Error ===============================')
  353. console.log('발생시각 : '+ new Date().toLocaleString());
  354. console.log(error.response);
  355. console.log(error.response.data.error);
  356. errorText = `status : ${error.response.status} - ${error.response.statusText}<br>message : ${error.response.data.error.message}`;
  357. }
  358. else {
  359. console.log('================================ Error =====================================')
  360. console.log('발생시각:'+ new Date().toLocaleString());
  361. console.log('에러 : '+ error);
  362. errorText = error;
  363. }
  364. return errorText;
  365. }
  366. serverApp.post('/api/makeWord',
  367. // isAuthenticated,
  368. // isAccessTokens,
  369. async (req, res, next)=>{
  370. const options = getOptions(req.session.accessToken);
  371. const {siteId, path, name} = req.body;
  372. const doc = new Document({
  373. sections : [
  374. {
  375. properties: {},
  376. children : [
  377. new Paragraph({
  378. children: [
  379. ]
  380. })
  381. ]
  382. }
  383. ]
  384. });
  385. Packer.toBuffer(doc).then(async (buffer)=>{
  386. const resultObj = {message:"", success: 'F'};;
  387. try{
  388. const base64EncodeData = Buffer.from(buffer).toString('base64');
  389. const labelData = await setLabel(gateWayKey, req.session.account.idTokenClaims.email, name,
  390. "878173ae-cc36-4881-af57-604af868314c", base64EncodeData, "Make New Word 문서");
  391. if (labelData.success === 'F') {
  392. return res.json(labelData);
  393. }
  394. const sitesInfo = await axios.get(endPoint + "/sites/"+ siteId + path, options);
  395. if (sitesInfo.data && sitesInfo.data.id) {
  396. const itemId = sitesInfo.data.id;
  397. const result = await axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+itemId+':/'+name+':/content', labelData.data, options);
  398. if (result.data) {
  399. resultObj.message = "요청하신 Word 파일이 생성되었습니다.<br>파일명 : "+ name;
  400. resultObj.success = 'S';
  401. }
  402. else {
  403. resultObj.message = "요청하신 Word 파일이 생성되지 않았습니다.";
  404. }
  405. }
  406. else {
  407. resultObj.message = "생성할 폴더 경로를 찾을 수 없습니다.";
  408. }
  409. }
  410. catch(error) {
  411. resultObj.message = "요청하신 Word 파일 생성 중 오류가 발생하였습니다.<br>" + getErrorMessage(error);
  412. }
  413. res.send(resultObj);
  414. });
  415. })
  416. serverApp.post('/api/makeExcel',
  417. // isAuthenticated,
  418. // isAccessTokens,
  419. async (req, res, next)=>{
  420. const options = getOptions(req.session.accessToken);
  421. const {siteId, path, name} = req.body;
  422. const wb = XLSX.utils.book_new();
  423. XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet([]), 'Sheet1');
  424. var wbout = XLSX.write(wb, {bookType:'xlsx', type: 'buffer'});
  425. const base64EncodeData = Buffer.from(wbout).toString('base64');
  426. const resultObj = {message:'', success: 'F'};
  427. try{
  428. const labelData = await setLabel(gateWayKey, req.session.account.idTokenClaims.email, name,
  429. "878173ae-cc36-4881-af57-604af868314c", base64EncodeData, "Make New Excel 통합 문서");
  430. if (labelData.success === 'F') {
  431. return res.json(labelData);
  432. }
  433. const parentData = await axios.get(endPoint + "/sites/"+ siteId +path, options);
  434. if (parentData.data) {
  435. const result = await axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+parentData.data.id+':/'+name+':/content', labelData.data, options);
  436. if (result.data) {
  437. resultObj.message ='요청하신 Excel 파일이 생성 되었습니다.';
  438. resultObj.success = 'S';
  439. }
  440. else{
  441. resultObj.message = '요청하신 Excel 파일이 생성 되지 않았습니다.';
  442. }
  443. }
  444. }
  445. catch(error) {
  446. resultObj.message = "요청하신 Excel 파일 생성 중 오류가 발생하였습니다.<br>" + getErrorMessage(error);
  447. }
  448. res.json(resultObj);
  449. })
  450. async function setLabelFiles(param, headers, lengthSync, apiKey, email) {
  451. console.log('======================setLabelFiles=====================================')
  452. // const param = {
  453. // apiKey: apiKey,
  454. // email: email,
  455. // file : files,
  456. // dispFileName: dispFileName,
  457. // aipGuid: aipGuid,
  458. // fileData: fileData,
  459. // comment: comment,
  460. // }
  461. const resultObj = {
  462. message : null,
  463. success : 'F',
  464. data : null,
  465. }
  466. const errorMessage = '레이블 적용 중 오류가 발생했습니다.<br>에러 : ';
  467. try {
  468. // const result = await axios.post(apiUrl + '/api/v1/stream/set-label', param);
  469. // console.log('실행')
  470. // console.log(param);
  471. const result = await axios.post(apiUrl + '/api/v1/file/encrypt', param, {
  472. headers : {
  473. ...headers,
  474. "Content-Length" : lengthSync,
  475. }
  476. });
  477. // console.log(result.data);
  478. if (result && result.data) {
  479. if (result.data.statusCode === 200 && !result.data.result.errorCode) {
  480. // resultObj.data = Buffer.from(result.data.result.fileData, "base64");
  481. // console.log(param.get('apiKey'));
  482. // console.log(param.get('email'));
  483. const infoParam = {
  484. apiKey: apiKey,
  485. email: email,
  486. dispFileName: result.data.result.dispFileName,
  487. realFileName: result.data.result.outputFileName,
  488. }
  489. // console.log(infoParam);
  490. const infoData = await axios.post(apiUrl + '/api/v1/file/info', infoParam);
  491. // console.log('=================infoData ========================');
  492. // console.log(infoData.data);
  493. resultObj.data = result.data.result;
  494. resultObj.success = 'S';
  495. }
  496. else {
  497. resultObj.message = errorMessage + result.data.result.errorMessage;
  498. }
  499. }
  500. else {
  501. resultObj.message = errorMessage + '수신 데이터 없음';
  502. }
  503. }
  504. catch (error) {
  505. console.log(error);
  506. resultObj.message = errorMessage + JSON.stringify(error);
  507. }
  508. return resultObj;
  509. }
  510. async function setLabel(apiKey, email, dispFileName, aipGuid, fileData, comment) {
  511. const param = {
  512. apiKey: apiKey,
  513. email: email,
  514. dispFileName: dispFileName,
  515. aipGuid: aipGuid,
  516. fileData: fileData,
  517. comment: comment,
  518. }
  519. const resultObj = {
  520. message : null,
  521. success : 'F',
  522. data : null,
  523. }
  524. const errorMessage = '레이블 적용 중 오류가 발생했습니다.<br>에러 : ';
  525. try {
  526. const result = await axios.post(apiUrl + '/api/v1/stream/set-label', param);
  527. if (result && result.data) {
  528. if (result.data.statusCode === 200 && !result.data.result.errorCode && result.data.result.fileData) {
  529. resultObj.data = Buffer.from(result.data.result.fileData, "base64");
  530. resultObj.success = 'S';
  531. }
  532. else {
  533. resultObj.message = errorMessage + result.data.result.errorMessage;
  534. }
  535. }
  536. else {
  537. resultObj.message = errorMessage + '수신 데이터 없음';
  538. }
  539. }
  540. catch (error) {
  541. resultObj.message = errorMessage + JSON.stringify(error);
  542. }
  543. return resultObj;
  544. }
  545. serverApp.post('/api/makePptx',
  546. // isAuthenticated,
  547. // isAccessTokens,
  548. async (req, res, next)=>{
  549. const options = getOptions(req.session.accessToken);
  550. const {siteId, path, name} = req.body;
  551. const pres = new pptxgen();
  552. pres.addSlide();
  553. const resultObj = {message:'', success: 'F'};
  554. pres.stream().then(async (data)=>{
  555. try{
  556. const base64EncodeData = Buffer.from(data).toString('base64');
  557. const labelData = await setLabel(gateWayKey, req.session.account.idTokenClaims.email, name,
  558. "878173ae-cc36-4881-af57-604af868314c", base64EncodeData, "Make New PowerPoint 프레젠테이션");
  559. if (labelData.success === 'F') {
  560. return res.json(labelData);
  561. }
  562. const parentData = await axios.get(endPoint + "/sites/"+ siteId +path, options);
  563. if (parentData.data) {
  564. const result = await axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+parentData.data.id+':/'+name+':/content', labelData.data, options);
  565. if (result.data) {
  566. resultObj.message ='요청하신 PowerPoint 프레젠테이션 파일이 생성 되었습니다.';
  567. resultObj.success = 'S';
  568. }
  569. else{
  570. resultObj.message = '요청하신 PowerPoint 프레젠테이션 파일이 생성 되지 않았습니다.';
  571. }
  572. }
  573. }
  574. catch(error) {
  575. resultObj.message = "요청하신 PowerPoint 프레젠테이션 파일 생성 중 오류가 발생하였습니다.<br>" + getErrorMessage(error);
  576. }
  577. res.json(resultObj);
  578. })
  579. })
  580. serverApp.post('/api/check-name',
  581. // isAuthenticated,
  582. // isAccessTokens,
  583. async (req, res, next)=>{
  584. const options = getOptions(req.session.accessToken);
  585. const {siteId, path, name} = req.body;
  586. try{
  587. const sitesInfo = await axios.get(endPoint + "/sites/"+ siteId + path, options);
  588. if (sitesInfo.data) {
  589. const itemId = sitesInfo.data.id;
  590. const result = await axios.get(endPoint + "/sites/"+ siteId +"/drive/items/" + itemId +"/children", options);
  591. if (result && result.data && result.data.value) {
  592. let idx = result.data.value.findIndex(obj=>obj.name === name);
  593. // console.log(name);
  594. // console.log(idx);
  595. // console.log((idx > -1));
  596. // console.log(result.data.value);
  597. res.json({hasName: (idx > -1)});
  598. }
  599. }
  600. }
  601. catch(error) {
  602. if (error.response) {
  603. console.log("error.response", error.response);
  604. const statusCode = err.response.status; // 400
  605. const statusText = err.response.statusText; // Bad Request
  606. const message = err.response.data.message[0]; // id should not be empty
  607. console.log(`${statusCode} - ${statusText} - ${message}`);
  608. res.json(error.response);
  609. }
  610. else {
  611. console.log(error);
  612. res.json(error);
  613. }
  614. }
  615. });
  616. async function uploadDrive(options, folder, siteId, path) {
  617. const startTime = new Date();
  618. const resultObj = {
  619. success : 'S',
  620. message : '',
  621. }
  622. if (!Array.isArray(folder)) {
  623. folder = [folder];
  624. }
  625. for (let item of folder) {
  626. const fileInfo = JSON.parse(item);
  627. const param = {
  628. name: fileInfo.name,
  629. folder: {},
  630. // '@microsoft.graph.conflictBehavior': 'rename'
  631. };
  632. let folderPath = '';
  633. if (fileInfo.path) {
  634. folderPath = fileInfo.path;
  635. if (!path.includes(':')) {
  636. folderPath = ":" + folderPath;
  637. }
  638. }
  639. let uri = endPoint + "/sites/"+ siteId + path + folderPath;
  640. const result = await new Promise (async (resolve, reject)=>{
  641. axios.get(uri, options).then((sitesInfo)=>{
  642. resolve(sitesInfo.data);
  643. })
  644. .catch((error)=>{
  645. reject(error);
  646. });
  647. })
  648. .then(async (result)=>{
  649. return await new Promise(async (resolve, reject)=>{
  650. axios.post(endPoint + "/sites/"+ siteId +"/drive/items/" + result.id +"/children", param, options)
  651. .then((uploadFolder)=>{
  652. resolve(uploadFolder.data);
  653. })
  654. .catch((error)=>{
  655. reject(error);
  656. });
  657. });
  658. })
  659. .catch((error)=>{
  660. return {success:'F', message: '요청하신 파일 업로드 중 오류가 발생하였습니다.<br>' + getErrorMessage(error)};
  661. });
  662. if (result.success === 'F') {
  663. return result;
  664. }
  665. }
  666. const makeFolderTime = new Date();
  667. console.log('폴더 시작 시간 :', startTime.toLocaleString(), ', 폴더 종료 시간 :', makeFolderTime.toLocaleString(), ', 소요 시간 :', timeCheck(startTime, makeFolderTime));
  668. return resultObj;
  669. }
  670. serverApp.post('/api/upload', upload.array('file'),
  671. async (req, res, next)=>{
  672. const startTime = new Date();
  673. const files = req.files;
  674. let {siteId, path, folder, file_path} = req.body;
  675. if (siteId && path) {
  676. const options = getOptions(req.session.accessToken);
  677. if (folder){
  678. const uploadDriveResult = await uploadDrive(options, folder, siteId, path);
  679. if (uploadDriveResult.success === 'F') {
  680. return res.json(uploadDriveResult);
  681. }
  682. }
  683. let fileWriteTime = new Date();
  684. if (files && files.length > 0) {
  685. const promiseArray = [];
  686. const labelPromiseArray = [];
  687. // const fileWriteArray = [];
  688. const possibleExt = POSSIBLE_EXT;
  689. const {supported_file_ext, protected_file_ext} = possibleExt;
  690. let supportedArr = [];
  691. // let protectedArr = [];
  692. // let protectedMap = new Map();
  693. if (supported_file_ext && protected_file_ext) {
  694. supportedArr = supported_file_ext.split(';');
  695. // protectedArr = protected_file_ext.split(';');
  696. if (!supportedArr[supportedArr.length - 1]) {
  697. supportedArr.splice(supportedArr.length - 1);
  698. }
  699. // if (!protectedArr[protectedArr.length - 1]) {
  700. // protectedArr.splice(protectedArr.length - 1);
  701. // }
  702. // if (protectedArr.length > 0) {
  703. // for (let array of protectedArr) {
  704. // array = array.split('-');
  705. // if (array.length === 2) {
  706. // protectedMap.set(array[0], array[1]);
  707. // }
  708. // }
  709. // }
  710. }
  711. let beforeUri = '';
  712. let beforeItemId = '';
  713. // const siteInfoArr = [];
  714. for (let idx in files) {
  715. const file = files[idx];
  716. //const fileName = file.originalname;
  717. //let filePath = req.body[ fileName + "_path"];
  718. file.originalname = Buffer.from(file.originalname, 'ascii').toString('utf8');
  719. let originName = file.originalname;
  720. if (originName) {
  721. let ext = globalPath.extname(originName);
  722. if (supportedArr.length > 0 && !supportedArr.includes(ext)) {
  723. return res.json({success:'F', message: '파일명 : ' + originName
  724. +'<br>해당 파일은 업로드 불가 파일입니다. 다시 시도해주세요.<br>가능 확장자 :'
  725. + JSON.stringify(supportedArr)});
  726. }
  727. // const uuid = uuidv4();
  728. // const realFileName = uuid + ext;
  729. // fileWriteArray.push(new Promise((resolve, reject) => {
  730. // const data = fs.writeFileSync('Z:/Source/' + realFileName, file.buffer)
  731. // resolve({
  732. // data
  733. // })
  734. // }));
  735. const base64Data = Buffer.from(file.buffer).toString('base64');
  736. const param = {
  737. apiKey: gateWayKey,
  738. email: req.session.account.idTokenClaims.email,
  739. dispFileName: originName,
  740. aipGuid: "878173ae-cc36-4881-af57-604af868314c",
  741. // aipGuid: "0166b75f-6a93-47f3-8fd3-e1e7c59141ab",
  742. // comment: "set-protection",
  743. comment: "set-label",
  744. fileData: base64Data,
  745. }
  746. // labelPromiseArray.push(new Promise(async (resolve)=>{resolve(await axios.post(apiUrl + '/api/v1/stream/set-label', param))}));
  747. labelPromiseArray.push(axios.post(apiUrl + '/api/v1/stream/set-label', param));
  748. // labelPromiseArray.push(axios.post(apiUrl + '/api/v1/stream/set-protection', param));
  749. let formatPath = '';
  750. if (file_path[idx]) {
  751. // console.log(file_path[idx]);
  752. if (!path.includes(":")) {
  753. formatPath = ":" + file_path[idx];
  754. }
  755. else {
  756. formatPath = file_path[idx];
  757. }
  758. }
  759. let itemId = '';
  760. const uri = endPoint + "/sites/"+ siteId + path + formatPath;
  761. // siteInfoArr.push(axios.get(uri, options));
  762. if (beforeUri === uri) {
  763. itemId = beforeItemId;
  764. }
  765. else {
  766. try {
  767. const sitesInfo = await axios.get(uri, options);
  768. itemId = sitesInfo.data.id;
  769. beforeUri = uri;
  770. beforeItemId = itemId;
  771. }
  772. catch(error) {
  773. console.log(error);
  774. res.json({success:'F', message: '파일 업로드 작업 중 오류가 발생했습니다.<br>에러 : ' + JSON.stringify(error.message)});
  775. }
  776. }
  777. // if (protectedMap.size > 0 && protectedMap.get(ext)) {
  778. // let name = originName.replace(ext, '');
  779. // ext = protectedMap.get(ext);
  780. // originName = name + ext;
  781. // }
  782. promiseArray.push(endPoint + "/sites/"+ siteId +"/drive/items/"+itemId+':/');
  783. }
  784. }
  785. try {
  786. // const siteInfos = await Promise.all(siteInfoArr);
  787. // siteInfos.forEach((obj)=>{
  788. // promiseArray.push(endPoint + "/sites/"+ siteId +"/drive/items/"+obj.data.id+':/');
  789. // })
  790. //file write 시 사용
  791. //const writeArr = await Promise.all(fileWriteArray);
  792. let writeTime = timeCheck(fileWriteTime, new Date());
  793. console.log('파일 Write Time : '+ writeTime);
  794. const labelTime = new Date();
  795. const labelResult = await Promise.all(labelPromiseArray);
  796. // console.log(labelResult[0].data.result.fileData);
  797. console.log('label time : ', timeCheck(labelTime, new Date()));
  798. for (let idx in labelResult) {
  799. const obj = labelResult[idx];
  800. if (obj.data && !obj.data.result.errorCode && obj.data.result.fileData) {
  801. const data = Buffer.from(obj.data.result.fileData, 'base64');
  802. // promiseArray[idx] = new Promise(async (resolve)=> resolve(await axios.put(promiseArray[idx] + obj.data.result.dispFileName + ':/content', data, options)));
  803. promiseArray[idx] = axios.put(promiseArray[idx] + obj.data.result.dispFileName + ':/content', data, options);
  804. // promiseArray.push(axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+ siteInfos[idx].data.id + ':/' + obj.data.result.dispFileName + ':/content', data, options));
  805. }
  806. else {
  807. throw '파일명 : '+obj.data.result.dispFileName + '<br>에러 : ' + obj.data.result.errorMessage;
  808. }
  809. }
  810. // labelResult.forEach((obj, idx)=>{
  811. // if (obj.data && !obj.data.result.errorCode && obj.data.result.fileData) {
  812. // const data = Buffer.from(obj.data.result.fileData, 'base64');
  813. // promiseArray[idx] = axios.put(promiseArray[idx] + obj.data.result.dispFileName + ':/content', data, options);
  814. // // promiseArray.push(axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+ siteInfos[idx].data.id + ':/' + obj.data.result.dispFileName + ':/content', data, options));
  815. // }
  816. // else {
  817. // throw '파일명 : '+obj.data.result.dispFileName + '<br>에러 : ' + obj.data.result.errorMessage;
  818. // }
  819. // })
  820. // const readArray = [];
  821. // labelResult.forEach((obj)=>{
  822. // readArray.push(new Promise((resolve, reject)=>{
  823. // if (obj.data && !obj.data.result.errorCode) {
  824. // fs.readFile('Z:/Target/' + obj.data.result.outputFileName, (err, data)=>{
  825. // if (err) {
  826. // reject({err});
  827. // }
  828. // resolve({data});
  829. // //promiseArray[idx] = axios.put(promiseArray[idx], data, options);
  830. // });
  831. // }
  832. // else {
  833. // reject(obj.data.result.errorMessage);
  834. // }
  835. // }))
  836. // });
  837. // console.log('labelResult : ', labelResult);
  838. // let readTime = new Date();
  839. // const readResult = await Promise.all(readArray);
  840. // console.log(readResult);
  841. // console.log('File Read time : ', timeCheck(readTime, new Date()));
  842. let uploadTime = new Date();
  843. // promiseArray.forEach((obj, idx)=>{
  844. // // console.log(readResult[idx].data);
  845. // // console.log(obj[idx]);
  846. // promiseArray[idx] = axios.put(obj, readResult[idx].data, options);
  847. // });
  848. const uploadResult = await Promise.all(promiseArray);
  849. console.log('File uploadTime : ', timeCheck(uploadTime, new Date()));
  850. }
  851. catch(error){
  852. return res.json({success:'F', message: '요청하신 파일 업로드 중 오류가 발생하였습니다.<br>' + getErrorMessage(error)});
  853. }
  854. }
  855. const endTime = new Date();
  856. let betweenTime = timeCheck(startTime, endTime);
  857. console.log('시작 시간 :', startTime.toLocaleString(), ', 종료 시간 :', endTime.toLocaleString(), ', 소요 시간 :', betweenTime);
  858. res.json({success:'S', message: '요청하신 파일 업로드가 정상적으로 처리 되었습니다.'});
  859. }
  860. else {
  861. return res.json({success:'F', message: '업로드 요청 파라미터 정보를 확인해 주세요.'});
  862. }
  863. });
  864. function timeCheck(startTime, endTime) {
  865. let betweenTime = endTime - startTime;
  866. if (betweenTime > 60000) {
  867. betweenTime = (betweenTime/1000/60) + ' 분';
  868. }
  869. else {
  870. betweenTime = (betweenTime/1000) + ' 초';
  871. }
  872. return betweenTime;
  873. }
  874. serverApp.post('/api/download',
  875. async (req, res, next)=>{
  876. try {
  877. let startTime = new Date();
  878. const {siteId, path, fileIds, zipName} = req.body;
  879. if (siteId && path && fileIds) {
  880. const options = getOptions(req.session.accessToken);
  881. const arr = JSON.parse(fileIds);
  882. const url = endPoint + "/sites/"+ siteId + "/drive/items/";
  883. const result = await axios(url + arr[0], options);
  884. // 단일 파일 다운로드
  885. if (arr.length === 1 && result && result.data && result.data.file) {
  886. const dataUrl = result.data['@microsoft.graph.downloadUrl'];
  887. const fileOption = {responseType: 'arraybuffer', headers: { withCredentials : true }};
  888. const fileData = await axios.get(dataUrl, fileOption);
  889. const bufferData = Buffer.from(fileData.data, 'base64');
  890. const param = {
  891. apiKey: gateWayKey,
  892. email : res.session.account.idTokenClaims.email,
  893. dispFileName: result.data.name,
  894. comment: "",
  895. fileData: Buffer.from(bufferData).toString('base64')
  896. }
  897. const deleteLabelResult = await axios.post(apiUrl + '/api/v1/stream/delete-label', param);
  898. if (deleteLabelResult && deleteLabelResult.data && !deleteLabelResult.data.result.errorCode) {
  899. return res.json({success: 'S', data: Buffer.from(data.data, 'base64'), name: deleteLabelResult.data.result.name})
  900. }
  901. }
  902. //폴더 또는 다중 파일 다운로드
  903. else {
  904. const zip = new JSZIP();
  905. // const downObj = await getFolderItems(url, arr, options, req.session, zip);
  906. const timer = new Date();
  907. console.log('getFolderItems Start : ', timer.toLocaleString());
  908. await getFolderItems(url, arr, options, req.session, zip);
  909. const timerEnd = new Date();
  910. console.log('getFolderItems end : ', timerEnd.toLocaleString(), ',소요시간 : '+ timeCheck(timer,timerEnd));
  911. // createZipFile(downObj, zip);
  912. const now = new Date();
  913. const year = now.getFullYear().toString();
  914. let month = now.getMonth() + 1;
  915. if (month < 10) month = "0" + month;
  916. let date = now.getDate();
  917. if (date < 10) date = "0" + date;
  918. zip.generateAsync({
  919. type: 'nodebuffer',
  920. // mimeType: 'application/epub+zip',
  921. // compression: 'DEFLATE',
  922. // compressionOptions: {
  923. // level: 9
  924. // },
  925. }).then((resZip)=>{
  926. const endTime = new Date();
  927. console.log('시작 시간 :', startTime.toLocaleString(), ', 종료 시간 :', endTime.toLocaleString(), ', 소요 시간 :', timeCheck(startTime, endTime));
  928. return res.json({success: 'S', data: resZip, name: zipName + '_' + year + '-' + month + '-' + date + '.zip'});
  929. })
  930. .catch((error)=>{
  931. console.log(error);
  932. return res.json({success: 'F', message:'파일 다운로드 중 오류가 발생하였습니다.', error: error});
  933. });
  934. }
  935. }
  936. else {
  937. return res.json({message:'다운로드 파일 정보를 확인 할 수 없습니다.', success:'F'})
  938. }
  939. }
  940. catch(error) {
  941. return res.json({success: 'F', message:'파일 다운로드 중 오류가 발생하였습니다.<br>'+ getErrorMessage(error)});
  942. }
  943. }
  944. );
  945. serverApp.post('/api/folderMove', async (req, res, next)=>{
  946. if (req.body) {
  947. const {id, name, siteId, driveId, text, moveSiteId, movePath} = req.body;
  948. const resultObj = {message:'폴더 이동에 실패 하였습니다.', success: 'F'};
  949. if (name && isNaN(name)) {
  950. const nameArray = JSON.parse(name);
  951. const options = getOptions(req.session.accessToken);
  952. if (nameArray && nameArray.length > 0) {
  953. for (let moveItem of nameArray) {
  954. if (moveItem) {
  955. try {
  956. const copyFolderPath = `${endPoint}/sites/${siteId}/drive/items/${moveItem.id}`;
  957. const result = await axios.get(copyFolderPath, options);
  958. if (result && result.data) {
  959. const data = result.data;
  960. const moveUri = `${endPoint}/sites/${moveSiteId}/${movePath}`;
  961. const moveFolderResult = await findSubFolder(data, moveUri, moveSiteId, options);
  962. console.log('moveFolderResult : ',moveFolderResult);
  963. if (!moveFolderResult) {
  964. resultObj.message ='폴더 이동 중 오류가 발생하였습니다.';
  965. }
  966. else {
  967. await axios.delete(endPoint + "/sites/"+ siteId + "/drive/items/" + moveItem.id, options);
  968. resultObj.message ='폴더 이동 되었습니다.';
  969. resultObj.success = 'S';
  970. }
  971. }
  972. }
  973. catch (error) {
  974. console.log(error.message);
  975. console.log(error.name);
  976. console.log(error.errors);
  977. resultObj.message = error.errors;
  978. // resultObj.failItems.push(moveItem);
  979. }
  980. }
  981. }
  982. }
  983. }
  984. return res.json(resultObj);
  985. }
  986. })
  987. async function findSubFolder(data, movePath, moveSiteId, options) {
  988. let resultType = false;
  989. try {
  990. const moveItem = await axios.get(movePath, options);
  991. if (moveItem.data && moveItem.data.id) {
  992. const param = {
  993. "name": data.name,
  994. "folder": {},
  995. "@microsoft.graph.conflictBehavior": "rename"
  996. }
  997. const makeFolderData = await axios.post(`${endPoint}/sites/${moveSiteId}/drive/items/${moveItem.data.id}/children`, param, options);
  998. if (makeFolderData && makeFolderData.data) {
  999. const makeFolderPath = `${endPoint}/sites/${moveSiteId}/${makeFolderData.data.parentReference.path}/${data.name}`;
  1000. if (data.folder.childCount) {
  1001. const siteId = data.parentReference.siteId;
  1002. const childrenData = await axios.get(`${endPoint}/sites/${siteId}/drive/items/${data.id}/children`, options);
  1003. if (childrenData && childrenData.data && childrenData.data.value) {
  1004. const childrenValues = childrenData.data.value;
  1005. if (childrenValues.length > 0) {
  1006. for (let ii = 0; ii < childrenValues.length; ii++) {
  1007. const children = childrenValues[ii];
  1008. if (children && children.folder) {
  1009. const result = await findSubFolder(children, makeFolderPath, moveSiteId, options);
  1010. resultType = result;
  1011. }
  1012. else {
  1013. const dataUrl = children['@microsoft.graph.downloadUrl'];
  1014. const response = await axios.get(dataUrl, {responseType: 'arraybuffer', headers: {
  1015. withCredentials:true,
  1016. },});
  1017. if (response.data) {
  1018. const file = response.data;
  1019. const uploadResult = await axios.put(`${endPoint}/sites/${moveSiteId}/drive/items/${makeFolderData.data.id}:/${children.name}:/content`,
  1020. file.buffer, options);
  1021. if (uploadResult) {
  1022. resultType = true;
  1023. }
  1024. }
  1025. }
  1026. }
  1027. }
  1028. }
  1029. }
  1030. }
  1031. }
  1032. }
  1033. catch(error) {
  1034. console.log(error);
  1035. return resultType;
  1036. }
  1037. return resultType;
  1038. }
  1039. function createZipFile(obj, zip) {
  1040. if (obj.files && obj.files.length > 0) {
  1041. for (let file of obj.files) {
  1042. console.log(file.name);
  1043. zip.file(file.name, file.data, {base64: true});
  1044. }
  1045. }
  1046. if (obj.folder && obj.folder.length > 0) {
  1047. for (let folder of obj.folder) {
  1048. console.log(folder.name);
  1049. zip.folder(folder.name);
  1050. if (folder.subFolder) {
  1051. createZipFile(folder.subFolder, zip.folder(folder.name));
  1052. }
  1053. }
  1054. }
  1055. }
  1056. async function getFolderItems(url, array, options, session, zip) {
  1057. // const files = [];
  1058. // const folder = [];
  1059. const sitesInfoArr = [];
  1060. const fileArr = [];
  1061. const fileInfoArr = [];
  1062. // const folderCheckTime = new Date();
  1063. // for (let fileId of array) {
  1064. // sitesInfoArr.push(axios.get(url + fileId, options));
  1065. // }
  1066. // const siteInfos = await Promise.all(sitesInfoArr).catch((error)=>{
  1067. // console.log(error);
  1068. // throw error;
  1069. // });
  1070. for (let fileId of array) {
  1071. sitesInfoArr.push(axios.get(url + fileId, options));
  1072. }
  1073. const siteInfos = await Promise.all(sitesInfoArr);
  1074. for (let site of siteInfos) {
  1075. const data = site.data;
  1076. if (data) {
  1077. if (data.folder) {
  1078. // const folderObj = {name : data.name, subFolder : []};
  1079. zip.folder(data.name);
  1080. if (data.folder.childCount) {
  1081. const itemsData = await axios.get(url + data.id + '/children', options);
  1082. if (itemsData && itemsData.data && itemsData.data.value.length > 0) {
  1083. const idArr = [];
  1084. for (let children of itemsData.data.value) {
  1085. idArr.push(children.id);
  1086. }
  1087. try {
  1088. // let result = await getFolderItems(url, idArr, options, session, zip.folder(data.name));
  1089. await getFolderItems(url, idArr, options, session, zip.folder(data.name));
  1090. // folderObj.subFolder = result;
  1091. }
  1092. catch(error) {
  1093. if (error) {
  1094. throw error;
  1095. }
  1096. }
  1097. // subFolder.push(result);
  1098. }
  1099. }
  1100. // folder.push(folderObj);
  1101. }
  1102. else {
  1103. const dataUrl = data['@microsoft.graph.downloadUrl'];
  1104. const fileOption = {responseType: 'arraybuffer', headers: { withCredentials : true }};
  1105. fileArr.push(axios.get(dataUrl, fileOption));
  1106. fileInfoArr.push(data);
  1107. }
  1108. }
  1109. }
  1110. // console.log('======================= folder check end ===============================');
  1111. // console.log('folder check 소요시간 : ', timeCheck(folderCheckTime, new Date()));
  1112. // console.log('======================= delete label start ===============================');
  1113. const fileDataArr = await Promise.all(fileArr).then((result)=>{
  1114. let deleteLabelArr = [];
  1115. for (let idx in result) {
  1116. let fileData = result[idx].data;
  1117. const param = {
  1118. apiKey: gateWayKey,
  1119. email : session.account.idTokenClaims.email,
  1120. dispFileName: fileInfoArr[idx].name,
  1121. comment: "",
  1122. fileData: Buffer.from(fileData).toString('base64')
  1123. }
  1124. deleteLabelArr.push(axios.post(apiUrl + '/api/v1/stream/delete-label', param));
  1125. }
  1126. return deleteLabelArr;
  1127. });
  1128. // const deleteLabelTime = new Date();
  1129. // const deleteLabelArr = [];
  1130. // for (let idx in fileDataArr) {
  1131. // let fileData = fileDataArr[idx].data;
  1132. // const param = {
  1133. // apiKey: gateWayKey,
  1134. // email : session.account.idTokenClaims.email,
  1135. // dispFileName: fileInfoArr[idx].name,
  1136. // comment: "",
  1137. // fileData: Buffer.from(fileData).toString('base64')
  1138. // }
  1139. // deleteLabelArr.push(axios.post(apiUrl + '/api/v1/stream/delete-label', param));
  1140. // }
  1141. const deleteLabelFiles = await Promise.all(fileDataArr);
  1142. // const deleteLabelFiles = await Promise.all(deleteLabelArr);
  1143. for (let idx in deleteLabelFiles) {
  1144. const fileObj = deleteLabelFiles[idx];
  1145. const data = fileObj.data;
  1146. if (data.success && !data.result.errorCode) {
  1147. // files.push({name : data.result.dispFileName, data: data.result.fileData});
  1148. zip.file(data.result.dispFileName, data.result.fileData, {base64: true});
  1149. }
  1150. else {
  1151. throw data.result.dispFileName + ' : ' + data.result.errorMessage;
  1152. }
  1153. }
  1154. // console.log('======================= delete label end ===============================')
  1155. // console.log('delete label 소요시간 : ',timeCheck(deleteLabelTime, new Date()));
  1156. // const resultObj = {
  1157. // folder : folder,
  1158. // files : files,
  1159. // };
  1160. // return resultObj;
  1161. }
  1162. serverApp.post('/api/getPossibleExtList', async (req, res, next)=>{
  1163. return res.json(POSSIBLE_EXT);
  1164. })
  1165. serverApp.post('/api/delete',
  1166. // isAuthenticated,
  1167. // isAccessTokens,
  1168. async (req, res, next)=>{
  1169. if (req.body) {
  1170. const {siteId, itemIds} = req.body;
  1171. const resultObj = {success: '', message:''};
  1172. if (siteId && itemIds) {
  1173. const itemIdArr = JSON.parse(itemIds);
  1174. if (itemIdArr.length > 0) {
  1175. const options = getOptions(req.session.accessToken);
  1176. for (let itemId of itemIdArr) {
  1177. try{
  1178. await axios.delete(endPoint + "/sites/"+ siteId + "/drive/items/" + itemId, options);
  1179. }
  1180. catch(error) {
  1181. resultObj.success = 'F';
  1182. let message = '선택하신 파일 정보 삭제중 오류가 발생하였습니다.';
  1183. if (error && error.response && error.response.data && error.response.data.error && error.response.data.error.message) {
  1184. console.log(error.response.data.error.message);
  1185. message += '<br>' + error.response.data.error.message;
  1186. }
  1187. resultObj.message = message;
  1188. return res.json(resultObj);
  1189. }
  1190. }
  1191. resultObj.success = 'S';
  1192. resultObj.message = '파일 정보가 삭제되었습니다.';
  1193. res.json(resultObj);
  1194. }
  1195. }
  1196. else {
  1197. resultObj.success = 'F';
  1198. resultObj.message = '파라미터 정보를 확인해주세요.';
  1199. res.json(resultObj);
  1200. }
  1201. }
  1202. })
  1203. serverApp.post('/api/update-name',
  1204. // isAuthenticated,
  1205. // isAccessTokens,
  1206. async (req, res, next)=>{
  1207. if (req.body) {
  1208. const {siteId, itemId, name} = req.body;
  1209. const resultObj = {success: '', message:''};
  1210. if (siteId && itemId && name) {
  1211. const options = getOptions(req.session.accessToken);
  1212. try{
  1213. await axios.patch(endPoint + "/sites/"+ siteId + "/drive/items/" + itemId, {name : name}, options);
  1214. }
  1215. catch(error) {
  1216. console.log(error.response.data.error);
  1217. resultObj.success = 'F';
  1218. resultObj.message = '선택하신 파일의 이름 변경 중 오류가 발생하였습니다.<br>' + error.response.data.error.message;
  1219. return res.json(resultObj);
  1220. }
  1221. resultObj.success = 'S';
  1222. resultObj.message = '선택하신 파일의 이름이 변경되었습니다.';
  1223. return res.json(resultObj);
  1224. }
  1225. }
  1226. else {
  1227. resultObj.success = 'F';
  1228. resultObj.message = '파라미터 정보를 확인해주세요.';
  1229. return res.json(resultObj);
  1230. }
  1231. });
  1232. serverApp.post('/api/move-item',
  1233. // isAuthenticated,
  1234. // isAccessTokens,
  1235. async (req, res, next)=>{
  1236. if (req.body) {
  1237. const {id, name, siteId, text} = req.body;
  1238. const resultObj = {message:'', successItems : [], failItems : [], locations: []};
  1239. if (name && isNaN(name)) {
  1240. const nameArray = JSON.parse(name);
  1241. const options = getOptions(req.session.accessToken);
  1242. if (nameArray && nameArray.length > 0) {
  1243. for (let moveItem of nameArray) {
  1244. if (moveItem) {
  1245. const param = {
  1246. parentReference: {
  1247. id: id,
  1248. },
  1249. name: moveItem.name
  1250. };
  1251. try {
  1252. const result = await axios.patch(`${endPoint}/sites/${siteId}/drive/items/${moveItem.id}`, param, options);
  1253. if (result) {
  1254. resultObj.successItems.push(moveItem);
  1255. // resultObj.locations.push(result.headers.location);
  1256. }
  1257. }
  1258. catch (error) {
  1259. // console.log(error);
  1260. console.log(error.message);
  1261. console.log(error.name);
  1262. console.log(error.errors);
  1263. resultObj.failItems.push(moveItem);
  1264. }
  1265. }
  1266. }
  1267. resultObj.message = `요청 하신 ${nameArray.length} 개 파일 중 ${ resultObj.successItems.length} 개 파일이 ${text} 되었습니다.`;
  1268. }
  1269. }
  1270. return res.json(resultObj);
  1271. }
  1272. });
  1273. serverApp.post('/api/copy-item',
  1274. // isAuthenticated,
  1275. // isAccessTokens,
  1276. async (req, res, next)=>{
  1277. if (req.body) {
  1278. const {id, name, siteId, driveId, text} = req.body;
  1279. const resultObj = {message:'', successItems : [], failItems : [], locations: []};
  1280. if (name && isNaN(name)) {
  1281. const nameArray = JSON.parse(name);
  1282. const options = getOptions(req.session.accessToken);
  1283. if (nameArray && nameArray.length > 0) {
  1284. for (let moveItem of nameArray) {
  1285. if (moveItem) {
  1286. const param = {
  1287. parentReference: {
  1288. id: id,
  1289. driveId : driveId,
  1290. },
  1291. name: moveItem.name
  1292. };
  1293. try {
  1294. const result = await axios.post(`${endPoint}/sites/${siteId}/drive/items/${moveItem.id}/copy`, param, options);
  1295. if (result) {
  1296. resultObj.successItems.push(moveItem);
  1297. resultObj.locations.push(result.headers.location);
  1298. }
  1299. }
  1300. catch (error) {
  1301. // console.log(error);
  1302. console.log(error.message);
  1303. console.log(error.name);
  1304. console.log(error.errors);
  1305. resultObj.failItems.push(moveItem);
  1306. }
  1307. }
  1308. }
  1309. resultObj.message = `요청 하신 ${nameArray.length} 개 파일 중 ${ resultObj.successItems.length} 개 파일이 ${text} 되었습니다.`;
  1310. }
  1311. }
  1312. return res.json(resultObj);
  1313. }
  1314. });
  1315. serverApp.post('/api/loading',
  1316. async (req, res, next)=>{
  1317. if (req.body) {
  1318. const {url} = req.body;
  1319. if (url) {
  1320. try {
  1321. const result = await axios.get(`${url}`);
  1322. if (result && result.data) {
  1323. console.log(result.data);
  1324. return res.json(result.data);
  1325. }
  1326. }
  1327. catch (error) {
  1328. // console.log(error);
  1329. console.log(error.message);
  1330. console.log(error.name);
  1331. console.log(error.errors);
  1332. return res.json(error);
  1333. }
  1334. }
  1335. }
  1336. });
  1337. serverApp.post('/api/add-tab',
  1338. // isAuthenticated,
  1339. // isAccessTokens,
  1340. async (req, res, next)=>{
  1341. if (req.body) {
  1342. const {name, siteId, path, teamId, teamName, bindId} = req.body;
  1343. const resultObj = {message:'', success: 'F'};
  1344. if (name && siteId && path && teamId && teamName) {
  1345. const options = getOptions(req.session.accessToken);
  1346. try {
  1347. const teamInfo = await axios.get(`${endPoint}/teams/${teamId}/channels`, options);
  1348. const sharePoint = await axios.get(`${endPoint}/sites/${siteId}/drive`, options);
  1349. if (teamInfo.data && teamInfo.data.value && sharePoint.data) {
  1350. const sharePointUrl = sharePoint.data.webUrl;
  1351. if (path.includes('/drive/root:/') && sharePointUrl) {
  1352. let channelName = path.replace('/drive/root:/', '');
  1353. const contentUrl = sharePointUrl + '/' + channelName;
  1354. channelName = channelName.substring(0, channelName.indexOf('/'));
  1355. const idx = teamInfo.data.value.findIndex(obj => obj.displayName === channelName);
  1356. resultObj.message = `채널명 : ${channelName}<br>파일명 : ${name}<br>요청하신 채널에 탭으로 설정 되지않았습니다.`;
  1357. if (idx >= 0 && contentUrl) {
  1358. const channelId = teamInfo.data.value[idx].id;
  1359. if (channelId) {
  1360. const param = {
  1361. displayName: name,
  1362. "teamsApp@odata.bind" : `https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/${bindId}`,
  1363. configuration: {
  1364. entityId: null,
  1365. contentUrl: contentUrl,
  1366. websiteUrl: "",
  1367. removeUrl: null
  1368. }
  1369. }
  1370. //sites/root/lists
  1371. const channelInfo = await axios.post(`${endPoint}/teams/${teamId}/channels/${channelId}/tabs`, param, options);
  1372. if (channelInfo.data) {
  1373. resultObj.success = 'S';
  1374. resultObj.message = '채널명 : ' + channelName + '<br>파일명 : '+name+'<br>요청하신 채널에 탭으로 설정 되었습니다.';
  1375. }
  1376. }
  1377. }
  1378. }
  1379. }
  1380. }
  1381. catch (error) {
  1382. resultObj.message = `채널명 : ${channelName}<br>파일명 : ${name}<br>요청하신 채널에 탭으로 설정 중 오류가 발생하였습니다.<br>` + getErrorMessage(error);
  1383. }
  1384. }
  1385. return res.json(resultObj);
  1386. }
  1387. });
  1388. // // 데이터베이스 연결
  1389. // pool.connect((err) => {
  1390. // // 연결이 안될 경우 에러 내용 콘솔에 출력
  1391. // if (err) {
  1392. // console.error('Error connecting to database:', err);
  1393. // return;
  1394. // }
  1395. // // 연결에 성공할 경우 연결 성공 메시지 콘솔에 출력
  1396. // console.log('Connected to database');
  1397. // });
  1398. async function getPossibleExt() {
  1399. const resultObj = {
  1400. success : 'F',
  1401. message : null,
  1402. data : null,
  1403. }
  1404. const sqlQuery =
  1405. `SELECT
  1406. A.ConfigValue AS supported_file_ext,
  1407. B.ConfigValue AS protected_file_ext
  1408. FROM (SELECT * FROM TB_AIP_CONFIG WHERE ConfigKey = 'SupportedFileExt' AND AipServerId = 0) A,
  1409. (SELECT * FROM TB_AIP_CONFIG WHERE ConfigKey = 'ProtectedFileExt' AND AipServerId = 0) B`;
  1410. try {
  1411. const query = await pool;
  1412. const result = await query.request().query(sqlQuery);
  1413. if (result && result.recordset.length) {
  1414. resultObj.success = 'S';
  1415. resultObj.message = 'Success';
  1416. resultObj.data = result.recordset[0];
  1417. }
  1418. else {
  1419. resultObj.success = 'F';
  1420. resultObj.message = "Not Found Data";
  1421. }
  1422. }
  1423. catch(error) {
  1424. // console.log(error);
  1425. console.log(error);
  1426. resultObj.success = 'F';
  1427. resultObj.message = JSON.stringify(error);
  1428. }
  1429. return resultObj;
  1430. }
  1431. async function setLabelFile(session, file, supported_file_ext) {
  1432. const resultObj = {
  1433. success : 'F',
  1434. message : null,
  1435. fileData : null,
  1436. }
  1437. const originName = file.originalname;
  1438. // 파일 확장자
  1439. if (originName && originName.lastIndexOf('.') >= 0) {
  1440. const ext = originName.substring(originName.lastIndexOf('.'), originName.length);
  1441. if (supported_file_ext) {
  1442. let supportedArr = supported_file_ext.split(';');
  1443. if (!supportedArr[supportedArr.length - 1]) {
  1444. supportedArr.splice(supportedArr.length - 1);
  1445. }
  1446. if (!supportedArr.includes(ext)) {
  1447. resultObj.status = 500;
  1448. resultObj.error = '파일명 : ' + originName
  1449. +'<br>해당 파일은 업로드 불가 파일입니다. 다시 시도해주세요.<br>가능 확장자 :'
  1450. + JSON.stringify(supportedArr);
  1451. return resultObj;
  1452. }
  1453. const fileData = Buffer.from(file.buffer).toString('base64');
  1454. const param = {
  1455. apiKey: gateWayKey,
  1456. email: session.account.idTokenClaims.email,
  1457. dispFileName: originName,
  1458. aipGuid: "878173ae-cc36-4881-af57-604af868314c",
  1459. comment: "",
  1460. fileData: fileData
  1461. }
  1462. try {
  1463. const result = await axios.post(apiUrl + '/api/v1/stream/set-label', param);
  1464. if (result) {
  1465. if (result.data.statusCode === 200 && !result.data.result.errorCode) {
  1466. resultObj.fileData = Buffer.from(result.data.result.fileData, "base64");
  1467. }
  1468. else {
  1469. console.log(result.data);
  1470. resultObj.success = 'F';
  1471. resultObj.message = '파일명 : ' + originName + '<br>에러 : ' + result.data.result.errorMessage;
  1472. }
  1473. }
  1474. }
  1475. catch(error) {
  1476. console.log(error);
  1477. resultObj.success = 'F';
  1478. resultObj.message = '레이블 설정 중 오류가 발생하였습니다.<br>' + JSON.stringify(error.message);
  1479. }
  1480. }
  1481. }
  1482. return resultObj;
  1483. }
  1484. async function deleteLabelFile(session, name, file) {
  1485. const resultObj = {
  1486. error : false,
  1487. errorMessage : null,
  1488. fileData : null,
  1489. }
  1490. try {
  1491. const param = {
  1492. apiKey: gateWayKey,
  1493. email : session.account.idTokenClaims.email,
  1494. dispFileName: name,
  1495. comment: "",
  1496. fileData: file
  1497. }
  1498. const result = await axios.post(apiUrl + '/api/v1/stream/delete-label', param);
  1499. if (result && result.data.statusCode === 200 && !result.data.result.errorCode) {
  1500. resultObj.fileData = result.data.result.fileData;
  1501. }
  1502. else {
  1503. resultObj.error = true;
  1504. resultObj.errorMessage = '파일명 : ' + name + '<br>에러 : ' + result.data.result.errorMessage;
  1505. console.log(result.data.result);
  1506. }
  1507. }
  1508. catch(error) {
  1509. console.log(error);
  1510. resultObj.error = true;
  1511. resultObj.errorMessage = '레이블 해제 중 오류가 발생하였습니다.<br>' + JSON.stringify(error.message);
  1512. }
  1513. return resultObj;
  1514. }
  1515. function getOptions(token) {
  1516. const options = {
  1517. headers: {
  1518. Authorization: `Bearer ${token}`,
  1519. },
  1520. };
  1521. return options;
  1522. }
  1523. serverApp.use((err, req, res, next)=>{
  1524. console.log(err.message);
  1525. // console.log(err);
  1526. console.log(res.statusCode);
  1527. if (err) {
  1528. res.status(400);
  1529. res.json({message: err.message});
  1530. } else {
  1531. res.status(500);
  1532. res.json({message: err.message});
  1533. }
  1534. })
  1535. server.listen(SERVER_PORT, function () {
  1536. console.log(`\n${serverApp.name} listening to ${SERVER_PORT}`);
  1537. });