123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657 |
- 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 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.test' });
- const session = require('express-session');
- const multer = require('multer');
- const { throws } = require('assert');
- let _ZIP;
- 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';
- Buffer.prototype.toArrayInteger = function(){
- if (this.length > 0) {
- const data = new Array(this.length);
- for (let i = 0; i < this.length; i=i+1)
- data[i] = this[i];
- return data;
- }
- return [];
- }
- 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')));
- serverApp.use("/node_modules",express.static(path.join(__dirname, 'node_modules')));
- 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);
- const corsOption = {
- origin: "*",
- }
- serverApp.use(cors(corsOption));
- serverApp.use(bodyParser.json());
- server.listen(SERVER_PORT, function () {
- console.log(`\n${serverApp.name} listening to ${SERVER_PORT}`);
- });
- serverApp.get("/tab",
- isAuthenticated,
- async function (req, res, next) {
- res.sendFile(path.join(__dirname, "/views/hello.html"),
- { idTokenClaims: req.session.account.idTokenClaims }
- );
- }
- );
- 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: 'https://localhost:53000/redirect',
- successRedirect: '/api-redirect'
- })(req, res, next);
- }
- next();
- }
- serverApp.get("/auth/signin", authProvider.login({
- scopes: ['.default'],
- redirectUri: 'https://localhost:53000/redirect',
- successRedirect: '/tab'
- }))
- serverApp.post("/redirect", authProvider.handleRedirect());
- 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: 'https://localhost:53000/redirect',
- successRedirect: '/post-redirect'
- }));
- serverApp.post("/api-post", authProvider.acquireToken({
- scopes: ['.default'],
- redirectUri: 'https://localhost:53000/redirect',
- successRedirect: '/post-redirect'
- }));
- serverApp.post("/getGroupList", authProvider.acquireToken({
- scopes: ['.default'],
- redirectUri: 'https://localhost:53000/redirect',
- successRedirect: '/group-redirect'
- }));
- serverApp.get("/group-redirect",
- isAuthenticated,
- async function (req, res, next) {
- // return;
- try {
- const oneDrive = await getFetch(endPoint + "/me/drive/root", req.session.accessToken);
- const sharePointIds = await getFetch(endPoint + "/me/drive/SharePointIds", 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 teams = graphResponse.value;
- oneDrive.sharePoint = sharePointIds;
- sites.sharePoint = sitesSharePoint;
- const resultObj = {
- oneDrive : {
- teams: oneDrive,
- },
- joinedTeams : {
- teams : teams,
- items : {},
- },
- sites : {
- teams : sites,
- },
- }
- if (teams && teams.length) {
- const options = {
- responseType: 'arraybuffer',
- headers: {
- Authorization: `Bearer ${req.session.accessToken}`,
- ConsistencyLevel: 'eventual',
- },
- };
- for (let team of teams) {
- 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);
- if (sharePoint) {
- team.sharePoint = sharePoint;
- }
- if (item && item.value) {
- resultObj.joinedTeams.items[team.id] = item.value;
- }
- }
- }
- res.json(resultObj);
- } catch (error) {
- next(error);
- }
- }
- )
- serverApp.post('/makeFolder',
- isAuthenticated,
- (req, res, next)=>{
- if (!req.session.accessToken) {
- return authProvider.acquireToken({
- scopes: ['.default'],
- redirectUri: 'https://localhost:53000/redirect',
- successRedirect: '/makeFolder'
- })(req, res, next);
- }
- next();
- },
- async (req, res, next)=>{
- const options = {
- headers: {
- Authorization: `Bearer ${req.session.accessToken}`,
- },
- };
- const {siteId, path, param} = 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.post(endPoint + "/sites/"+ siteId +"/drive/items/" + itemId +"/children", JSON.parse(param), options);
- res.json(result.data)
- }
- }
- catch(error) {
- console.log(error.response.data.error);
-
- // resultObj.success = 'F';
- // resultObj.message = '선택하신 파일 정보 삭제중 오류가 발생하였습니다.\n' + error.response.data.error.message;
- // return res.json(resultObj);
- }
- })
- serverApp.post('/uploadItems', upload.array('file'),
- isAuthenticated,
- (req, res, next)=>{
- if (!req.session.accessToken) {
- return authProvider.acquireToken({
- scopes: ['.default'],
- redirectUri: 'https://localhost:53000/redirect',
- successRedirect: '/uploadItems'
- })(req, res, next);
- }
- next();
- },
- async (req, res, next)=>{
- const startTime = new Date();
- const folderParam = {
- name: '',
- folder: { },
- '@microsoft.graph.conflictBehavior': 'rename'
- }
- 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];
- }
- let beforeUri = '';
- let beforeItemId = '';
- for (let item of folder) {
- const fileInfo = JSON.parse(item);
- const param = {...folderParam};
- param.name = fileInfo.name;
- let folderPath = '';
- if (fileInfo.path) {
- folderPath = ':' + fileInfo.path;
- }
- let uri = endPoint + "/sites/"+ siteId + path + folderPath;
- try {
-
- let itemId = '';
- if (beforeUri === uri) {
- itemId = beforeItemId;
- }
- else {
- const sitesInfo = await axios.get(uri, options);
- itemId = sitesInfo.data.id;
- beforeItemId = itemId;
- beforeUri = uri;
- }
- await axios.post(endPoint + "/sites/"+ siteId +"/drive/items/" + itemId +"/children", param, options);
-
- // await axios.post(endPoint + "/sites/"+ siteId +"/drive/items/" + itemId +"/children", param, options);
- }
- catch(error) {
- console.log(error);
- // next(error);
- return res.json({success:'F', message: '요청하신 파일 업로드 중 오류가 발생하였습니다.', error : error});
- }
- }
- }
- if (files && files.length > 0) {
- const promiseArray = [];
- let beforeUri = '';
- let beforeItemId = '';
- for (let file of files) {
- // const fileName = file.originalname.substring(0, file.originalname.lastIndexOf('.'));
- const fileName = file.originalname;
- let filePath = req.body[ fileName + "_path"];
- file.originalname = Buffer.from(file.originalname, 'ascii').toString('utf8');
- try {
- 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;
- }
- }
- 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 uploadUri = endPoint + "/sites/"+ siteId +"/drive/items/"+itemId+':/'+file.originalname+':/content';
- 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);
- }
- catch(error) {
- if (error) {
- if (error.response) {
- console.log(error.response.data);
- }
- else {
- console.log(error);
- }
- }
- return res.json({success:'F', message: '요청하신파일 업로드 중 오류가 발생하였습니다.', error : error});
- }
- }
- }
- const endTime = new Date();
- console.log('시작 시간 :', startTime, '종료 시간 :', endTime);
- res.json({success:'S', message: '요청하신 파일 업로드가 정상적으로 처리 되었습니다.'});
- }
- })
- serverApp.post('/api/download',
- isAuthenticated,
- (req, res, next)=>{
- if (!req.session.accessToken) {
- return authProvider.acquireToken({
- scopes: ['.default'],
- redirectUri: 'https://localhost:53000/redirect',
- successRedirect: '/api/download'
- })(req, res, next);
- }
- next();
- },
- async (req, res, next)=>{
- 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);
- 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)=>{
- 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;
- return res.json({success: 'S', data: file, 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);
- 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)=>{
- 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'})
- }
- }
- }
- )
- 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) {
- 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);
- // 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,
- },});
- files.push({name : data.name, data : response.data, type: data.file.mimeType});
- }
- }
- }
- const resultObj = {
- folder : folder,
- files : files,
- };
- return resultObj;
- }
- serverApp.post('/deleteItems',
- isAuthenticated,
- (req, res, next)=>{
- if (!req.session.accessToken) {
- return authProvider.acquireToken({
- scopes: ['.default'],
- redirectUri: 'https://localhost:53000/redirect',
- successRedirect: '/deleteItems'
- })(req, res, next);
- }
- next();
- },
- 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) {
- console.log(error.response.data.error);
-
- resultObj.success = 'F';
- resultObj.message = '선택하신 파일 정보 삭제중 오류가 발생하였습니다.<br>' + error.response.data.error.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,
- (req, res, next)=>{
- if (!req.session.accessToken) {
- return authProvider.acquireToken({
- scopes: ['.default'],
- redirectUri: 'https://localhost:53000/redirect',
- successRedirect: '/api/update-name'
- })(req, res, next);
- }
- next();
- },
- 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 = '선택하신 파일의 이름 변경 중 오류가 발생하였습니다.<br>' + 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);
- }
- })
|