diff --git a/.env.local b/.env.local index 48877f7e..a086b470 100644 --- a/.env.local +++ b/.env.local @@ -1,5 +1,3 @@ - - ACCESS_TOKEN_ENDPOINT = https://login.microsoftonline.com/ //ESNR Tenant TENANT = a8d860de-d5e1-45af-8376-d93f02e6b502 @@ -45,10 +43,10 @@ RELAYPATH = "dev-pedw-hc" GOOGLE_TAG_MANAGER = GTM-T78CBC3 -SHOWLOGIN = "false" -SHOWREPRESENTATIONS = "false" -SHOWFILEUPLOAD = "false" -SHOWMAPS = "false" +SHOWLOGIN = "true" +SHOWREPRESENTATIONS = false +SHOWFILEUPLOAD = "true" +SHOWMAPS = "true" //BASIC_AUTH_CREDENTIALS = pinswg:password|pinswg2:password2 @@ -89,3 +87,13 @@ NEXTAUTH_URL=http://localhost:3000 NEXTAUTH_URL_INTERNAL=http://localhost:3000 DATABASE_URL=mysql://nextAuthAdmin:!Sky9fish1972@77.68.17.157:3306/nextauthDB?synchronise=true SECRET=SuperSecret + + +//Azure Storage Account + +AZURE_CLIENT_ID = $CLIENT_ID +AZURE_TENANT_ID = $TENANT +AZURE_CLIENT_SECRET = $CLIENT_SECRET + +AZURE_PEDW_STORAGE_ENDPOINT = https://pedwdev.blob.core.windows.net +AZURE_PEDW_CONTAINER = "pedwapplications" \ No newline at end of file diff --git a/actions/azurestorage.js b/actions/azurestorage.js new file mode 100644 index 00000000..bdcd8d78 --- /dev/null +++ b/actions/azurestorage.js @@ -0,0 +1,205 @@ +import { v4 as uuidv4 } from "uuid"; +import { BlobServiceClient, ContainerClient } from "@azure/storage-blob"; +import { + DefaultAzureCredential, + InteractiveBrowserCredential, + EnvironmentCredential, + ClientSecretCredential, +} from "@azure/identity"; +import { hashAPIPath } from "."; + +const STORAGE_PATH = process.env.AZURE_PEDW_STORAGE_ENDPOINT; +const STORAGE_CONTAINER = process.env.AZURE_PEDW_CONTAINER; + +export const createContainer = async (containerName) => { + const creds = new DefaultAzureCredential(); + + containerName = containerName.toLowerCase(); + + // console.log( + // "container name:", + // containerName, + // STORAGE_PATH + "/" + containerName + // ); + + const containerClient = new ContainerClient( + `${STORAGE_PATH}/${containerName}`, + creds + ); + + const blobServiceClient = new BlobServiceClient(`${STORAGE_PATH}`, creds); + + const createContainerResponse = await containerClient.createIfNotExists(); + // console.log( + // `Created container ${containerName} successfully`, + // createContainerResponse.requestId + // ); + + // console.log("Containers:"); + // for await (const container of blobServiceClient.listContainers()) { + // console.log(`- ${container.name}`); + // } + + return containerName; +}; + +export const getContainers = async () => { + const creds = new DefaultAzureCredential(); + const blobServiceClient = new BlobServiceClient(`${STORAGE_PATH}`, creds); + + console.log("Containers:"); + for await (const container of blobServiceClient.listContainers()) { + console.log(`- ${container.name}`); + } +}; + +export const getBlobs = async (containerName) => { + const creds = new DefaultAzureCredential(); + + const containerClient = new ContainerClient( + `${STORAGE_PATH}/${containerName}`, + creds + ); + + containerClient.createIfNotExists(); + + const blobObj = []; + for await (const blob of containerClient.listBlobsFlat({ + prefix: "files/", + })) { + let blobDocumentType = blob.name + .split("/")[1] + .slice(0, blob.name.split("/")[1].indexOf("_")); + + blobObj.push({ + "name": blob.name.split("/")[1], + "path": blob.name, + "documentType": blobDocumentType, + "versionId": blob.versionId, + "isCurrentVersion": blob.isCurrentVersion, + "contentLength": blob.properties.contentLength, + "contentType": blob.contentType, + "hashedfilepath": hashAPIPath( + "/api/file/downloadblob?container=" + + containerName.toLowerCase() + + "&blobname=" + + blob.name.split("/")[1] + ), + "hasheddeletepath": hashAPIPath( + "/api/file/deleteblob?container=" + + containerName.toLowerCase() + + "&blobname=" + + blob.name.split("/")[1] + ), + "hashgetblobs": hashAPIPath( + "/api/file/getbloblist?container=" + containerName.toLowerCase() + ), + }); + } + + return blobObj; +}; + +export const createBlob = async (formContent, containerName) => { + const creds = new DefaultAzureCredential(); + + const containerClient = new ContainerClient( + `${STORAGE_PATH}/${containerName}`, + creds + ); + + const content = JSON.stringify(formContent); + const blobName = + formContent.pinswg_name + "_" + new Date().getTime() + ".json"; + const blockBlobClient = containerClient.getBlockBlobClient(blobName); + + const uploadBlobResponse = await blockBlobClient.upload( + content, + Buffer.byteLength(content) + ); + + // console.log("Blobs:"); + // for await (const blob of containerClient.listBlobsByHierarchy("/")) { + // console.log(`- ${blob.name}`); + // } + + return formContent.pinswg_name; +}; + +export const deleteBlob = async (containerName, blobName) => { + const creds = new DefaultAzureCredential(); + + const options = { + deleteSnapshots: "include", // or 'only' + }; + + const containerClient = new ContainerClient( + `${STORAGE_PATH}/${containerName.toLowerCase()}`, + creds + ); + + const blockBlobClient = containerClient.getBlockBlobClient(blobName); + + await blockBlobClient.deleteIfExists(options); + + console.log(`deleted blob ${blobName}`); + + return { "deleted": blobName }; +}; + +export const uploadFile = async (formContent, containerName, foldername) => { + const creds = new DefaultAzureCredential(); + + const containerClient = new ContainerClient( + `${STORAGE_PATH}/${containerName}`, + creds + ); + + const files = formContent; + + //console.log(...formContent); + //console.log("files...", files, files.length); + + for (const prop in files) { + //console.log(`files[${prop}] = ${files[prop][0].size}`); + const blobName = "files/" + files[prop][0].fieldName; + const blockBlobClient = containerClient.getBlockBlobClient(blobName); + const uploadBlobResponse = await blockBlobClient.uploadFile( + files[prop][0].path, + files[prop].size + ); + console.log( + `Uploaded block blob ${files[prop][0].fieldName} successfully`, + uploadBlobResponse.requestId + ); + } +}; + +export const downloadFile = async (containerName, blobName) => { + //console.log.apply(containerName, blobName); + const creds = new DefaultAzureCredential(); + + const containerClient = new ContainerClient( + `${STORAGE_PATH}/${containerName}`, + creds + ); + + const blobClient = containerClient.getBlobClient("files/" + blobName); + const downloadedBlob = await blobClient.download(0); + + const downloaded = await streamToBuffer(downloadedBlob.readableStreamBody); + return downloaded; +}; + +const streamToBuffer = async (readableStream) => { + return new Promise((resolve, reject) => { + const chunks = []; + readableStream.on("data", (data) => { + chunks.push(data instanceof Buffer ? data : Buffer.from(data)); + }); + readableStream.on("end", () => { + resolve(Buffer.concat(chunks)); + }); + readableStream.on("error", reject); + }); +}; diff --git a/actions/govgateway.js b/actions/govgateway.js index cf03784f..0b6e2061 100644 --- a/actions/govgateway.js +++ b/actions/govgateway.js @@ -1,5 +1,5 @@ import axios from "axios"; -import { hashAPIPath } from "./"; +import { hashAPIPath, consoleLogger } from "./"; const configEndpoint = process.env.GG_PROVIDER_CONFIG_ENDPOINT; const ggClientID = process.env.GG_CLIENT_ID; @@ -87,7 +87,9 @@ export const getPortalLogin = (emailAddress, token) => { .get(WEBAPI_URL + queryUrl + hashAPIPath(queryUrl), azureHeaders(token)) .then((res) => res.data) .catch((error) => { - console.log("thiserror", error); + console.log(consoleLogger(error)); + //console.log("thiserror", error); + return JSON.stringify(error); }); }; diff --git a/actions/index.js b/actions/index.js index a57b8827..aa3a0d01 100644 --- a/actions/index.js +++ b/actions/index.js @@ -3,7 +3,7 @@ import https from "https"; import CryptoJS from "crypto-js"; import HmacSHA256 from "crypto-js/hmac-sha256"; import { getFormCollection } from "../components/utils"; - +import { downloadFile } from "./azurestorage"; let BASE_URL; const port = parseInt(process.env.PORT, 10) || 3000; @@ -24,9 +24,17 @@ const WEBAPI_URL = process.env.RELAY_ROOT || "https://dev-pedw-ns.servicebus.windows.net/dev-pedw-hc/"; -const agent = new https.Agent({ - rejectUnauthorized: false, -}); +export const consoleLogger = (err) => { + var errStr = + "///////\nServer Error " + + "\n" + + err.response.status + + " : " + + err.response.statusText + + "\n///////"; + + return errStr; +}; export const getToken = () => { return axios @@ -125,7 +133,6 @@ export const hashAPIPath = (queryPath) => { CryptoJS.enc.Hex.parse(WORDKEY) ); hashlink = hashlink.toString(CryptoJS.enc.Hex); - return (queryPath.indexOf("?") > -1 ? "&hash=" : "?hash=") + hashlink; }; @@ -1029,35 +1036,117 @@ export const createAccount = (formValues) => { }); }; -export const uploadFiles = (formValues) => { - var data = formValues; - var queryUrl = "/api/uploads"; - var config = { +export const uploadFiles = async (formValues, filesObj, uploadhash) => { + let files = filesObj; + + //console.log(formValues); + var formData = new FormData(); + formData.append("appealData", JSON.stringify(formValues)); + + // files.forEach((file) => formData.append("files", file)); + + for (let i = 0; i < files.length; i++) { + for (let j = 0; j < files[i].length; j++) { + console.log(files[i][j].name); + formData.append(files[i][j].name, files[i][j]); + } + } + + //console.log(formData); + + var queryUrl = "/api/file/upload"; + + const config = { method: "post", url: queryUrl, - data: data, + data: formData, + headers: { "content-type": "multipart/form-data" }, }; - // const config = { - // method: "post", - // url: queryUrl, - // data: data, - // headers: { "content-type": "multipart/form-data" }, - // onUploadProgress: (event) => { - // //console.log( - // `Current progress:`, - // Math.round((event.loaded * 100) / event.total) - // ); - // }, - // }; - //console.log(config); - return axios(config) + try { + const res = await axios(config); + return res.data; + } catch (error) { + console.log("this serror", error); + } +}; + +export const getFilesFromBlob = (containerName) => { + return axios + .get( + BASE_URL + + "/api/file/getbloblist?container=" + + containerName.toLowerCase() + + hashAPIPath( + "/api/file/getbloblist?container=" + + containerName.toLowerCase() + ) + ) .then((res) => { - //console.log("posted ", res.data); + //console.log("//////////----", res.data); return res.data; }) .catch((error) => { console.log("this serror", error); }); }; + +export const getFilesFromBlobHashed = (containerName, getblobshash) => { + return axios + .get( + BASE_URL + + "/api/file/getbloblist?container=" + + containerName.toLowerCase() + + getblobshash + ) + .then((res) => { + //console.log("//////////----", res.data); + return res.data; + }) + .catch((error) => { + console.log("this serror", error); + }); +}; + +export const deleteBlob = async (containerName, blobName, deleteblobhash) => { + try { + const res = await axios.get( + BASE_URL + + "/api/file/deleteblob?container=" + + containerName.toLowerCase() + + "&blobname=" + + blobName + + deleteblobhash + ); + return res.data; + } catch (error) { + console.log("this serror", error); + } +}; + +export const downloadBlob = (containerName, blobName) => { + return axios + .get( + BASE_URL + + "/api/file/downloadblob?container=" + + containerName.toLowerCase() + + "&blobname=" + + blobName, + { responseType: "blob" } + ) + .then((response) => { + console.log("Downloaded blob content:www"); + + res.setHeader( + "content-disposition", + "attachment; filename=" + blobName + ); + console.log("has downloaded"); + + return res.status(200).send(response.data); + }) + .catch((error) => { + console.log("this serror", error); + }); +}; diff --git a/components/elements/index.js b/components/elements/index.js index fc653a3c..8e18de07 100644 --- a/components/elements/index.js +++ b/components/elements/index.js @@ -14,6 +14,13 @@ import FileUpload from "../newappeal/fileupload"; import Dropzone, { useDropzone } from "react-dropzone"; import _ from "lodash"; import { connect, useDispatch } from "react-redux"; +import { + getFilesFromBlobHashed, + deleteBlob, + downloadBlob, +} from "../../actions"; +import { setFilesForAppeal } from "../../store/appealType/action"; +import Link from "next/link"; import { addYears, @@ -1057,7 +1064,7 @@ export function NumericField(props) { (showIfHasParentShowValue == parentField) != false && showIfHasParentShowValue; - console.log("parentField:", parentField, showIfHasParentShowValue); + //console.log("parentField:", parentField, showIfHasParentShowValue); return ( <> @@ -1126,7 +1133,7 @@ export function DecimalField(props) { (showIfHasParentShowValue == parentField) != false && showIfHasParentShowValue; - console.log("parentField:", parentField, showIfHasParentShowValue); + //console.log("parentField:", parentField, showIfHasParentShowValue); return ( <> @@ -1246,6 +1253,8 @@ export function FileUploadField(props) { ticketnumber={props.ticketnumber} documentTypeCode={props.documentTypeCode} hint={props.hint} + fileList={props.fileList} + setFilesForAppeal={props.setFilesForAppeal} /> > ); @@ -1277,104 +1286,6 @@ const rejectStyle = { borderColor: "#ff1744", }; -// const RenderFileUpload2 = ({ -// id, -// className, -// rows, -// datafieldname, -// name, -// label, -// input, -// errorMsg, -// meta: { touched, errorStr }, -// ...custom -// }) => { -// const [files, setFiles] = useState([]); - -// const onDrop = useCallback((acceptedFiles, fileRejections, event) => { -// setFiles( -// acceptedFiles.map((file) => -// Object.assign(file, { -// preview: URL.createObjectURL(file), -// }) -// ) -// ); -// console.log(acceptedFiles); -// event.target[acceptedFiles]; -// console.log(event.target.files); -// }, []); - -// const onChange = useCallback((acceptedFiles, fileRejections, event) => { -// setFiles( -// acceptedFiles.map((file) => -// Object.assign(file, { -// preview: URL.createObjectURL(file), -// }) -// ) -// ); -// event.target.files[acceptedFiles]; -// console.log(event.target.files); -// }, []); - -// const { -// getRootProps, -// getInputProps, -// isDragActive, -// isDragAccept, -// isDragReject, -// } = useDropzone({ -// onDrop, -// onChange, -// }); - -// const style = useMemo( -// () => ({ -// ...baseStyle, -// ...(isDragActive ? activeStyle : {}), -// ...(isDragAccept ? acceptStyle : {}), -// ...(isDragReject ? rejectStyle : {}), -// }), -// [isDragActive, isDragReject, isDragAccept] -// ); - -// const thumbs = files.map((file) => ( -//