zet-lib 1.4.11 → 1.4.13

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/zAppRouter.js CHANGED
@@ -1,3 +1,4 @@
1
+ require("dotenv").config();
1
2
  const express = require("express");
2
3
  const router = express.Router();
3
4
  const csrf = require("csurf");
@@ -23,7 +24,8 @@ const qs = require("qs");
23
24
  const zip = require("express-zip");
24
25
  const sharp = require("sharp");
25
26
  const path = require("path");
26
-
27
+ const { Dropbox } = require("dropbox");
28
+ const fetch = require("isomorphic-fetch");
27
29
  /*
28
30
  ajax Post
29
31
  */
@@ -403,8 +405,8 @@ router.post("/signup-custom", async (req, res) => {
403
405
  },
404
406
  });
405
407
  /* await zRoute.loginAjax(dataUser.username, body.password, req, res);
406
- //refresh cache
407
- await zCache.renew();*/
408
+ //refresh cache
409
+ await zCache.renew();*/
408
410
 
409
411
  res.json(Util.jsonSuccess("Successfuly"));
410
412
  } catch (e) {
@@ -708,15 +710,15 @@ router.post("/zzapproval", async (req, res) => {
708
710
  if (data.status == 2) {
709
711
  //send activity
710
712
  /* await zRoute.insertSQL(req, res, "zactivity", {
711
- user_id: res.locals.userId,
712
- table: MYMODEL.table,
713
- id_data: data.id,
714
- status: data.status,
715
- status_label: MYMODEL.widgets.status.fields[data.status],
716
- title: MYMODEL.widgets.status.fields[data.status],
717
- description: users[res.locals.userId].fname + " " +users[res.locals.userId].lname ,
718
- data: JSON.stringify(data)
719
- });*/
713
+ user_id: res.locals.userId,
714
+ table: MYMODEL.table,
715
+ id_data: data.id,
716
+ status: data.status,
717
+ status_label: MYMODEL.widgets.status.fields[data.status],
718
+ title: MYMODEL.widgets.status.fields[data.status],
719
+ description: users[res.locals.userId].fname + " " +users[res.locals.userId].lname ,
720
+ data: JSON.stringify(data)
721
+ });*/
720
722
  //if serial
721
723
  if (data.type == 2) {
722
724
  approvers = [approvers[0]];
@@ -786,38 +788,38 @@ router.post("/zzapproval", async (req, res) => {
786
788
  textWa += `Please click the link above to view the document.\r\n${link}`;
787
789
 
788
790
  /* await whatsapp({
789
- to: phone,
790
- text: textWa,
791
- sections: JSON.stringify(sections),
792
- buttonText: "Click me for details"
793
- });*/
791
+ to: phone,
792
+ text: textWa,
793
+ sections: JSON.stringify(sections),
794
+ buttonText: "Click me for details"
795
+ });*/
794
796
  }
795
797
 
796
798
  //send notification
797
799
  /* await zRoute.insertSQL(req, res, "znotification", {
798
- user_id: item,
799
- table: MYMODEL.table,
800
- id_data: data.id,
801
- status: 1,
802
- link: "/za/" + post.token,
803
- status_label: MYMODEL.widgets.status.fields[1],
804
- title: `Need Approve`,
805
- description: data.title,
806
- token: post.token
807
- });*/
800
+ user_id: item,
801
+ table: MYMODEL.table,
802
+ id_data: data.id,
803
+ status: 1,
804
+ link: "/za/" + post.token,
805
+ status_label: MYMODEL.widgets.status.fields[1],
806
+ title: `Need Approve`,
807
+ description: data.title,
808
+ token: post.token
809
+ });*/
808
810
 
809
811
  //send todolist
810
812
  /* await zRoute.insertSQL(req, res, "ztodolist", {
811
- user_id: item,
812
- table: MYMODEL.table,
813
- id_data: data.id,
814
- status: 1,
815
- link: "/za/" + post.token,
816
- status_label: MYMODEL.widgets.status.fields[1],
817
- title: `Need Approve`,
818
- description: data.title,
819
- users: JSON.stringify(allUsers)
820
- });*/
813
+ user_id: item,
814
+ table: MYMODEL.table,
815
+ id_data: data.id,
816
+ status: 1,
817
+ link: "/za/" + post.token,
818
+ status_label: MYMODEL.widgets.status.fields[1],
819
+ title: `Need Approve`,
820
+ description: data.title,
821
+ users: JSON.stringify(allUsers)
822
+ });*/
821
823
 
822
824
  //send toastr using socket.io
823
825
  io.to(users[item].token).emit("message", "Need Approve " + data.title);
@@ -863,50 +865,50 @@ router.post("/zzapproval", async (req, res) => {
863
865
  textWa += "We have some document for you.\r\n";
864
866
  textWa += `Please click the link above to view the document.\r\n${link}`;
865
867
  /* await whatsapp({
866
- to: phone,
867
- text: textWa,
868
- sections: JSON.stringify(sections),
869
- buttonText: "Click me for details"
870
- });*/
868
+ to: phone,
869
+ text: textWa,
870
+ sections: JSON.stringify(sections),
871
+ buttonText: "Click me for details"
872
+ });*/
871
873
  }
872
874
 
873
875
  //send activity
874
876
  /* await cRoute.insertSQL(req, res, "zactivity",{
875
- user_id:item,
876
- table:MYMODEL.table,
877
- id_data:data.id,
878
- status:7,
879
- status_label: MYMODEL.widgets.status.fields[7],
880
- title : MYMODEL.widgets.status.fields[7],
881
- description: data.title,
882
- data:JSON.stringify(data)
883
- });*/
877
+ user_id:item,
878
+ table:MYMODEL.table,
879
+ id_data:data.id,
880
+ status:7,
881
+ status_label: MYMODEL.widgets.status.fields[7],
882
+ title : MYMODEL.widgets.status.fields[7],
883
+ description: data.title,
884
+ data:JSON.stringify(data)
885
+ });*/
884
886
 
885
887
  //send notification
886
888
  /* await zRoute.insertSQL(req, res, "znotification", {
887
- user_id: item,
888
- table: MYMODEL.table,
889
- id_data: data.id,
890
- status: 1,
891
- link: "/za/" + post.token,
892
- status_label: MYMODEL.widgets.status.fields[1],
893
- title: `Need Acknowledge`,
894
- description: data.title,
895
- token: post.token
896
- });
897
-
898
- //send todolist
899
- await zRoute.insertSQL(req, res, "ztodolist", {
900
- user_id: item,
901
- table: MYMODEL.table,
902
- id_data: data.id,
903
- status: 1,
904
- link: "/za/" + post.token,
905
- status_label: MYMODEL.widgets.status.fields[1],
906
- title: `Need Acknowledge`,
907
- description: data.title,
908
- users: JSON.stringify(allUsers)
909
- });*/
889
+ user_id: item,
890
+ table: MYMODEL.table,
891
+ id_data: data.id,
892
+ status: 1,
893
+ link: "/za/" + post.token,
894
+ status_label: MYMODEL.widgets.status.fields[1],
895
+ title: `Need Acknowledge`,
896
+ description: data.title,
897
+ token: post.token
898
+ });
899
+
900
+ //send todolist
901
+ await zRoute.insertSQL(req, res, "ztodolist", {
902
+ user_id: item,
903
+ table: MYMODEL.table,
904
+ id_data: data.id,
905
+ status: 1,
906
+ link: "/za/" + post.token,
907
+ status_label: MYMODEL.widgets.status.fields[1],
908
+ title: `Need Acknowledge`,
909
+ description: data.title,
910
+ users: JSON.stringify(allUsers)
911
+ });*/
910
912
  io.to(users[item].token).emit(
911
913
  "message",
912
914
  "Need Acknowledge " + data.title
@@ -1042,23 +1044,23 @@ router.get("/za/:token", csrfProtection, async (req, res) => {
1042
1044
  if (result.mystatus == 7) {
1043
1045
  MYMODEL = MYMODELS["zapprovals"];
1044
1046
  /* await connection.insert({
1045
- table: "zactivity",
1046
- data: {
1047
- company_id: result.company_id,
1048
- created_at: Util.now(),
1049
- created_by: result.user_id,
1050
- updated_by: result.user_id,
1051
- user_id: result.user_id,
1052
- table: MYMODEL.table,
1053
- id_data: result.ide,
1054
- status: 6,
1055
- status_label: MYMODEL.widgets.status.fields[6],
1056
- title: `${MYMODEL.widgets.status.fields[6]}`,
1057
- description: `Ok `,
1058
- data: JSON.stringify(data)
1059
- }
1060
- });
1061
- */
1047
+ table: "zactivity",
1048
+ data: {
1049
+ company_id: result.company_id,
1050
+ created_at: Util.now(),
1051
+ created_by: result.user_id,
1052
+ updated_by: result.user_id,
1053
+ user_id: result.user_id,
1054
+ table: MYMODEL.table,
1055
+ id_data: result.ide,
1056
+ status: 6,
1057
+ status_label: MYMODEL.widgets.status.fields[6],
1058
+ title: `${MYMODEL.widgets.status.fields[6]}`,
1059
+ description: `Ok `,
1060
+ data: JSON.stringify(data)
1061
+ }
1062
+ });
1063
+ */
1062
1064
 
1063
1065
  await connection.update({
1064
1066
  table: "zapprovals_details",
@@ -1636,6 +1638,7 @@ router.post("/zdropzone-remove", async (req, res) => {
1636
1638
  res.status(500).send(e + "");
1637
1639
  }
1638
1640
  });
1641
+
1639
1642
  router.post("/zdropzone-attributes", async (req, res) => {
1640
1643
  try {
1641
1644
  let userId = res.locals.userId;
@@ -1859,4 +1862,288 @@ router.post("/zcompress-dropzone", async (req, res) => {
1859
1862
  }
1860
1863
  });
1861
1864
 
1865
+ //for dropbox
1866
+ // Initialize Dropbox client
1867
+ let dbx = new Dropbox({
1868
+ accessToken: process.env.DROPBOX_ACCESS_TOKEN,
1869
+ refreshToken: process.env.DROPBOX_REFRESH_TOKEN,
1870
+ clientId: process.env.DROPBOX_CLIENT_ID,
1871
+ clientSecret: process.env.DROPBOX_CLIENT_SECRET,
1872
+ fetch: fetch,
1873
+ });
1874
+
1875
+ // Function to refresh access token
1876
+ async function refreshAccessToken() {
1877
+ try {
1878
+ const response = await fetch("https://api.dropbox.com/oauth2/token", {
1879
+ method: "POST",
1880
+ headers: {
1881
+ "Content-Type": "application/x-www-form-urlencoded",
1882
+ },
1883
+ body: new URLSearchParams({
1884
+ grant_type: "refresh_token",
1885
+ refresh_token: process.env.DROPBOX_REFRESH_TOKEN,
1886
+ client_id: process.env.DROPBOX_CLIENT_ID,
1887
+ client_secret: process.env.DROPBOX_CLIENT_SECRET,
1888
+ }),
1889
+ });
1890
+
1891
+ const data = await response.json();
1892
+
1893
+ if (data.access_token) {
1894
+ // Update the access token in the Dropbox client
1895
+ dbx = new Dropbox({
1896
+ accessToken: data.access_token,
1897
+ refreshToken: process.env.DROPBOX_REFRESH_TOKEN,
1898
+ clientId: process.env.DROPBOX_CLIENT_ID,
1899
+ clientSecret: process.env.DROPBOX_CLIENT_SECRET,
1900
+ fetch: fetch,
1901
+ });
1902
+
1903
+ // Update the .env file with the new access token
1904
+ const envContent = fs.readFileSync(`${dirRoot}/.env`, "utf8");
1905
+ const updatedEnv = envContent.replace(
1906
+ /DROPBOX_ACCESS_TOKEN=.*/,
1907
+ `DROPBOX_ACCESS_TOKEN=${data.access_token}`
1908
+ );
1909
+ fs.writeFileSync(`${dirRoot}/.env`, updatedEnv);
1910
+
1911
+ return data.access_token;
1912
+ } else {
1913
+ throw new Error("Failed to refresh access token");
1914
+ }
1915
+ } catch (error) {
1916
+ console.error("Error refreshing access token:", error);
1917
+ throw error;
1918
+ }
1919
+ }
1920
+
1921
+ // Middleware to handle token refresh
1922
+ async function handleTokenRefresh(req, res, next) {
1923
+ try {
1924
+ // Try to make a test API call
1925
+ await dbx.usersGetCurrentAccount();
1926
+ next();
1927
+ } catch (error) {
1928
+ if (error.status === 401) {
1929
+ try {
1930
+ // Token expired, try to refresh it
1931
+ await refreshAccessToken();
1932
+ next();
1933
+ } catch (refreshError) {
1934
+ res
1935
+ .status(401)
1936
+ .json({ error: "Authentication failed. Please re-authenticate." });
1937
+ }
1938
+ } else {
1939
+ next(error);
1940
+ }
1941
+ }
1942
+ }
1943
+
1944
+ // Serve static files
1945
+ //app.use(express.static('public'));
1946
+ // Create test folder if it doesn't exist
1947
+ //dir = '/test'
1948
+ async function ensureFolder(dir) {
1949
+ try {
1950
+ await dbx.filesCreateFolderV2({
1951
+ path: dir,
1952
+ autorename: false,
1953
+ });
1954
+ } catch (error) {
1955
+ if (error.status !== 409) {
1956
+ // 409 means folder already exists
1957
+ throw error;
1958
+ }
1959
+ }
1960
+ }
1961
+
1962
+ // Function to delay execution
1963
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1964
+
1965
+ // Upload endpoint
1966
+ router.post("/zdropbox/:table/:field", handleTokenRefresh, async (req, res) => {
1967
+ try {
1968
+ if (!req.files || !req.files.file) {
1969
+ return res.status(400).json({ error: "No file uploaded" });
1970
+ }
1971
+
1972
+ const userId = res.locals.userId;
1973
+ const table = req.params.table;
1974
+ const field = req.params.field;
1975
+ const file = req.files.file;
1976
+ const fileName = file.name;
1977
+ //ensure folder
1978
+ const dir = `/temps/${table}/${field}/${userId}`;
1979
+ await ensureFolder(dir);
1980
+ const filePath = `${dir}/${fileName}`;
1981
+
1982
+ console.log("Uploading file to path:", filePath);
1983
+ console.log("File size:", file.size);
1984
+ console.log("File name:", fileName);
1985
+
1986
+ const response = await dbx.filesUpload({
1987
+ path: filePath,
1988
+ contents: file.data,
1989
+ mode: { ".tag": "add" },
1990
+ autorename: true,
1991
+ });
1992
+ res.json("ok");
1993
+ } catch (error) {
1994
+ console.error("Upload error:", error);
1995
+ console.error("Error details:", {
1996
+ message: error.message,
1997
+ stack: error.stack,
1998
+ response: error.response,
1999
+ });
2000
+ res.status(500).json({
2001
+ error: "Failed to upload file",
2002
+ details: error.message,
2003
+ });
2004
+ }
2005
+ });
2006
+
2007
+ router.post("/zdropbox-attributes", handleTokenRefresh, async (req, res) => {
2008
+ try {
2009
+ let userId = res.locals.userId;
2010
+ let dir = `${dirRoot}/public/zdropzone/${userId}`;
2011
+ if (!fs.existsSync(dir)) {
2012
+ fs.mkdirSync(dir, { recursive: true });
2013
+ }
2014
+ let body = req.body;
2015
+ let category = body.category;
2016
+ let name = `dropbox__${userId}__${body.table}__${body.field}__${body.type}`;
2017
+ //dropzone__${res.locals.userId}__${table}__${key}__create
2018
+ let arr = myCache.has(name) ? myCache.get(name) : [];
2019
+ if (category === "add") {
2020
+ arr.push(body.file);
2021
+ } else {
2022
+ name = `dropzone__${userId}__${body.table}__${body.field}__${body.type}`;
2023
+ if (myCache.has(name)) {
2024
+ arr = myCache.get(name);
2025
+ }
2026
+ arr = Util.arrayDelete(arr, body.file);
2027
+ }
2028
+ myCache.set(name, arr);
2029
+ res.json("ok");
2030
+ } catch (e) {
2031
+ console.log(e);
2032
+ res.status(500).send(e + "");
2033
+ }
2034
+ });
2035
+
2036
+ //get all files and meta in dropbox
2037
+ router.post("/zdropbox-files", handleTokenRefresh, async (req, res) => {
2038
+ let datas = [];
2039
+ const room = res.locals.token;
2040
+ try {
2041
+ const { files, table, field } = req.body;
2042
+ let dir = `/${table}/${field}`;
2043
+ for (file of files) {
2044
+ let pathFile = `${dir}/${file.fileName}`;
2045
+ //console.log(pathFile)
2046
+ try {
2047
+ const metadata = await dbx.filesGetMetadata({
2048
+ path: pathFile,
2049
+ });
2050
+ let link = ``;
2051
+ try {
2052
+ const response = await dbx.filesGetTemporaryLink({
2053
+ path: pathFile,
2054
+ });
2055
+ link = response.result.link;
2056
+ } catch (error) {
2057
+ console.error("Error getting temporary link:", error);
2058
+ io.to(room).emit(
2059
+ "errormessage",
2060
+ `Error getting temporary link: ${error.message}`
2061
+ );
2062
+ }
2063
+
2064
+ const mockFile = {
2065
+ name: metadata.result.name,
2066
+ id: metadata.result,
2067
+ path: metadata.result.path_display,
2068
+ link: link,
2069
+ isImage: metadata.result.name.match(/\.(jpg|jpeg|png|gif)$/i),
2070
+ size: metadata.result.size,
2071
+ modified: metadata.result.server_modified,
2072
+ accepted: true,
2073
+ };
2074
+ //console.log(mockFile)
2075
+ datas.push(mockFile);
2076
+ } catch (e) {
2077
+ console.log(e);
2078
+ io.to(room).emit(
2079
+ "errormessage",
2080
+ `${e.message} Error ${pathFile} not exist in dropbox`
2081
+ );
2082
+ }
2083
+ }
2084
+ } catch (e) {
2085
+ console.log(e);
2086
+ res.status(500).send(e + "");
2087
+ }
2088
+ res.json(datas);
2089
+ });
2090
+
2091
+ // Delete file
2092
+ router.post("/zdropbox-delete/", handleTokenRefresh, async (req, res) => {
2093
+ try {
2094
+ let body = req.body;
2095
+ let path = body.path;
2096
+ const filePath = decodeURIComponent(req.params.path);
2097
+ await dbx.filesDeleteV2({
2098
+ path: filePath,
2099
+ });
2100
+ res.json({ success: true });
2101
+ } catch (error) {
2102
+ console.error("Error deleting file:", error);
2103
+ res.status(500).json({ error: "Error deleting file" });
2104
+ }
2105
+ });
2106
+
2107
+ // Endpoint to check token status
2108
+ router.get("/zdropbox-check-token", handleTokenRefresh, async (req, res) => {
2109
+ try {
2110
+ await dbx.usersGetCurrentAccount();
2111
+ res.json({ status: "valid" });
2112
+ } catch (error) {
2113
+ res.status(401).json({ status: "invalid" });
2114
+ }
2115
+ });
2116
+
2117
+ // Get temporary link for a file
2118
+ router.post("/zdropbox-get-temp-link", handleTokenRefresh, async (req, res) => {
2119
+ try {
2120
+ const response = await dbx.filesGetTemporaryLink({
2121
+ path: req.body.path,
2122
+ });
2123
+ res.json({ link: response.result.link });
2124
+ } catch (error) {
2125
+ console.error("Error getting temporary link:", error);
2126
+ res.status(500).json({ error: "Error getting temporary link" });
2127
+ }
2128
+ });
2129
+
2130
+ router.get(
2131
+ "/zdropbox-view/:table/:field/:item",
2132
+ handleTokenRefresh,
2133
+ async (req, res) => {
2134
+ try {
2135
+ let item = req.params.item;
2136
+ item = item.substring(13);
2137
+ let filePath = `/${req.params.table}/${req.params.field}/${req.params.item}`;
2138
+ const response = await dbx.filesGetTemporaryLink({
2139
+ path: filePath,
2140
+ });
2141
+ res.send(`<img src="${response.result.link}">`);
2142
+ } catch (e) {
2143
+ console.log(e);
2144
+ res.send(e);
2145
+ }
2146
+ }
2147
+ );
2148
+
1862
2149
  module.exports = router;