zet-lib 1.4.25 → 1.4.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Util.js +23 -18
- package/lib/index.js +1 -0
- package/lib/zAppRouter.js +142 -324
- package/lib/zDropbox.js +134 -0
- package/lib/zRoute.js +58 -51
- package/package.json +1 -1
package/lib/Util.js
CHANGED
|
@@ -1442,26 +1442,30 @@ Util.tableShowInGrid = (arr, qey, MYMODEL, myCache, companyId) => {
|
|
|
1442
1442
|
arr.map((item) => {
|
|
1443
1443
|
html += `<tr>`;
|
|
1444
1444
|
for (let key in item) {
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1445
|
+
if (mywidget[key]) {
|
|
1446
|
+
if (!mywidget[key].hidden) {
|
|
1447
|
+
var keyFields = key + "Fields";
|
|
1448
|
+
var keyObject = key + "Object";
|
|
1449
|
+
let value = item[key];
|
|
1450
|
+
if (mywidget[key].name == "select") {
|
|
1451
|
+
value = value ? mywidget[key].fields[value] : "";
|
|
1452
|
+
} else if (mywidget[key].name == "relation") {
|
|
1453
|
+
value = value
|
|
1454
|
+
? Util.array_id_to_zname(
|
|
1455
|
+
myCache.get(
|
|
1456
|
+
`${mywidget[key].table}_${MYMODEL.widgets[qey].table}___${key}_${companyId}`
|
|
1457
|
+
)
|
|
1458
|
+
)[value]
|
|
1459
|
+
: "";
|
|
1460
|
+
} else {
|
|
1461
|
+
if (Util.isNumeric(value)) {
|
|
1462
|
+
value = Util.formatNumber(value, ".");
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
html += `<td>${value}</td>`;
|
|
1461
1467
|
}
|
|
1462
1468
|
}
|
|
1463
|
-
|
|
1464
|
-
html += `<td>${value}</td>`;
|
|
1465
1469
|
}
|
|
1466
1470
|
html += `</tr>`;
|
|
1467
1471
|
});
|
|
@@ -1469,6 +1473,7 @@ Util.tableShowInGrid = (arr, qey, MYMODEL, myCache, companyId) => {
|
|
|
1469
1473
|
}
|
|
1470
1474
|
return html;
|
|
1471
1475
|
} catch (e) {
|
|
1476
|
+
console.log(e);
|
|
1472
1477
|
return e + "";
|
|
1473
1478
|
}
|
|
1474
1479
|
};
|
package/lib/index.js
CHANGED
package/lib/zAppRouter.js
CHANGED
|
@@ -27,6 +27,7 @@ const path = require("path");
|
|
|
27
27
|
const { Dropbox } = require("dropbox");
|
|
28
28
|
const fetch = require("isomorphic-fetch");
|
|
29
29
|
const JSZip = require("jszip");
|
|
30
|
+
const zDropbox = require("./zDropbox");
|
|
30
31
|
|
|
31
32
|
/*
|
|
32
33
|
ajax Post
|
|
@@ -711,16 +712,6 @@ router.post("/zzapproval", async (req, res) => {
|
|
|
711
712
|
}
|
|
712
713
|
if (data.status == 2) {
|
|
713
714
|
//send activity
|
|
714
|
-
/* await zRoute.insertSQL(req, res, "zactivity", {
|
|
715
|
-
user_id: res.locals.userId,
|
|
716
|
-
table: MYMODEL.table,
|
|
717
|
-
id_data: data.id,
|
|
718
|
-
status: data.status,
|
|
719
|
-
status_label: MYMODEL.widgets.status.fields[data.status],
|
|
720
|
-
title: MYMODEL.widgets.status.fields[data.status],
|
|
721
|
-
description: users[res.locals.userId].fname + " " +users[res.locals.userId].lname ,
|
|
722
|
-
data: JSON.stringify(data)
|
|
723
|
-
});*/
|
|
724
715
|
//if serial
|
|
725
716
|
if (data.type == 2) {
|
|
726
717
|
approvers = [approvers[0]];
|
|
@@ -788,41 +779,8 @@ router.post("/zzapproval", async (req, res) => {
|
|
|
788
779
|
} \r\n \r\n`;
|
|
789
780
|
textWa += "We have some document for you.\r\n";
|
|
790
781
|
textWa += `Please click the link above to view the document.\r\n${link}`;
|
|
791
|
-
|
|
792
|
-
/* await whatsapp({
|
|
793
|
-
to: phone,
|
|
794
|
-
text: textWa,
|
|
795
|
-
sections: JSON.stringify(sections),
|
|
796
|
-
buttonText: "Click me for details"
|
|
797
|
-
});*/
|
|
798
782
|
}
|
|
799
|
-
|
|
800
783
|
//send notification
|
|
801
|
-
/* await zRoute.insertSQL(req, res, "znotification", {
|
|
802
|
-
user_id: item,
|
|
803
|
-
table: MYMODEL.table,
|
|
804
|
-
id_data: data.id,
|
|
805
|
-
status: 1,
|
|
806
|
-
link: "/za/" + post.token,
|
|
807
|
-
status_label: MYMODEL.widgets.status.fields[1],
|
|
808
|
-
title: `Need Approve`,
|
|
809
|
-
description: data.title,
|
|
810
|
-
token: post.token
|
|
811
|
-
});*/
|
|
812
|
-
|
|
813
|
-
//send todolist
|
|
814
|
-
/* await zRoute.insertSQL(req, res, "ztodolist", {
|
|
815
|
-
user_id: item,
|
|
816
|
-
table: MYMODEL.table,
|
|
817
|
-
id_data: data.id,
|
|
818
|
-
status: 1,
|
|
819
|
-
link: "/za/" + post.token,
|
|
820
|
-
status_label: MYMODEL.widgets.status.fields[1],
|
|
821
|
-
title: `Need Approve`,
|
|
822
|
-
description: data.title,
|
|
823
|
-
users: JSON.stringify(allUsers)
|
|
824
|
-
});*/
|
|
825
|
-
|
|
826
784
|
//send toastr using socket.io
|
|
827
785
|
io.to(users[item].token).emit("message", "Need Approve " + data.title);
|
|
828
786
|
});
|
|
@@ -866,51 +824,7 @@ router.post("/zzapproval", async (req, res) => {
|
|
|
866
824
|
} \r\n \r\n`;
|
|
867
825
|
textWa += "We have some document for you.\r\n";
|
|
868
826
|
textWa += `Please click the link above to view the document.\r\n${link}`;
|
|
869
|
-
/* await whatsapp({
|
|
870
|
-
to: phone,
|
|
871
|
-
text: textWa,
|
|
872
|
-
sections: JSON.stringify(sections),
|
|
873
|
-
buttonText: "Click me for details"
|
|
874
|
-
});*/
|
|
875
827
|
}
|
|
876
|
-
|
|
877
|
-
//send activity
|
|
878
|
-
/* await cRoute.insertSQL(req, res, "zactivity",{
|
|
879
|
-
user_id:item,
|
|
880
|
-
table:MYMODEL.table,
|
|
881
|
-
id_data:data.id,
|
|
882
|
-
status:7,
|
|
883
|
-
status_label: MYMODEL.widgets.status.fields[7],
|
|
884
|
-
title : MYMODEL.widgets.status.fields[7],
|
|
885
|
-
description: data.title,
|
|
886
|
-
data:JSON.stringify(data)
|
|
887
|
-
});*/
|
|
888
|
-
|
|
889
|
-
//send notification
|
|
890
|
-
/* await zRoute.insertSQL(req, res, "znotification", {
|
|
891
|
-
user_id: item,
|
|
892
|
-
table: MYMODEL.table,
|
|
893
|
-
id_data: data.id,
|
|
894
|
-
status: 1,
|
|
895
|
-
link: "/za/" + post.token,
|
|
896
|
-
status_label: MYMODEL.widgets.status.fields[1],
|
|
897
|
-
title: `Need Acknowledge`,
|
|
898
|
-
description: data.title,
|
|
899
|
-
token: post.token
|
|
900
|
-
});
|
|
901
|
-
|
|
902
|
-
//send todolist
|
|
903
|
-
await zRoute.insertSQL(req, res, "ztodolist", {
|
|
904
|
-
user_id: item,
|
|
905
|
-
table: MYMODEL.table,
|
|
906
|
-
id_data: data.id,
|
|
907
|
-
status: 1,
|
|
908
|
-
link: "/za/" + post.token,
|
|
909
|
-
status_label: MYMODEL.widgets.status.fields[1],
|
|
910
|
-
title: `Need Acknowledge`,
|
|
911
|
-
description: data.title,
|
|
912
|
-
users: JSON.stringify(allUsers)
|
|
913
|
-
});*/
|
|
914
828
|
io.to(users[item].token).emit(
|
|
915
829
|
"message",
|
|
916
830
|
"Need Acknowledge " + data.title
|
|
@@ -1045,25 +959,6 @@ router.get("/za/:token", csrfProtection, async (req, res) => {
|
|
|
1045
959
|
//send activity
|
|
1046
960
|
if (result.mystatus == 7) {
|
|
1047
961
|
MYMODEL = MYMODELS["zapprovals"];
|
|
1048
|
-
/* await connection.insert({
|
|
1049
|
-
table: "zactivity",
|
|
1050
|
-
data: {
|
|
1051
|
-
company_id: result.company_id,
|
|
1052
|
-
created_at: Util.now(),
|
|
1053
|
-
created_by: result.user_id,
|
|
1054
|
-
updated_by: result.user_id,
|
|
1055
|
-
user_id: result.user_id,
|
|
1056
|
-
table: MYMODEL.table,
|
|
1057
|
-
id_data: result.ide,
|
|
1058
|
-
status: 6,
|
|
1059
|
-
status_label: MYMODEL.widgets.status.fields[6],
|
|
1060
|
-
title: `${MYMODEL.widgets.status.fields[6]}`,
|
|
1061
|
-
description: `Ok `,
|
|
1062
|
-
data: JSON.stringify(data)
|
|
1063
|
-
}
|
|
1064
|
-
});
|
|
1065
|
-
*/
|
|
1066
|
-
|
|
1067
962
|
await connection.update({
|
|
1068
963
|
table: "zapprovals_details",
|
|
1069
964
|
where: {
|
|
@@ -1869,168 +1764,80 @@ router.post("/zcompress-dropzone", async (req, res) => {
|
|
|
1869
1764
|
}
|
|
1870
1765
|
});
|
|
1871
1766
|
|
|
1872
|
-
//for dropbox
|
|
1873
|
-
// Initialize Dropbox client
|
|
1874
|
-
let dbx = new Dropbox({
|
|
1875
|
-
accessToken: process.env.DROPBOX_ACCESS_TOKEN,
|
|
1876
|
-
refreshToken: process.env.DROPBOX_REFRESH_TOKEN,
|
|
1877
|
-
clientId: process.env.DROPBOX_CLIENT_ID,
|
|
1878
|
-
clientSecret: process.env.DROPBOX_CLIENT_SECRET,
|
|
1879
|
-
fetch: fetch,
|
|
1880
|
-
});
|
|
1881
|
-
|
|
1882
|
-
// Function to refresh access token
|
|
1883
|
-
async function refreshAccessToken() {
|
|
1884
|
-
try {
|
|
1885
|
-
const response = await fetch("https://api.dropbox.com/oauth2/token", {
|
|
1886
|
-
method: "POST",
|
|
1887
|
-
headers: {
|
|
1888
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
1889
|
-
},
|
|
1890
|
-
body: new URLSearchParams({
|
|
1891
|
-
grant_type: "refresh_token",
|
|
1892
|
-
refresh_token: process.env.DROPBOX_REFRESH_TOKEN,
|
|
1893
|
-
client_id: process.env.DROPBOX_CLIENT_ID,
|
|
1894
|
-
client_secret: process.env.DROPBOX_CLIENT_SECRET,
|
|
1895
|
-
}),
|
|
1896
|
-
});
|
|
1897
|
-
|
|
1898
|
-
const data = await response.json();
|
|
1899
|
-
|
|
1900
|
-
if (data.access_token) {
|
|
1901
|
-
// Update the access token in the Dropbox client
|
|
1902
|
-
dbx = new Dropbox({
|
|
1903
|
-
accessToken: data.access_token,
|
|
1904
|
-
refreshToken: process.env.DROPBOX_REFRESH_TOKEN,
|
|
1905
|
-
clientId: process.env.DROPBOX_CLIENT_ID,
|
|
1906
|
-
clientSecret: process.env.DROPBOX_CLIENT_SECRET,
|
|
1907
|
-
fetch: fetch,
|
|
1908
|
-
});
|
|
1909
|
-
|
|
1910
|
-
// Update the .env file with the new access token
|
|
1911
|
-
const envContent = fs.readFileSync(`${dirRoot}/.env`, "utf8");
|
|
1912
|
-
const updatedEnv = envContent.replace(
|
|
1913
|
-
/DROPBOX_ACCESS_TOKEN=.*/,
|
|
1914
|
-
`DROPBOX_ACCESS_TOKEN=${data.access_token}`
|
|
1915
|
-
);
|
|
1916
|
-
fs.writeFileSync(`${dirRoot}/.env`, updatedEnv);
|
|
1917
|
-
|
|
1918
|
-
return data.access_token;
|
|
1919
|
-
} else {
|
|
1920
|
-
throw new Error("Failed to refresh access token");
|
|
1921
|
-
}
|
|
1922
|
-
} catch (error) {
|
|
1923
|
-
console.error("Error refreshing access token:", error);
|
|
1924
|
-
throw error;
|
|
1925
|
-
}
|
|
1926
|
-
}
|
|
1927
|
-
|
|
1928
|
-
// Middleware to handle token refresh
|
|
1929
|
-
async function handleTokenRefresh(req, res, next) {
|
|
1930
|
-
try {
|
|
1931
|
-
// Try to make a test API call
|
|
1932
|
-
await dbx.usersGetCurrentAccount();
|
|
1933
|
-
next();
|
|
1934
|
-
} catch (error) {
|
|
1935
|
-
if (error.status === 401) {
|
|
1936
|
-
try {
|
|
1937
|
-
// Token expired, try to refresh it
|
|
1938
|
-
await refreshAccessToken();
|
|
1939
|
-
next();
|
|
1940
|
-
} catch (refreshError) {
|
|
1941
|
-
res
|
|
1942
|
-
.status(401)
|
|
1943
|
-
.json({ error: "Authentication failed. Please re-authenticate." });
|
|
1944
|
-
}
|
|
1945
|
-
} else {
|
|
1946
|
-
next(error);
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
|
|
1951
|
-
// Serve static files
|
|
1952
|
-
//app.use(express.static('public'));
|
|
1953
|
-
// Create test folder if it doesn't exist
|
|
1954
|
-
//dir = '/test'
|
|
1955
|
-
async function ensureFolder(dir) {
|
|
1956
|
-
try {
|
|
1957
|
-
await dbx.filesCreateFolderV2({
|
|
1958
|
-
path: dir,
|
|
1959
|
-
autorename: false,
|
|
1960
|
-
});
|
|
1961
|
-
} catch (error) {
|
|
1962
|
-
if (error.status !== 409) {
|
|
1963
|
-
// 409 means folder already exists
|
|
1964
|
-
throw error;
|
|
1965
|
-
}
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
|
|
1969
1767
|
// Function to delay execution
|
|
1970
1768
|
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1971
1769
|
|
|
1770
|
+
let dbx = zDropbox.dbx;
|
|
1972
1771
|
// Upload endpoint
|
|
1973
|
-
router.post(
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1772
|
+
router.post(
|
|
1773
|
+
"/zdropbox/:table/:field",
|
|
1774
|
+
zDropbox.handleTokenRefresh,
|
|
1775
|
+
async (req, res) => {
|
|
1776
|
+
try {
|
|
1777
|
+
if (!req.files || !req.files.file) {
|
|
1778
|
+
return res.status(400).json({ error: "No file uploaded" });
|
|
1779
|
+
}
|
|
1780
|
+
const userId = res.locals.userId;
|
|
1781
|
+
const table = req.params.table;
|
|
1782
|
+
const field = req.params.field;
|
|
1783
|
+
const file = req.files.file;
|
|
1784
|
+
const fileName = file.name;
|
|
1785
|
+
//ensure folder
|
|
1786
|
+
const dir = `/temps/${table}/${field}/${userId}`;
|
|
1787
|
+
await zDropbox.ensureFolder(dir);
|
|
1788
|
+
const filePath = `${dir}/${fileName}`;
|
|
1789
|
+
/*console.log("Uploading file to path:", filePath);
|
|
1988
1790
|
console.log("File size:", file.size);
|
|
1989
1791
|
console.log("File name:", fileName);*/
|
|
1990
1792
|
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
1793
|
+
const response = await dbx.filesUpload({
|
|
1794
|
+
path: filePath,
|
|
1795
|
+
contents: file.data,
|
|
1796
|
+
mode: { ".tag": "add" },
|
|
1797
|
+
autorename: true,
|
|
1798
|
+
});
|
|
1799
|
+
res.json("ok");
|
|
1800
|
+
} catch (error) {
|
|
1801
|
+
console.error("Error details:", {
|
|
1802
|
+
message: error.message,
|
|
1803
|
+
stack: error.stack,
|
|
1804
|
+
response: error.response,
|
|
1805
|
+
});
|
|
1806
|
+
res.status(500).json({
|
|
1807
|
+
error: "Failed to upload file",
|
|
1808
|
+
details: error.message,
|
|
1809
|
+
});
|
|
1810
|
+
}
|
|
2008
1811
|
}
|
|
2009
|
-
|
|
1812
|
+
);
|
|
2010
1813
|
|
|
2011
|
-
router.post(
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
if (
|
|
2023
|
-
arr
|
|
1814
|
+
router.post(
|
|
1815
|
+
"/zdropbox-attributes",
|
|
1816
|
+
zDropbox.handleTokenRefresh,
|
|
1817
|
+
async (req, res) => {
|
|
1818
|
+
try {
|
|
1819
|
+
let userId = res.locals.userId;
|
|
1820
|
+
let body = req.body;
|
|
1821
|
+
console.log(body);
|
|
1822
|
+
let category = body.category;
|
|
1823
|
+
let name = `dropbox__${userId}__${body.table}__${body.field}__${body.type}`;
|
|
1824
|
+
let arr = myCache.has(name) ? myCache.get(name) : [];
|
|
1825
|
+
if (category === "add") {
|
|
1826
|
+
arr.push(body.file);
|
|
1827
|
+
} else {
|
|
1828
|
+
if (myCache.has(name)) {
|
|
1829
|
+
arr = myCache.get(name);
|
|
1830
|
+
}
|
|
1831
|
+
arr = Util.arrayDelete(arr, body.file);
|
|
2024
1832
|
}
|
|
2025
|
-
|
|
1833
|
+
myCache.set(name, arr);
|
|
1834
|
+
res.json("ok");
|
|
1835
|
+
} catch (e) {
|
|
1836
|
+
console.log(e);
|
|
1837
|
+
res.status(500).send(e + "");
|
|
2026
1838
|
}
|
|
2027
|
-
myCache.set(name, arr);
|
|
2028
|
-
res.json("ok");
|
|
2029
|
-
} catch (e) {
|
|
2030
|
-
console.log(e);
|
|
2031
|
-
res.status(500).send(e + "");
|
|
2032
1839
|
}
|
|
2033
|
-
|
|
1840
|
+
);
|
|
2034
1841
|
|
|
2035
1842
|
//get all files and meta in dropbox
|
|
2036
1843
|
router.post("/zdropbox-files", async (req, res) => {
|
|
@@ -2061,14 +1868,16 @@ router.post("/zdropbox-files", async (req, res) => {
|
|
|
2061
1868
|
res.json(datas);
|
|
2062
1869
|
});
|
|
2063
1870
|
|
|
2064
|
-
router.post(
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
1871
|
+
router.post(
|
|
1872
|
+
"/zdropbox-file/:index",
|
|
1873
|
+
zDropbox.handleTokenRefresh,
|
|
1874
|
+
async (req, res) => {
|
|
1875
|
+
let datas = {};
|
|
1876
|
+
const room = res.locals.token;
|
|
2068
1877
|
const { fileName, table, field } = req.body;
|
|
2069
1878
|
let dir = `/${table}/${field}`;
|
|
2070
1879
|
let pathFile = `${dir}/${fileName}`;
|
|
2071
|
-
|
|
1880
|
+
console.log(pathFile);
|
|
2072
1881
|
try {
|
|
2073
1882
|
const metadata = await dbx.filesGetMetadata({
|
|
2074
1883
|
path: pathFile,
|
|
@@ -2129,85 +1938,94 @@ router.post("/zdropbox-file/:index", handleTokenRefresh, async (req, res) => {
|
|
|
2129
1938
|
`${e.message} Error ${pathFile} not exist in dropbox, Please reload your browser !!`
|
|
2130
1939
|
);
|
|
2131
1940
|
}
|
|
2132
|
-
|
|
2133
|
-
console.log(e);
|
|
2134
|
-
res.status(500).send(e + "");
|
|
1941
|
+
res.json(datas);
|
|
2135
1942
|
}
|
|
2136
|
-
|
|
2137
|
-
});
|
|
1943
|
+
);
|
|
2138
1944
|
|
|
2139
1945
|
// Delete file dicache dulu kemudian submit delete dropbox file
|
|
2140
|
-
router.post(
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
1946
|
+
router.post(
|
|
1947
|
+
"/zdropbox-remove/",
|
|
1948
|
+
zDropbox.handleTokenRefresh,
|
|
1949
|
+
async (req, res) => {
|
|
1950
|
+
try {
|
|
1951
|
+
let body = req.body;
|
|
1952
|
+
//console.log(body);
|
|
1953
|
+
const userId = res.locals.userId;
|
|
1954
|
+
const fileName = body.file;
|
|
1955
|
+
let cname = body.cname.replace("ZUSER___ID", userId);
|
|
1956
|
+
let cacheName = cname;
|
|
1957
|
+
//console.log(cacheName);
|
|
1958
|
+
let splits = cname.split("__");
|
|
1959
|
+
let table = splits[2];
|
|
1960
|
+
let field = splits[3];
|
|
1961
|
+
let type = splits[4];
|
|
1962
|
+
const dir = `/temps/${table}/${field}/${userId}`;
|
|
1963
|
+
await zDropbox.ensureFolder(dir);
|
|
1964
|
+
const filePath = `${dir}/${fileName}`;
|
|
1965
|
+
let arr = [];
|
|
1966
|
+
if (type != "create") {
|
|
1967
|
+
cacheName = cacheName + "__remove";
|
|
1968
|
+
}
|
|
1969
|
+
if (myCache.has(cacheName)) {
|
|
1970
|
+
arr = myCache.get(cacheName);
|
|
1971
|
+
}
|
|
1972
|
+
//console.log(cacheName)
|
|
1973
|
+
if (type == "create") {
|
|
1974
|
+
try {
|
|
1975
|
+
await dbx.filesDeleteV2({
|
|
1976
|
+
path: filePath,
|
|
1977
|
+
});
|
|
1978
|
+
arr = Util.arrayDelete(arr, body.file);
|
|
1979
|
+
myCache.set(cacheName, arr);
|
|
1980
|
+
} catch (e) {
|
|
1981
|
+
console.log(e);
|
|
1982
|
+
}
|
|
1983
|
+
} else {
|
|
1984
|
+
arr.push(body.file);
|
|
2170
1985
|
myCache.set(cacheName, arr);
|
|
2171
|
-
} catch (e) {
|
|
2172
|
-
console.log(e);
|
|
2173
1986
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
1987
|
+
res.json({ success: true });
|
|
1988
|
+
} catch (error) {
|
|
1989
|
+
console.error("Error deleting file:", error);
|
|
1990
|
+
res.status(500).json({ error: "Error deleting file" });
|
|
2177
1991
|
}
|
|
2178
|
-
res.json({ success: true });
|
|
2179
|
-
} catch (error) {
|
|
2180
|
-
console.error("Error deleting file:", error);
|
|
2181
|
-
res.status(500).json({ error: "Error deleting file" });
|
|
2182
1992
|
}
|
|
2183
|
-
|
|
1993
|
+
);
|
|
2184
1994
|
|
|
2185
1995
|
// Endpoint to check token status
|
|
2186
|
-
router.get(
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
1996
|
+
router.get(
|
|
1997
|
+
"/zdropbox-check-token",
|
|
1998
|
+
zDropbox.handleTokenRefresh,
|
|
1999
|
+
async (req, res) => {
|
|
2000
|
+
try {
|
|
2001
|
+
await dbx.usersGetCurrentAccount();
|
|
2002
|
+
res.json({ status: "valid" });
|
|
2003
|
+
} catch (error) {
|
|
2004
|
+
res.status(401).json({ status: "invalid" });
|
|
2005
|
+
}
|
|
2192
2006
|
}
|
|
2193
|
-
|
|
2007
|
+
);
|
|
2194
2008
|
|
|
2195
2009
|
// Get temporary link for a file
|
|
2196
|
-
router.post(
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2010
|
+
router.post(
|
|
2011
|
+
"/zdropbox-get-temp-link",
|
|
2012
|
+
zDropbox.handleTokenRefresh,
|
|
2013
|
+
async (req, res) => {
|
|
2014
|
+
try {
|
|
2015
|
+
const response = await dbx.filesGetTemporaryLink({
|
|
2016
|
+
path: req.body.path,
|
|
2017
|
+
});
|
|
2018
|
+
res.json({ link: response.result.link });
|
|
2019
|
+
} catch (error) {
|
|
2020
|
+
console.error("Error getting temporary link:", error);
|
|
2021
|
+
res.status(500).json({ error: "Error getting temporary link" });
|
|
2022
|
+
}
|
|
2205
2023
|
}
|
|
2206
|
-
|
|
2024
|
+
);
|
|
2207
2025
|
|
|
2208
2026
|
router.get(
|
|
2209
2027
|
"/zdropbox-view/:table/:field/:item",
|
|
2210
|
-
handleTokenRefresh,
|
|
2028
|
+
zDropbox.handleTokenRefresh,
|
|
2211
2029
|
async (req, res) => {
|
|
2212
2030
|
try {
|
|
2213
2031
|
let item = req.params.item;
|
package/lib/zDropbox.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require("dotenv").config();
|
|
2
|
+
const { Dropbox } = require("dropbox");
|
|
3
|
+
const fetch = require("isomorphic-fetch");
|
|
4
|
+
const Util = require("./Util");
|
|
5
|
+
|
|
6
|
+
const zDropbox = {};
|
|
7
|
+
|
|
8
|
+
let dbx = new Dropbox({
|
|
9
|
+
accessToken: process.env.DROPBOX_ACCESS_TOKEN,
|
|
10
|
+
refreshToken: process.env.DROPBOX_REFRESH_TOKEN,
|
|
11
|
+
clientId: process.env.DROPBOX_CLIENT_ID,
|
|
12
|
+
clientSecret: process.env.DROPBOX_CLIENT_SECRET,
|
|
13
|
+
fetch: fetch,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
zDropbox.dbx = dbx;
|
|
17
|
+
|
|
18
|
+
// Function to refresh access token
|
|
19
|
+
zDropbox.refreshAccessToken = async () => {
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetch("https://api.dropbox.com/oauth2/token", {
|
|
22
|
+
method: "POST",
|
|
23
|
+
headers: {
|
|
24
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
25
|
+
},
|
|
26
|
+
body: new URLSearchParams({
|
|
27
|
+
grant_type: "refresh_token",
|
|
28
|
+
refresh_token: process.env.DROPBOX_REFRESH_TOKEN,
|
|
29
|
+
client_id: process.env.DROPBOX_CLIENT_ID,
|
|
30
|
+
client_secret: process.env.DROPBOX_CLIENT_SECRET,
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const data = await response.json();
|
|
35
|
+
|
|
36
|
+
if (data.access_token) {
|
|
37
|
+
// Update the access token in the Dropbox client
|
|
38
|
+
dbx = new Dropbox({
|
|
39
|
+
accessToken: data.access_token,
|
|
40
|
+
refreshToken: process.env.DROPBOX_REFRESH_TOKEN,
|
|
41
|
+
clientId: process.env.DROPBOX_CLIENT_ID,
|
|
42
|
+
clientSecret: process.env.DROPBOX_CLIENT_SECRET,
|
|
43
|
+
fetch: fetch,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Update the .env file with the new access token
|
|
47
|
+
const envContent = fs.readFileSync(`${dirRoot}/.env`, "utf8");
|
|
48
|
+
const updatedEnv = envContent.replace(
|
|
49
|
+
/DROPBOX_ACCESS_TOKEN=.*/,
|
|
50
|
+
`DROPBOX_ACCESS_TOKEN=${data.access_token}`
|
|
51
|
+
);
|
|
52
|
+
fs.writeFileSync(`${dirRoot}/.env`, updatedEnv);
|
|
53
|
+
|
|
54
|
+
return data.access_token;
|
|
55
|
+
} else {
|
|
56
|
+
throw new Error("Failed to refresh access token");
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error("Error refreshing access token:", error);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Middleware to handle token refresh
|
|
65
|
+
zDropbox.handleTokenRefresh = async (req, res, next) => {
|
|
66
|
+
try {
|
|
67
|
+
// Try to make a test API call
|
|
68
|
+
await dbx.usersGetCurrentAccount();
|
|
69
|
+
next();
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (error.status === 401) {
|
|
72
|
+
try {
|
|
73
|
+
// Token expired, try to refresh it
|
|
74
|
+
await zDropbox.refreshAccessToken();
|
|
75
|
+
next();
|
|
76
|
+
} catch (refreshError) {
|
|
77
|
+
res
|
|
78
|
+
.status(401)
|
|
79
|
+
.json({ error: "Authentication failed. Please re-authenticate." });
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
next(error);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
zDropbox.ensureFolder = async (dir) => {
|
|
88
|
+
try {
|
|
89
|
+
await dbx.filesCreateFolderV2({
|
|
90
|
+
path: dir,
|
|
91
|
+
autorename: false,
|
|
92
|
+
});
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (error.status !== 409) {
|
|
95
|
+
// 409 means folder already exists
|
|
96
|
+
console.log(error + "");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
zDropbox.deleteFolder = async (dir) => {
|
|
102
|
+
let jsonStatus = Util.flashError("error");
|
|
103
|
+
try {
|
|
104
|
+
if (!dir) {
|
|
105
|
+
return Util.flashError("not folder");
|
|
106
|
+
}
|
|
107
|
+
// First check if the path exists and is a folder
|
|
108
|
+
try {
|
|
109
|
+
const metadata = await dbx.filesGetMetadata({
|
|
110
|
+
path: dir,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (metadata.result[".tag"] !== "folder") {
|
|
114
|
+
return Util.flashError("The specified path is not a folder");
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (error.status === 409) {
|
|
118
|
+
return Util.flashError("Folder not found");
|
|
119
|
+
}
|
|
120
|
+
//throw error;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Delete the folder
|
|
124
|
+
await dbx.filesDeleteV2({
|
|
125
|
+
path: dir,
|
|
126
|
+
});
|
|
127
|
+
return Util.jsonSuccess("Folder deleted successfully");
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error("Delete folder error:", error);
|
|
130
|
+
return Util.flashError("Failed to delete folder");
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
module.exports = zDropbox;
|
package/lib/zRoute.js
CHANGED
|
@@ -21,7 +21,8 @@ const debug = require("./debug");
|
|
|
21
21
|
const moduleLib = require("./moduleLib");
|
|
22
22
|
const cForm = require("./Form");
|
|
23
23
|
const readXlsxFile = require("read-excel-file/node");
|
|
24
|
-
const { Dropbox } = require("dropbox");
|
|
24
|
+
//const { Dropbox } = require("dropbox");
|
|
25
|
+
const zDropbox = require("./zDropbox");
|
|
25
26
|
|
|
26
27
|
const zRoute = {};
|
|
27
28
|
|
|
@@ -3108,6 +3109,11 @@ zRoute.forms = (
|
|
|
3108
3109
|
break;
|
|
3109
3110
|
case "dropbox":
|
|
3110
3111
|
let dropbox_data_arr = [];
|
|
3112
|
+
//clear temp folder /temps/estimation/documents/8
|
|
3113
|
+
/*zDropbox.deleteFolder(`/temps/${MYMODEL.table}/${key}/${res.locals.userId}`).then(function (tt) {
|
|
3114
|
+
console.log(tt)
|
|
3115
|
+
zDropbox.ensureFolder(`/temps/${MYMODEL.table}/${key}/${res.locals.userId}`)
|
|
3116
|
+
})*/
|
|
3111
3117
|
if (obj.value.length > 0) {
|
|
3112
3118
|
let dropfiles = obj.value || [];
|
|
3113
3119
|
if (typeof obj.value == "string") {
|
|
@@ -4730,25 +4736,8 @@ zRoute.insertSQL = async (req, res, table, data) => {
|
|
|
4730
4736
|
let path_dest = `/${MYMODEL.table}/${key}`;
|
|
4731
4737
|
|
|
4732
4738
|
// Initialize Dropbox client
|
|
4733
|
-
let dbx =
|
|
4734
|
-
|
|
4735
|
-
refreshToken: process.env.DROPBOX_REFRESH_TOKEN,
|
|
4736
|
-
clientId: process.env.DROPBOX_CLIENT_ID,
|
|
4737
|
-
clientSecret: process.env.DROPBOX_CLIENT_SECRET,
|
|
4738
|
-
fetch: fetch,
|
|
4739
|
-
});
|
|
4740
|
-
|
|
4741
|
-
try {
|
|
4742
|
-
await dbx.filesCreateFolderV2({
|
|
4743
|
-
path: path_dest,
|
|
4744
|
-
autorename: false,
|
|
4745
|
-
});
|
|
4746
|
-
} catch (error) {
|
|
4747
|
-
if (error.status !== 409) {
|
|
4748
|
-
// 409 means folder already exists
|
|
4749
|
-
throw error;
|
|
4750
|
-
}
|
|
4751
|
-
}
|
|
4739
|
+
let dbx = zDropbox.dbx;
|
|
4740
|
+
await zDropbox.ensureFolder(path_dest);
|
|
4752
4741
|
|
|
4753
4742
|
//get all files in folder
|
|
4754
4743
|
//let files = await
|
|
@@ -4765,7 +4754,9 @@ zRoute.insertSQL = async (req, res, table, data) => {
|
|
|
4765
4754
|
let newItem = Util.cleanString(time + item);
|
|
4766
4755
|
movDropboxArr.push({
|
|
4767
4756
|
from_path: `${path_src}/${item}`,
|
|
4757
|
+
from_dir: path_src,
|
|
4768
4758
|
to_path: `${path_dest}/${newItem}`,
|
|
4759
|
+
to_dir: path_dest,
|
|
4769
4760
|
});
|
|
4770
4761
|
newArr.push(newItem);
|
|
4771
4762
|
} catch (e) {
|
|
@@ -4778,14 +4769,17 @@ zRoute.insertSQL = async (req, res, table, data) => {
|
|
|
4778
4769
|
myCache.del(name);
|
|
4779
4770
|
}
|
|
4780
4771
|
}
|
|
4781
|
-
const result = await connection.insert({ table: table, data: data });
|
|
4782
|
-
zRoute.modelsCacheRenew(table, res.locals.companyId);
|
|
4783
4772
|
//dropbox
|
|
4773
|
+
console.log(JSON.stringify(movDropboxArr));
|
|
4784
4774
|
if (movDropboxArr.length > 0) {
|
|
4785
|
-
setTimeout(
|
|
4786
|
-
zRoute.moveDropbox(movDropboxArr)
|
|
4787
|
-
|
|
4775
|
+
setTimeout(() => {
|
|
4776
|
+
zRoute.moveDropbox(movDropboxArr).then(function (et) {
|
|
4777
|
+
console.log(et);
|
|
4778
|
+
});
|
|
4779
|
+
}, 1000);
|
|
4788
4780
|
}
|
|
4781
|
+
const result = await connection.insert({ table: table, data: data });
|
|
4782
|
+
zRoute.modelsCacheRenew(table, res.locals.companyId);
|
|
4789
4783
|
return result;
|
|
4790
4784
|
} catch (e) {
|
|
4791
4785
|
throw Error(e + "");
|
|
@@ -4794,24 +4788,49 @@ zRoute.insertSQL = async (req, res, table, data) => {
|
|
|
4794
4788
|
};
|
|
4795
4789
|
|
|
4796
4790
|
zRoute.moveDropbox = async (items) => {
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4791
|
+
// Initialize Dropbox client
|
|
4792
|
+
let dbx = zDropbox.dbx;
|
|
4793
|
+
for (item of items) {
|
|
4794
|
+
//console.log(JSON.stringify(item));
|
|
4795
|
+
try {
|
|
4796
|
+
//const normalizedSourcePath = '/' + item.from_path.replace(/^\/+|\/+$/g, '');
|
|
4797
|
+
//const normalizedDestPath = '/' + item.to_path.replace(/^\/+|\/+$/g, '');
|
|
4798
|
+
try {
|
|
4799
|
+
const sourceMetadata = await dbx.filesGetMetadata({
|
|
4800
|
+
path: item.from_path,
|
|
4801
|
+
});
|
|
4802
|
+
if (sourceMetadata.result[".tag"] !== "file") {
|
|
4803
|
+
console.log("Source path is not a file", normalizedSourcePath);
|
|
4804
|
+
continue;
|
|
4805
|
+
}
|
|
4806
|
+
console.log("Source file found:", sourceMetadata.result);
|
|
4807
|
+
} catch (error) {
|
|
4808
|
+
console.error("Source file check error:", error);
|
|
4809
|
+
continue;
|
|
4810
|
+
}
|
|
4811
|
+
// Check if destination folder exists
|
|
4812
|
+
try {
|
|
4813
|
+
const destMetadata = await dbx.filesGetMetadata({
|
|
4814
|
+
path: item.to_dir,
|
|
4815
|
+
});
|
|
4816
|
+
if (destMetadata.result[".tag"] !== "folder") {
|
|
4817
|
+
console.error("Destination path is not a folder", item.to_dir);
|
|
4818
|
+
}
|
|
4819
|
+
console.log("Destination folder found:", destMetadata.result);
|
|
4820
|
+
} catch (error) {
|
|
4821
|
+
console.error("Destination folder check error:", error);
|
|
4822
|
+
continue;
|
|
4823
|
+
}
|
|
4824
|
+
|
|
4807
4825
|
await dbx.filesMoveV2({
|
|
4808
4826
|
from_path: item.from_path,
|
|
4809
4827
|
to_path: item.to_path,
|
|
4810
4828
|
autorename: true,
|
|
4811
4829
|
});
|
|
4830
|
+
} catch (e) {
|
|
4831
|
+
console.log(JSON.stringify(item), "can not move");
|
|
4832
|
+
console.log(e);
|
|
4812
4833
|
}
|
|
4813
|
-
} catch (e) {
|
|
4814
|
-
console.log(e);
|
|
4815
4834
|
}
|
|
4816
4835
|
};
|
|
4817
4836
|
|
|
@@ -4875,13 +4894,7 @@ zRoute.updateSQL = async (req, res, table, data, whereData) => {
|
|
|
4875
4894
|
}
|
|
4876
4895
|
} else if (MYMODEL.widgets[key].name === "dropbox") {
|
|
4877
4896
|
// Initialize Dropbox client
|
|
4878
|
-
let dbx =
|
|
4879
|
-
accessToken: process.env.DROPBOX_ACCESS_TOKEN,
|
|
4880
|
-
refreshToken: process.env.DROPBOX_REFRESH_TOKEN,
|
|
4881
|
-
clientId: process.env.DROPBOX_CLIENT_ID,
|
|
4882
|
-
clientSecret: process.env.DROPBOX_CLIENT_SECRET,
|
|
4883
|
-
fetch: fetch,
|
|
4884
|
-
});
|
|
4897
|
+
let dbx = zDropbox.dbx;
|
|
4885
4898
|
//console.log('has dropbox')
|
|
4886
4899
|
let dir1 = `/${MYMODEL.table}/${key}`;
|
|
4887
4900
|
let dir2 = `/temps/${MYMODEL.table}/${key}/${userId}`;
|
|
@@ -5095,13 +5108,7 @@ zRoute.deleteFiles = async (table, result) => {
|
|
|
5095
5108
|
}
|
|
5096
5109
|
if (widgets[key].name == "dropbox") {
|
|
5097
5110
|
if (result[key]) {
|
|
5098
|
-
let dbx =
|
|
5099
|
-
accessToken: process.env.DROPBOX_ACCESS_TOKEN,
|
|
5100
|
-
refreshToken: process.env.DROPBOX_REFRESH_TOKEN,
|
|
5101
|
-
clientId: process.env.DROPBOX_CLIENT_ID,
|
|
5102
|
-
clientSecret: process.env.DROPBOX_CLIENT_SECRET,
|
|
5103
|
-
fetch: fetch,
|
|
5104
|
-
});
|
|
5111
|
+
let dbx = zDropbox.dbx;
|
|
5105
5112
|
const files = result[key];
|
|
5106
5113
|
const dropboxPath = `/${table}/${key}`;
|
|
5107
5114
|
for (const file of files) {
|