mirror of
https://github.com/dec0dOS/zero-ui.git
synced 2025-08-19 13:01:30 -07:00
feat: add file download support
feat: backend: new api to download file such as planet /PROJECT/frontend/down_folder/ http://locahost:4000/downfile/:downfilename feat: frontend: add file download component for ease use Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
This commit is contained in:
parent
96fd0b70aa
commit
17bf258ea1
7 changed files with 147 additions and 0 deletions
|
@ -12,6 +12,7 @@ const authRoutes = require("./routes/auth");
|
|||
const networkRoutes = require("./routes/network");
|
||||
const memberRoutes = require("./routes/member");
|
||||
const controllerRoutes = require("./routes/controller");
|
||||
const downFileRoutes = require("./routes/downfile");
|
||||
|
||||
const app = express();
|
||||
|
||||
|
@ -64,6 +65,7 @@ routerController.use("", controllerRoutes);
|
|||
app.use("/auth", authRoutes);
|
||||
app.use("/api", routerAPI); // offical SaaS API compatible
|
||||
app.use("/controller", routerController); // other controller-specific routes
|
||||
app.use("/downfile", downFileRoutes); // file download routes
|
||||
|
||||
// error handlers
|
||||
app.get("*", async function (req, res) {
|
||||
|
|
21
backend/routes/downfile.js
Normal file
21
backend/routes/downfile.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
const express = require("express");
|
||||
const path = require("path");
|
||||
const router = express.Router();
|
||||
|
||||
const auth = require("../services/auth");
|
||||
|
||||
router.get("/:downfilename", async function (req, res) {
|
||||
const ret = await auth.isUserLoggedIn(req);
|
||||
if (ret) {
|
||||
const filename = req.params.downfilename;
|
||||
res.sendFile(
|
||||
path.join(__dirname, "..", "..", "frontend", "down_folder", filename)
|
||||
);
|
||||
} else {
|
||||
res
|
||||
.status(401)
|
||||
.json({ error: "401 Not authorized, must Login to download" });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
|
@ -35,3 +35,16 @@ async function isAuthorized(req, res, next) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.isUserLoggedIn = isUserLoggedIn;
|
||||
async function isUserLoggedIn(req) {
|
||||
if (process.env.ZU_DISABLE_AUTH === "true") {
|
||||
// assuming logged in
|
||||
return true;
|
||||
}
|
||||
if (!req.token) {
|
||||
return false;
|
||||
}
|
||||
const user = await db.get("users").find({ token: req.token }).value();
|
||||
return !!user ? true : false;
|
||||
}
|
||||
|
|
0
frontend/down_folder/.keep
Normal file
0
frontend/down_folder/.keep
Normal file
|
@ -5,6 +5,7 @@ import { Divider, Button, Grid, Typography, Box } from "@material-ui/core";
|
|||
import useStyles from "./HomeLoggedIn.styles";
|
||||
|
||||
import NetworkButton from "./components/NetworkButton";
|
||||
import DownloadFile from "./components/DownloadFile";
|
||||
|
||||
import API from "utils/API";
|
||||
import { generateNetworkConfig } from "utils/NetworkConfig";
|
||||
|
@ -40,6 +41,8 @@ function HomeLoggedIn() {
|
|||
>
|
||||
Create A Network
|
||||
</Button>
|
||||
<Divider orientation="vertical" />
|
||||
<DownloadFile />
|
||||
<Divider />
|
||||
<Grid container spacing={3} className={classes.container}>
|
||||
<Grid item xs={6}>
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
import { useState } from "react";
|
||||
import { useLocalStorage } from "react-use";
|
||||
import { TextField, Button, Snackbar } from "@material-ui/core";
|
||||
|
||||
import axios from "axios";
|
||||
|
||||
function DownloadFile() {
|
||||
const [snackbarOpen, setSnackbarOpen] = useState(false);
|
||||
|
||||
const [filename, setFilename] = useState("planet");
|
||||
const [errormsg, setErrormsg] = useState("");
|
||||
|
||||
const [token] = useLocalStorage("token", null);
|
||||
|
||||
const downloadFile = async (fileName) => {
|
||||
if (!!!token) {
|
||||
await handleDownFileErr(`Invalid token`);
|
||||
return;
|
||||
}
|
||||
if (typeof filename === "undefined" || filename.length === 0) {
|
||||
await handleDownFileErr(`Invalid file name [${filename}]`);
|
||||
return;
|
||||
}
|
||||
let ret;
|
||||
ret = await axios
|
||||
.create({
|
||||
baseURL: `/downfile/`,
|
||||
responseType: "arraybuffer",
|
||||
withCredentials: "true",
|
||||
headers:
|
||||
localStorage.getItem("disableAuth") === "true"
|
||||
? {}
|
||||
: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
})
|
||||
.get(`${fileName}`)
|
||||
.then((resp) => {
|
||||
const blobUrl = window.URL.createObjectURL(
|
||||
new Blob([resp.data], { type: "application/octet-stream" })
|
||||
);
|
||||
const tmpLink = document.createElement("a");
|
||||
tmpLink.style.display = "none";
|
||||
tmpLink.href = blobUrl;
|
||||
tmpLink.setAttribute("download", `${fileName}`);
|
||||
if (typeof tmpLink.download === "undefined") {
|
||||
tmpLink.setAttribute("target", "_blank");
|
||||
}
|
||||
document.body.appendChild(tmpLink);
|
||||
tmpLink.click();
|
||||
document.body.removeChild(tmpLink);
|
||||
window.URL.revokeObjectURL(blobUrl);
|
||||
})
|
||||
.catch(async (e) => {
|
||||
let errmsg = `downfile(${fileName}): ${e}: ${ret}`;
|
||||
await handleDownFileErr(errmsg);
|
||||
});
|
||||
};
|
||||
|
||||
const handleDownFileBtnClick = async () => {
|
||||
await downloadFile(filename);
|
||||
};
|
||||
|
||||
const handleDownFileErr = async (errormsg) => {
|
||||
setErrormsg(errormsg);
|
||||
setSnackbarOpen(true);
|
||||
let sleep = function (ms) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
};
|
||||
await sleep(3 * 1000);
|
||||
setSnackbarOpen(false);
|
||||
setErrormsg("");
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<TextField
|
||||
value={filename}
|
||||
onChange={(e) => {
|
||||
setFilename(e.target.value);
|
||||
}}
|
||||
margin="dense"
|
||||
label="File name to download"
|
||||
type="text"
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleDownFileBtnClick}
|
||||
>
|
||||
Download file
|
||||
</Button>
|
||||
<Snackbar
|
||||
open={snackbarOpen}
|
||||
anchorOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
}}
|
||||
message={errormsg}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default DownloadFile;
|
|
@ -0,0 +1 @@
|
|||
export { default } from "./DownloadFile";
|
Loading…
Add table
Add a link
Reference in a new issue