const cookieParser = require('cookie-parser'); const cors = require("cors"); const fs = require("fs"); const path = require("path"); const express = require("express"); const axios = require("axios"); // const SERVER_PORT = process.env.port || process.env.PORT || 53000; const SERVER_PORT = process.env.port || process.env.PORT || 53000; // const authProvider = require('./auth/AuthProvider'); const {getFetch, updateFetch} = require('./fetch'); const bodyParser = require('body-parser'); const https = require('https'); const JSZIP = require('jszip'); require('dotenv').config({ path: './env/.env.local' }); const session = require('express-session'); const multer = require('multer'); const XLSX = require('xlsx'); const pptxgen = require('pptxgenjs'); const msal = require('@azure/msal-node'); const {pool, sql} = require('./config/sql.js'); const gateWayKey = process.env.GATE_WAY_KEY; const msalConfig = { auth: { clientId: process.env.TEAMS_APP_ID, authority: "https://login.microsoftonline.com/"+process.env.TEAMS_APP_TENANT_ID, clientSecret: process.env.TEAMS_APP_SECRET, knownAuthorities: [], }, cache: { // your implementation of caching }, system: { loggerOptions: { /** logging related options */ } } } const cca = new msal.ConfidentialClientApplication(msalConfig); const {Document, Packer, Paragraph, TextRun} = require('docx'); const messages = require('dote/src/messages.js'); let WebSocketServer = require('websocket').server; // const redirectUri = 'https://localhost:53000/redirect'; const redirectUri = 'https://localhost:53000/redirect'; const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/') }, filename: function (req, file, cb) { cb(null, file.originalname) // 원래 파일이름으로 저장 } }) const upload = multer(storage); const serverApp = express(); const endPoint = process.env.GRAPH_API_ENDPOINT + 'v1.0'; serverApp.use(session({ secret: process.env.EXPRESS_SESSION_SECRET, resave: false, saveUninitialized: true, cookie: { httpOnly: true, secure: true, // set this to true on production sameSite: 'none', maxAge: 60 * 60 * 24 * 1000 } })); serverApp.set(express.json()); serverApp.use(cookieParser()); serverApp.use(express.urlencoded({ extended: false })); serverApp.use("/static", express.static(path.join(__dirname, 'static'))); const options = { key: process.env.SSL_KEY_FILE ? fs.readFileSync(process.env.SSL_KEY_FILE) : undefined, cert: process.env.SSL_CRT_FILE ? fs.readFileSync(process.env.SSL_CRT_FILE) : undefined, }; const server = https.createServer(options, serverApp); let wsServer = new WebSocketServer({ httpServer: server, ssl : true, key : process.env.SSL_KEY_FILE ? fs.readFileSync(process.env.SSL_KEY_FILE) : undefined, cert: process.env.SSL_CRT_FILE ? fs.readFileSync(process.env.SSL_CRT_FILE) : undefined, }); wsServer.on('request', function(req) { var connection = req.accept(); connection.on('message', function(message) { if (message && message.type === 'utf8') { const { value } = JSON.parse(message.utf8Data); if (value) { try { getPercentageComplete(value, connection); } catch (error) { // console.log(error); console.log(error.message); console.log(error.name); console.log(error.errors); connection.sendUTF(error); // return res.json(error); } } } }) }); async function getPercentageComplete(url, connection) { const result = await axios.get(url); if (result && result.data && result.data.percentageComplete >= 0) { const percent = result.data.percentageComplete; // console.log(result.data); connection.sendUTF(Number(percent.toFixed(2))); if (result.data.percentageComplete !== 100) { setTimeout(()=>getPercentageComplete(url, connection), 1000); } } } const corsOption = { origin: "*", } serverApp.use(cors(corsOption)); serverApp.use(bodyParser.json()); serverApp.get("/tab", // isAuthenticated, async function (req, res, next) { res.sendFile(path.join(__dirname, "/views/hello.html"), // { idTokenClaims: req.session.account.idTokenClaims } ); } ); serverApp.post("/getProfileOnBehalfOf", async (req, res, next) => { result = await cca.acquireTokenOnBehalfOf({ oboAssertion: req.body.token, scopes: [".default"] }); req.session.tokenCache = result.tokenCache; req.session.accessToken = result.accessToken; req.session.idToken = result.idToken; req.session.account = result.account; req.session.auth = result; return res.send(result); }) // function isAuthenticated(req, res, next) { // if (!req.session.isAuthenticated) { // return res.redirect('/auth/signin'); // redirect to sign-in route // } // next(); // }; // function isAccessToken(req, res, next) { // if (!req.session.accessToken) { // return authProvider.acquireToken({ // scopes: ['.default'], // redirectUri: redirectUri, // successRedirect: '/api-redirect' // })(req, res, next); // } // next(); // } // serverApp.get("/auth/signin", authProvider.login({ // scopes: ['.default'], // redirectUri: redirectUri, // successRedirect: '/tab' // })) // serverApp.post("/redirect", authProvider.handleRedirect()); serverApp.post("/redirect", (req, res, next)=>{ console.log(req); }); serverApp.get("/redirect", (req, res, next)=>{ console.log(req); }); serverApp.post("/api-get", // isAuthenticated, // isAccessToken, async (req, res, next) => { const uri = req.body.api_uri || req.session.apiUri; let param = {}; if (req.session.param) { param = req.session.param; } try { const graphResponse = await getFetch(endPoint + uri, req.session.accessToken, param); res.json(graphResponse); } catch (error) { next(error); } }); serverApp.get("/api-redirect", // isAuthenticated, async function (req, res, next) { const uri = req.session.apiUri; let param = {}; if (req.session.param) { param = req.session.param; } try { const graphResponse = await getFetch(endPoint + uri, req.session.accessToken, param); res.json(graphResponse); } catch (error) { next(error); } }) serverApp.get("/post-redirect", // isAuthenticated, async function (req, res, next) { const uri = req.session.apiUri; let param = {}; if (req.session.param) { param = req.session.param; } try { const graphResponse = await updateFetch(endPoint + uri, req.session.accessToken, param); res.json(graphResponse); } catch (error) { next(error); } } ) // serverApp.post("/api-update", authProvider.acquireToken({ // scopes: [], // redirectUri: redirectUri, // successRedirect: '/post-redirect' // })); // serverApp.post("/api-post", authProvider.acquireToken({ // scopes: ['.default'], // redirectUri: redirectUri, // successRedirect: '/post-redirect' // })); // serverApp.post("/getGroupList", authProvider.acquireToken({ // scopes: ['.default'], // redirectUri: redirectUri, // successRedirect: '/group-redirect' // })); serverApp.post("/getGroupList", async function (req, res, next) { try { const oneDrive = await getFetch(endPoint + "/me/drive/root", req.session.accessToken); const sharePointIds = await getFetch(endPoint + "/me/drive/SharePointIds", req.session.accessToken); // const publicTeam = await getFetch(endPoint + "/groups?$filter=groupTypes/any(c:c+eq+'Unified')", req.session.accessToken); const graphResponse = await getFetch(endPoint + "/me/joinedTeams", req.session.accessToken); const sites = await getFetch(endPoint + "/sites/root", req.session.accessToken); const sitesSharePoint = await getFetch(endPoint + "/sites/root/SharePointIds", req.session.accessToken); // const public = publicTeam.value; const teams = graphResponse.value; oneDrive.sharePoint = sharePointIds; sites.sharePoint = sitesSharePoint; const resultObj = { oneDrive : { teams: oneDrive, }, joinedTeams : { teams : teams, // teams : public, items : {}, }, sites : { teams : sites, }, } if (teams && teams.length) { // if (public && public.length) { // const options = { // responseType: 'arraybuffer', // headers: { // Authorization: `Bearer ${req.session.accessToken}`, // ConsistencyLevel: 'eventual', // withCredentials:true, // }, // }; for (let team of teams) { // for (let team of public) { const item = await getFetch(endPoint + "/groups/"+team.id+"/drive/items/root/children", req.session.accessToken); const sharePoint = await getFetch(endPoint + "/groups/"+team.id+"/drive/SharePointIds", req.session.accessToken); // const image = await axios.get(endPoint + "/groups/" + team.id + "/photo/$value", options); // if (image && image.data) { // team.image = image.data; // } if (sharePoint) { team.sharePoint = sharePoint; } if (item && item.value) { resultObj.joinedTeams.items[team.id] = item.value; } } } res.json(resultObj); } catch (error) { next(error); } }); function isAccessTokens(req, res, next) { if (!req.session.accessToken) { return authProvider.acquireToken({ scopes: ['.default'], redirectUri: redirectUri, successRedirect: req.url })(req, res, next); } next(); } serverApp.post('/api/makeFolder', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }, }; const {siteId, path, name} = req.body; const resultObj = {message:"", success: 'F'}; const param ={ name: name, folder: { }, '@microsoft.graph.conflictBehavior': 'rename' } try{ const sitesInfo = await axios.get(endPoint + "/sites/"+ siteId + path, options); if (sitesInfo.data && sitesInfo.data.id) { const itemId = sitesInfo.data.id; const result = await axios.post(endPoint + "/sites/"+ siteId +"/drive/items/" + itemId +"/children",param, options); if (result.data) { resultObj.message = "폴더가 생성되었습니다.
폴더명 : "+ name; resultObj.success = 'S'; } else { resultObj.message = "폴더가 생성되지 않았습니다."; } } else { resultObj.message = "생성할 폴더 경로를 찾을 수 없습니다."; } } catch(error) { resultObj.message = "폴더 생성 중 오류가 발생하였습니다.
" + getErrorMessage(error); } res.json(resultObj); }); function getErrorMessage(error) { let errorText = ""; if (error.response && error.response.status && error.response.statusText && error.response.data && error.response.data.error) { // console.log(error.response); console.log('=============================== Axios Error ===============================') console.log(error.response); console.log(error.response.data.error); errorText = `status : ${error.response.status} - ${error.response.statusText}
message : ${error.response.data.error.message}`; } else { console.log('================================ Error =====================================') console.log(error); errorText = error; } return errorText; } serverApp.post('/api/makeWord', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }, }; const {siteId, path, name} = req.body; const doc = new Document({ sections : [ { properties: {}, children : [ new Paragraph({ children: [ ] }) ] } ] }); Packer.toBuffer(doc).then(async (buffer)=>{ const resultObj = {message:"", success: 'F'};; try{ const sitesInfo = await axios.get(endPoint + "/sites/"+ siteId + path, options); if (sitesInfo.data && sitesInfo.data.id) { const itemId = sitesInfo.data.id; const result = await axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+itemId+':/'+name+':/content', buffer, options); if (result.data) { resultObj.message = "요청하신 Word 파일이 생성되었습니다.
파일명 : "+ name; resultObj.success = 'S'; } else { resultObj.message = "요청하신 Word 파일이 생성되지 않았습니다."; } } else { resultObj.message = "생성할 폴더 경로를 찾을 수 없습니다."; } } catch(error) { resultObj.message = "요청하신 Word 파일 생성 중 오류가 발생하였습니다.
" + getErrorMessage(error); } res.send(resultObj); }); }) serverApp.post('/api/makeExcel', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ const fileOptions = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }} const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }} const {siteId, path, name} = req.body; const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, XLSX.utils.json_to_sheet([]), 'Sheet1'); var wbout = XLSX.write(wb, {bookType:'xlsx', type: 'buffer'}); const resultObj = {message:'', success: 'F'}; try{ const parentData = await axios.get(endPoint + "/sites/"+ siteId +path, options); if (parentData.data) { const result = await axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+parentData.data.id+':/'+name+':/content', wbout, options); if (result.data) { resultObj.message ='요청하신 Excel 파일이 생성 되었습니다.'; resultObj.success = 'S'; } else{ resultObj.message = '요청하신 Excel 파일이 생성 되지 않았습니다.'; } } } catch(error) { resultObj.message = "요청하신 Word 파일 생성 중 오류가 발생하였습니다.
" + getErrorMessage(error); } res.json(resultObj); }) serverApp.post('/api/makePptx', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }} const {siteId, path, name} = req.body; const pres = new pptxgen(); pres.addSlide("TITLE_SLIDE"); const resultObj = {message:'', success: 'F'}; pres.stream().then(async (data)=>{ try{ const parentData = await axios.get(endPoint + "/sites/"+ siteId +path, options); if (parentData.data) { const result = await axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+parentData.data.id+':/'+name+':/content', data, options); if (result.data) { resultObj.message ='요청하신 PowerPoint 프레젠테이션 파일이 생성 되었습니다.'; resultObj.success = 'S'; } else{ resultObj.message = '요청하신 PowerPoint 프레젠테이션 파일이 생성 되지 않았습니다.'; } } } catch(error) { resultObj.message = "요청하신 PowerPoint 프레젠테이션 파일 생성 중 오류가 발생하였습니다.
" + getErrorMessage(error); } res.json(resultObj); }) }) serverApp.post('/api/check-name', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }, }; const {siteId, path, name} = req.body; try{ const sitesInfo = await axios.get(endPoint + "/sites/"+ siteId + path, options); if (sitesInfo.data) { const itemId = sitesInfo.data.id; const result = await axios.get(endPoint + "/sites/"+ siteId +"/drive/items/" + itemId +"/children", options); if (result && result.data && result.data.value) { let idx = result.data.value.findIndex(obj=>obj.name === name); console.log(name); console.log(idx); console.log((idx > -1)); console.log(result.data.value); res.json({hasName: (idx > -1)}); } } } catch(error) { if (error.response) { console.log("error.response", error.response); const statusCode = err.response.status; // 400 const statusText = err.response.statusText; // Bad Request const message = err.response.data.message[0]; // id should not be empty console.log(`${statusCode} - ${statusText} - ${message}`); res.json(error.response); } else { console.log(error); res.json(error); } } }) serverApp.post('/api/upload', upload.array('file'), // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ const startTime = new Date(); const files = req.files; let {siteId, path, folder} = req.body; if (siteId && path) { const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }, }; if (folder) { if (!Array.isArray(folder)) { folder = [folder]; } for (let item of folder) { const fileInfo = JSON.parse(item); const param = { name: fileInfo.name, folder: {}, '@microsoft.graph.conflictBehavior': 'rename' }; let folderPath = ''; if (fileInfo.path) { folderPath = fileInfo.path; if (!path.includes(':')) { folderPath = ":" + folderPath; } } let uri = endPoint + "/sites/"+ siteId + path + folderPath; try { const result = await new Promise (async (resolve, reject)=>{ try { const sitesInfo = await axios.get(uri, options); resolve(sitesInfo.data); } catch(error) { if (error.response) { reject(error.response); } else { reject(error); } } }).then(async (result)=>{ return await new Promise(async (resolve, reject)=>{ try { const uploadFolder = await axios.post(endPoint + "/sites/"+ siteId +"/drive/items/" + result.id +"/children", param, options); resolve(uploadFolder.data); } catch(error){ if (error.response) { reject(error.response); } else { reject(error); } } }) }).catch((error)=>{ console.log(error); }) } catch(error) { return res.json({success:'F', message: '요청하신 파일 업로드 중 오류가 발생하였습니다.
' + getErrorMessage(error)}); } } const makeFolderTime = new Date(); let betweenTime = makeFolderTime - startTime; if (betweenTime > 60000) { betweenTime = (betweenTime/1000/60) + ' 분'; } else { betweenTime = (betweenTime/1000) + ' 초'; } console.log('폴더 시작 시간 :', startTime.toLocaleString(), ', 폴더 종료 시간 :', makeFolderTime.toLocaleString(), ', 소요 시간 :', betweenTime); } const promiseArray = []; if (files && files.length > 0) { let beforeUri = ''; let beforeItemId = ''; for (let file of files) { const fileName = file.originalname; let filePath = req.body[ fileName + "_path"]; file.originalname = Buffer.from(file.originalname, 'ascii').toString('utf8'); let originName = file.originalname; if (originName.lastIndexOf('.') >= 0) { const possibleExt = await getPossibleExt(); const {supported_file_ext, protected_file_ext} = possibleExt; const ext = originName.substring(originName.lastIndexOf('.'), originName.length); if (supported_file_ext && protected_file_ext) { const supportedArr = supported_file_ext.split(';'); if (!supportedArr.includes(ext)) { return res.json({success:'F', message: '파일명 : '+originName+'
해당 파일은 업로드 불가 파일입니다. 다시 시도해주세요.'}); } const fileData = Buffer.from(file.buffer).toString('base64'); const param = { apiKey: process.env.GATE_WAY_KEY, email: req.session.account.idTokenClaims.email, dispFileName: originName, aipGuid: "878173ae-cc36-4881-af57-604af868314c", comment: "", fileData: fileData } try { // const result = await axios.post('https://115.91.94.42/api/v1/stream/set-label', param); const result = await axios.post('http://192.168.20.99:5050/api/v1/stream/set-label', param); if (result) { if (result.data.statusCode === 200) { let bufferValue = Buffer.from(result.data.result.fileData, "base64"); file = bufferValue; } } } catch(error) { console.log(error); } } } let formatPath = ''; if (filePath) { if (Array.isArray(filePath) && filePath.length > 0) { formatPath = filePath[0]; if (filePath.length > 1) { req.body[ fileName + "_path"] = filePath.splice(1); } } else if (filePath.trim()){ formatPath = filePath; } if (!path.includes(":")) { formatPath = ":" + formatPath; } } let itemId = ''; const uri = endPoint + "/sites/"+ siteId + path + formatPath; if (beforeUri === uri) { itemId = beforeItemId; } else { const sitesInfo = await axios.get(uri, options); itemId = sitesInfo.data.id; beforeUri = uri; beforeItemId = itemId; } const fileOptions = { headers: { Authorization: `Bearer ${req.session.accessToken}`, "Content-Type" : file.mimeType }} // await axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+itemId+':/'+file.originalname+':/content', file.buffer, fileOptions); promiseArray.push(axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+itemId+':/'+originName+':/content', file, fileOptions)); } } if (promiseArray.length > 0) { try { const result = await Promise.all(promiseArray); } catch(error){ return res.json({success:'F', message: '요청하신 파일 업로드 중 오류가 발생하였습니다.
' + getErrorMessage(error)}); } } const endTime = new Date(); let betweenTime = endTime - startTime; if (betweenTime > 60000) { betweenTime = (betweenTime/1000/60) + ' 분'; } else { betweenTime = (betweenTime/1000) + ' 초'; } console.log('시작 시간 :', startTime.toLocaleString(), ', 종료 시간 :', endTime.toLocaleString(), ', 소요 시간 :', betweenTime); res.json({success:'S', message: '요청하신 파일 업로드가 정상적으로 처리 되었습니다.'}); } }); serverApp.post('/api/download', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ let startTime = new Date(); if (req.body) { const {siteId, path, fileIds, zipName} = req.body; if (siteId && path && fileIds) { const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }, }; const arr = JSON.parse(fileIds); if (arr.length === 1) { const sitesInfo = await axios.get(endPoint + "/sites/"+ siteId + "/drive/items/" + arr[0], options); if (sitesInfo && sitesInfo.data) { const data = sitesInfo.data; if (data.folder) { const folderObj = await getFolderItems(endPoint + "/sites/"+ siteId + "/drive/items/", arr, options, req.session); const zip = new JSZIP(); if (folderObj) { createZipFile(folderObj, zip); const now = new Date(); const year = now.getFullYear().toString(); let month = now.getMonth() + 1; if (month < 10) month = "0" + month; let date = now.getDate(); if (date < 10) date = "0" + date; zip.generateAsync({ type: 'nodebuffer', mimeType: 'application/epub+zip', compression: 'DEFLATE', compressionOptions: { level: 9 }, }).then((resZip)=>{ const endTime = new Date(); let betweenTime = endTime - startTime; if (betweenTime > 60000) { betweenTime = (betweenTime/1000/60) + ' 분'; } else { betweenTime = (betweenTime/1000) + ' 초'; } console.log('시작 시간 :', startTime.toLocaleString(), ', 종료 시간 :', endTime.toLocaleString(), ', 소요 시간 :', betweenTime); return res.json({success: 'S', data: resZip, name: data.name + '_' + year + '-' + month + '-' + date + '.zip'}); }) .catch((error)=>{ console.log(error); return res.json({success: 'F', message:'파일 다운로드 중 오류가 발생하였습니다.', error: error}); }); } } else { const dataUrl = data['@microsoft.graph.downloadUrl']; const response = await axios.get(dataUrl, {responseType: 'arraybuffer', headers: { withCredentials:true, },}); if (response.data) { const file = response.data; let decodeFile = null; try { const param = { apiKey: process.env.GATE_WAY_KEY, email : req.session.account.idTokenClaims.email, dispFileName: data.name, comment: "", fileData: Buffer.from(file).toString("base64") } const result = await axios.post('http://192.168.20.99:5050/api/v1/stream/delete-label', param); if (result && result.data.statusCode === 200) { var binaryString = atob(result.data.result.fileData); var bytes = new Uint8Array(binaryString.length); for (var i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } decodeFile = bytes.buffer; } else { return res.json({message: '레이블 해제 중 오류가 발생하였습니다.
' + result.data.message, success: 'F'}); } } catch(error) { return res.json({message: '레이블 해제 중 오류가 발생하였습니다.
' + JSON.stringify(error.message), success: 'F'}); } const endTime = new Date(); let betweenTime = endTime - startTime; if (betweenTime > 60000) { betweenTime = (betweenTime/1000/60) + ' 분'; } else { betweenTime = (betweenTime/1000) + ' 초'; } console.log('시작 시간 :', startTime.toLocaleString(), ', 종료 시간 :', endTime.toLocaleString(), ', 소요 시간 :', betweenTime); return res.json({success: 'S', data: decodeFile, type: data.file.mimeType, name: data.name}); } else { return res.json({message:'파일 다운로드에 실패하였습니다.', success:'F'}) } } } } else { try { const url = endPoint + "/sites/"+ siteId + "/drive/items/"; const zip = new JSZIP(); const downObj = await getFolderItems(url, arr, options, req.session); if (downObj) { createZipFile(downObj, zip); const now = new Date(); const year = now.getFullYear().toString(); let month = now.getMonth() + 1; if (month < 10) month = "0" + month; let date = now.getDate(); if (date < 10) date = "0" + date; zip.generateAsync({ type: 'nodebuffer', mimeType: 'application/epub+zip', compression: 'DEFLATE', compressionOptions: { level: 9 }, }).then((resZip)=>{ const endTime = new Date(); let betweenTime = endTime - startTime; if (betweenTime > 60000) { betweenTime = (betweenTime/1000/60) + ' 분'; } else { betweenTime = (betweenTime/1000) + ' 초'; } console.log('시작 시간 :', startTime.toLocaleString(), ', 종료 시간 :', endTime.toLocaleString(), ', 소요 시간 :', betweenTime); return res.json({success: 'S', data: resZip, name: zipName + '_' + year + '-' + month + '-' + date + '.zip'}); }) .catch((error)=>{ console.log(error); return res.json({success: 'F', message:'파일 다운로드 중 오류가 발생하였습니다.', error: error}); }); } } catch(err) { // console.log(sitesInfo.data); console.log(err); } // } } } else { return res.json({message:'다운로드 파일 정보를 확인 할 수 없습니다.', success:'F'}) } } } ); serverApp.post('/api/folderMove', async (req, res, next)=>{ if (req.body) { const {id, name, siteId, driveId, text, moveSiteId, movePath} = req.body; const resultObj = {message:'폴더 이동에 실패 하였습니다.', success: 'F'}; if (name && isNaN(name)) { const nameArray = JSON.parse(name); const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }, }; if (nameArray && nameArray.length > 0) { for (let moveItem of nameArray) { if (moveItem) { try { const copyFolderPath = `${endPoint}/sites/${siteId}/drive/items/${moveItem.id}`; const result = await axios.get(copyFolderPath, options); if (result && result.data) { const data = result.data; const moveUri = `${endPoint}/sites/${moveSiteId}/${movePath}`; const moveFolderResult = await findSubFolder(data, moveUri, moveSiteId, options); console.log('moveFolderResult : ',moveFolderResult); if (!moveFolderResult) { resultObj.message ='폴더 이동 중 오류가 발생하였습니다.'; } else { await axios.delete(endPoint + "/sites/"+ siteId + "/drive/items/" + moveItem.id, options); resultObj.message ='폴더 이동 되었습니다.'; resultObj.success = 'S'; } } } catch (error) { console.log(error.message); console.log(error.name); console.log(error.errors); resultObj.message = error.errors; // resultObj.failItems.push(moveItem); } } } } } return res.json(resultObj); } }) async function findSubFolder(data, movePath, moveSiteId, options) { let resultType = true; try { const moveItem = await axios.get(movePath, options); if (moveItem.data && moveItem.data.id) { const param = { "name": data.name, "folder": {}, "@microsoft.graph.conflictBehavior": "rename" } const makeFolderData = await axios.post(`${endPoint}/sites/${moveSiteId}/drive/items/${moveItem.data.id}/children`, param, options); if (makeFolderData && makeFolderData.data) { const makeFolderPath = `${endPoint}/sites/${moveSiteId}/${makeFolderData.data.parentReference.path}/${data.name}`; if (data.folder.childCount) { const siteId = data.parentReference.siteId; const childrenData = await axios.get(`${endPoint}/sites/${siteId}/drive/items/${data.id}/children`, options); if (childrenData && childrenData.data && childrenData.data.value) { const childrenValues = childrenData.data.value; if (childrenValues.length > 0) { for (let ii = 0; ii < childrenValues.length; ii++) { const children = childrenValues[ii]; if (children && children.folder) { const result = await findSubFolder(children, makeFolderPath, moveSiteId, options); if (!result) { resultType = result; } } else { const dataUrl = children['@microsoft.graph.downloadUrl']; const response = await axios.get(dataUrl, {responseType: 'arraybuffer', headers: { withCredentials:true, },}); if (response.data) { const file = response.data; const uploadResult = await axios.put(`${endPoint}/sites/${moveSiteId}/drive/items/${makeFolderData.data.id}:/${children.name}:/content`, file.buffer, options); if (!uploadResult) { resultType = false; } } else { resultType = false; } } } } else { resultType = false; } } else { resultType = false; } } else { resultType = false; } } else { resultType = false; } } else { resultType = false; } return resultType; } catch(error) { console.log(error); return false; } } function createZipFile(obj, zip) { if (obj.files.length > 0) { for (let file of obj.files) { zip.file(file.name, file.data); } } if (obj.folder.length > 0) { for (let folder of obj.folder) { zip.folder(folder.name); if (folder.subFolder) { createZipFile(folder.subFolder, zip.folder(folder.name)); } } } } async function getFolderItems(url, array, options, session) { const files = []; // let subFolder = []; let folder = []; for (let fileId of array) { const sitesInfo = await axios.get(url + fileId, options); const data = sitesInfo.data; if (data) { if (data.folder) { const folderObj = {name : data.name, subFolder : []}; if (data.folder.childCount) { const itemsData = await axios.get(url + fileId + '/children', options); if (itemsData && itemsData.data && itemsData.data.value.length > 0) { const idArr = []; for (let children of itemsData.data.value) { idArr.push(children.id); } let result = await getFolderItems(url, idArr, options, session); // subFolder.push(result); folderObj.subFolder = result; } } folder.push(folderObj); } else { const dataUrl = data['@microsoft.graph.downloadUrl']; const response = await axios.get(dataUrl, {responseType: 'arraybuffer', headers: { withCredentials:true, },}); //암호화 해제 let decodeFile; try { const param = { apiKey: process.env.GATE_WAY_KEY, email : session.account.idTokenClaims.email, dispFileName: data.name, comment: "", fileData: Buffer.from(response.data).toString("base64") } const result = await axios.post('http://192.168.20.99:5050/api/v1/stream/delete-label', param); if (result && result.data.statusCode === 200) { var binaryString = atob(result.data.result.fileData); var bytes = new Uint8Array(binaryString.length); for (var i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } decodeFile = bytes.buffer; } else { return res.json({message: '레이블 해제 중 오류가 발생하였습니다.
' + result.data.message, success: 'F'}); } } catch(error) { return res.json({message: '레이블 해제 중 오류가 발생하였습니다.
' + JSON.stringify(error.message), success: 'F'}); } files.push({name : data.name, data : decodeFile, type: data.file.mimeType}); // files.push({name : data.name, data : response.data, type: data.file.mimeType}); } } } const resultObj = { folder : folder, files : files, }; return resultObj; } serverApp.post('/api/getPossibleExtList', async (req, res, next)=>{ if (req.body) { try { const result = await getPossibleExt(); return res.json(result); } catch(error) { console.log(error); res.status(500); res.send(error); } } }) serverApp.post('/api/delete', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ if (req.body) { const {siteId, itemIds} = req.body; const resultObj = {success: '', message:''}; if (siteId && itemIds) { const itemIdArr = JSON.parse(itemIds); if (itemIdArr.length > 0) { const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }, }; for (let itemId of itemIdArr) { try{ await axios.delete(endPoint + "/sites/"+ siteId + "/drive/items/" + itemId, options); } catch(error) { resultObj.success = 'F'; let message = '선택하신 파일 정보 삭제중 오류가 발생하였습니다.'; if (error && error.response && error.response.data && error.response.data.error && error.response.data.error.message) { console.log(error.response.data.error.message); message += '
' + error.response.data.error.message; } resultObj.message = message; return res.json(resultObj); } } resultObj.success = 'S'; resultObj.message = '파일 정보가 삭제되었습니다.'; res.json(resultObj); } } else { resultObj.success = 'F'; resultObj.message = '파라미터 정보를 확인해주세요.'; res.json(resultObj); } } }) serverApp.post('/api/update-name', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ if (req.body) { const {siteId, itemId, name} = req.body; const resultObj = {success: '', message:''}; if (siteId && itemId && name) { const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, }, }; try{ await axios.patch(endPoint + "/sites/"+ siteId + "/drive/items/" + itemId, {name : name}, options); } catch(error) { console.log(error.response.data.error); resultObj.success = 'F'; resultObj.message = '선택하신 파일의 이름 변경 중 오류가 발생하였습니다.
' + error.response.data.error.message; return res.json(resultObj); } resultObj.success = 'S'; resultObj.message = '선택하신 파일의 이름이 변경되었습니다.'; return res.json(resultObj); } } else { resultObj.success = 'F'; resultObj.message = '파라미터 정보를 확인해주세요.'; return res.json(resultObj); } }); serverApp.post('/api/move-item', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ if (req.body) { const {id, name, siteId, text} = req.body; const resultObj = {message:'', successItems : [], failItems : [], locations: []}; if (name && isNaN(name)) { const nameArray = JSON.parse(name); const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, ContentType: "application/json", }, }; if (nameArray && nameArray.length > 0) { for (let moveItem of nameArray) { if (moveItem) { const param = { parentReference: { id: id, }, name: moveItem.name }; try { const result = await axios.patch(`${endPoint}/sites/${siteId}/drive/items/${moveItem.id}`, param, options); if (result) { resultObj.successItems.push(moveItem); // resultObj.locations.push(result.headers.location); } } catch (error) { // console.log(error); console.log(error.message); console.log(error.name); console.log(error.errors); resultObj.failItems.push(moveItem); } } } resultObj.message = `요청 하신 ${nameArray.length} 개 파일 중 ${ resultObj.successItems.length} 개 파일이 ${text} 되었습니다.`; } } return res.json(resultObj); } }); serverApp.post('/api/copy-item', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ if (req.body) { const {id, name, siteId, driveId, text} = req.body; const resultObj = {message:'', successItems : [], failItems : [], locations: []}; if (name && isNaN(name)) { const nameArray = JSON.parse(name); const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, ContentType: "application/json", }, }; if (nameArray && nameArray.length > 0) { for (let moveItem of nameArray) { if (moveItem) { const param = { parentReference: { id: id, driveId : driveId, }, name: moveItem.name }; try { const result = await axios.post(`${endPoint}/sites/${siteId}/drive/items/${moveItem.id}/copy`, param, options); if (result) { resultObj.successItems.push(moveItem); resultObj.locations.push(result.headers.location); } } catch (error) { // console.log(error); console.log(error.message); console.log(error.name); console.log(error.errors); resultObj.failItems.push(moveItem); } } } resultObj.message = `요청 하신 ${nameArray.length} 개 파일 중 ${ resultObj.successItems.length} 개 파일이 ${text} 되었습니다.`; } } return res.json(resultObj); } }); serverApp.post('/api/loading', async (req, res, next)=>{ if (req.body) { const {url} = req.body; if (url) { try { const result = await axios.get(`${url}`); if (result && result.data) { console.log(result.data); return res.json(result.data); } } catch (error) { // console.log(error); console.log(error.message); console.log(error.name); console.log(error.errors); return res.json(error); } } } }); serverApp.post('/api/add-tab', // isAuthenticated, // isAccessTokens, async (req, res, next)=>{ if (req.body) { const {name, siteId, path, teamId, teamName, bindId} = req.body; const resultObj = {message:'', success: 'F'}; if (name && siteId && path && teamId && teamName) { const options = { headers: { Authorization: `Bearer ${req.session.accessToken}`, ContentType: "application/json", }, }; try { const teamInfo = await axios.get(`${endPoint}/teams/${teamId}/channels`, options); const sharePoint = await axios.get(`${endPoint}/sites/${siteId}/drive`, options); if (teamInfo.data && teamInfo.data.value && sharePoint.data) { const sharePointUrl = sharePoint.data.webUrl; if (path.includes('/drive/root:/') && sharePointUrl) { let channelName = path.replace('/drive/root:/', ''); const contentUrl = sharePointUrl + '/' + channelName; channelName = channelName.substring(0, channelName.indexOf('/')); const idx = teamInfo.data.value.findIndex(obj => obj.displayName === channelName); resultObj.message = `채널명 : ${channelName}
파일명 : ${name}
요청하신 채널에 탭으로 설정 되지않았습니다.`; if (idx >= 0 && contentUrl) { const channelId = teamInfo.data.value[idx].id; if (channelId) { const param = { displayName: name, "teamsApp@odata.bind" : `https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/${bindId}`, configuration: { entityId: null, contentUrl: contentUrl, websiteUrl: "", removeUrl: null } } //sites/root/lists const channelInfo = await axios.post(`${endPoint}/teams/${teamId}/channels/${channelId}/tabs`, param, options); if (channelInfo.data) { resultObj.success = 'S'; resultObj.message = '채널명 : ' + channelName + '
파일명 : '+name+'
요청하신 채널에 탭으로 설정 되었습니다.'; } } } } } } catch (error) { resultObj.message = `채널명 : ${channelName}
파일명 : ${name}
요청하신 채널에 탭으로 설정 중 오류가 발생하였습니다.
` + getErrorMessage(error); } } return res.json(resultObj); } }); // // 데이터베이스 연결 // pool.connect((err) => { // // 연결이 안될 경우 에러 내용 콘솔에 출력 // if (err) { // console.error('Error connecting to database:', err); // return; // } // // 연결에 성공할 경우 연결 성공 메시지 콘솔에 출력 // console.log('Connected to database'); // }); async function getPossibleExt() { const sqlQuery = `SELECT A.ConfigValue AS supported_file_ext, B.ConfigValue AS protected_file_ext FROM (SELECT * FROM TB_AIP_CONFIG WHERE ConfigKey = 'SupportedFileExt') A, (SELECT * FROM TB_AIP_CONFIG WHERE ConfigKey = 'ProtectedFileExt') B`; try { const query = await pool; const result = await query.request().query(sqlQuery); if (result) { return result.recordset[0]; } } catch(error) { console.log(error); } } server.listen(SERVER_PORT, function () { console.log(`\n${serverApp.name} listening to ${SERVER_PORT}`); });