app.js 49 KB

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