diff --git a/backend/package.json b/backend/package.json index 0e3aa5bbb..cdc8ad1fb 100644 --- a/backend/package.json +++ b/backend/package.json @@ -6,7 +6,7 @@ "dev": "cross-env NODE_ENV=development nest start --watch", "prod": "prisma migrate deploy && prisma db seed && node dist/src/main", "lint": "eslint 'src/**/*.ts'", - "format": "prettier --write 'src/**/*.ts'", + "format": "prettier --end-of-line=auto --write 'src/**/*.ts'", "test:system": "prisma migrate reset -f && nest start & wait-on http://localhost:8080/api/configs && newman run ./test/newman-system-tests.json" }, "prisma": { diff --git a/backend/src/constants.ts b/backend/src/constants.ts index c812b589a..e00299d5c 100644 --- a/backend/src/constants.ts +++ b/backend/src/constants.ts @@ -1,5 +1,9 @@ export const DATA_DIRECTORY = process.env.DATA_DIRECTORY || "./data"; -export const SHARE_DIRECTORY = `${DATA_DIRECTORY}/uploads/shares` -export const DATABASE_URL = process.env.DATABASE_URL || "file:../data/pingvin-share.db?connection_limit=1"; -export const CLAMAV_HOST = process.env.CLAMAV_HOST || (process.env.NODE_ENV == "docker" ? "clamav" : "127.0.0.1"); -export const CLAMAV_PORT = parseInt(process.env.CLAMAV_PORT) || 3310; \ No newline at end of file +export const SHARE_DIRECTORY = `${DATA_DIRECTORY}/uploads/shares`; +export const DATABASE_URL = + process.env.DATABASE_URL || + "file:../data/pingvin-share.db?connection_limit=1"; +export const CLAMAV_HOST = + process.env.CLAMAV_HOST || + (process.env.NODE_ENV == "docker" ? "clamav" : "127.0.0.1"); +export const CLAMAV_PORT = parseInt(process.env.CLAMAV_PORT) || 3310; diff --git a/backend/src/reverseShare/dto/reverseShare.dto.ts b/backend/src/reverseShare/dto/reverseShare.dto.ts index 863030374..b392b85da 100644 --- a/backend/src/reverseShare/dto/reverseShare.dto.ts +++ b/backend/src/reverseShare/dto/reverseShare.dto.ts @@ -10,6 +10,9 @@ export class ReverseShareDTO { @Expose() shareExpiration: Date; + @Expose() + token: string; + from(partial: Partial) { return plainToClass(ReverseShareDTO, partial, { excludeExtraneousValues: true, diff --git a/backend/src/share/dto/myShare.dto.ts b/backend/src/share/dto/myShare.dto.ts index 8b75883f0..7b5449e9e 100644 --- a/backend/src/share/dto/myShare.dto.ts +++ b/backend/src/share/dto/myShare.dto.ts @@ -1,7 +1,7 @@ import { Expose, plainToClass, Type } from "class-transformer"; import { ShareDTO } from "./share.dto"; -import {FileDTO} from "../../file/dto/file.dto"; -import {OmitType} from "@nestjs/swagger"; +import { FileDTO } from "../../file/dto/file.dto"; +import { OmitType } from "@nestjs/swagger"; export class MyShareDTO extends OmitType(ShareDTO, [ "files", @@ -30,4 +30,4 @@ export class MyShareDTO extends OmitType(ShareDTO, [ plainToClass(MyShareDTO, part, { excludeExtraneousValues: true }) ); } -} \ No newline at end of file +} diff --git a/frontend/package.json b/frontend/package.json index 37079c08c..098744dbc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,7 +6,7 @@ "build": "next build", "start": "next start", "lint": "next lint", - "format": "prettier --write \"src/**/*.ts*\"" + "format": "prettier --end-of-line=auto --write \"src/**/*.ts*\"" }, "dependencies": { "@emotion/react": "^11.10.6", diff --git a/frontend/src/components/account/showReverseShareLinkModal.tsx b/frontend/src/components/account/showReverseShareLinkModal.tsx new file mode 100644 index 000000000..33116b3d5 --- /dev/null +++ b/frontend/src/components/account/showReverseShareLinkModal.tsx @@ -0,0 +1,20 @@ +import { Stack, TextInput } from "@mantine/core"; +import { ModalsContextProps } from "@mantine/modals/lib/context"; + +const showReverseShareLinkModal = ( + modals: ModalsContextProps, + reverseShareToken: string, + appUrl: string +) => { + const link = `${appUrl}/upload/${reverseShareToken}`; + return modals.openModal({ + title: "Reverse share link", + children: ( + + + + ), + }); +}; + +export default showReverseShareLinkModal; diff --git a/frontend/src/components/upload/CopyTextField.tsx b/frontend/src/components/upload/CopyTextField.tsx index 69bf3448d..bdb261446 100644 --- a/frontend/src/components/upload/CopyTextField.tsx +++ b/frontend/src/components/upload/CopyTextField.tsx @@ -1,8 +1,8 @@ -import { useRef, useState } from "react"; -import toast from "../../utils/toast.util"; import { ActionIcon, TextInput } from "@mantine/core"; -import { TbCheck, TbCopy } from "react-icons/tb"; import { useClipboard } from "@mantine/hooks"; +import { useRef, useState } from "react"; +import { TbCheck, TbCopy } from "react-icons/tb"; +import toast from "../../utils/toast.util"; function CopyTextField(props: { link: string }) { const clipboard = useClipboard({ timeout: 500 }); @@ -14,7 +14,7 @@ function CopyTextField(props: { link: string }) { const copyLink = () => { clipboard.copy(props.link); - toast.success("Your link was copied to the keyboard."); + toast.success("The link was copied to your clipboard."); if (timerRef.current) clearTimeout(timerRef.current); timerRef.current = setTimeout(() => { setCheckState(false); diff --git a/frontend/src/components/upload/modals/showCreateUploadModal.tsx b/frontend/src/components/upload/modals/showCreateUploadModal.tsx index c9f5901fb..ae640cf4e 100644 --- a/frontend/src/components/upload/modals/showCreateUploadModal.tsx +++ b/frontend/src/components/upload/modals/showCreateUploadModal.tsx @@ -62,6 +62,10 @@ const CreateUploadModalBody = ({ }) => { const modals = useModals(); + const generatedLink = Buffer.from(Math.random().toString(), "utf8") + .toString("base64") + .substr(10, 7); + const [showNotSignedInAlert, setShowNotSignedInAlert] = useState(true); const validationSchema = yup.object().shape({ @@ -78,7 +82,7 @@ const CreateUploadModalBody = ({ }); const form = useForm({ initialValues: { - link: "", + link: generatedLink, recipients: [] as string[], password: undefined, maxViews: undefined, diff --git a/frontend/src/pages/account/reverseShares.tsx b/frontend/src/pages/account/reverseShares.tsx index 6d8541fc4..0d2b26889 100644 --- a/frontend/src/pages/account/reverseShares.tsx +++ b/frontend/src/pages/account/reverseShares.tsx @@ -1,6 +1,7 @@ import { Accordion, ActionIcon, + Anchor, Box, Button, Center, @@ -16,9 +17,10 @@ import { useModals } from "@mantine/modals"; import moment from "moment"; import { useEffect, useState } from "react"; import { TbInfoCircle, TbLink, TbPlus, TbTrash } from "react-icons/tb"; +import Meta from "../../components/Meta"; +import showReverseShareLinkModal from "../../components/account/showReverseShareLinkModal"; import showShareLinkModal from "../../components/account/showShareLinkModal"; import CenterLoader from "../../components/core/CenterLoader"; -import Meta from "../../components/Meta"; import showCreateReverseShareModal from "../../components/share/modals/showCreateReverseShareModal"; import useConfig from "../../hooks/config.hook"; import shareService from "../../services/share.service"; @@ -34,6 +36,8 @@ const MyShares = () => { const [reverseShares, setReverseShares] = useState(); + const appUrl = config.get("general.appUrl"); + const getReverseShares = () => { shareService .getMyReverseShares() @@ -119,9 +123,14 @@ const MyShares = () => { {reverseShare.shares.map((share) => ( - - {share.id} - + + + {share.id} + + { onClick={() => { if (window.isSecureContext) { clipboard.copy( - `${config.get( - "general.appUrl" - )}/share/${share.id}` + `${appUrl}/share/${share.id}` ); toast.success( "The share link was copied to the keyboard." @@ -165,6 +172,31 @@ const MyShares = () => { + { + if (window.isSecureContext) { + clipboard.copy( + `${config.get("general.appUrl")}/upload/${ + reverseShare.token + }` + ); + toast.success( + "The link was copied to your clipboard." + ); + } else { + showReverseShareLinkModal( + modals, + reverseShare.token, + config.get("general.appUrl") + ); + } + }} + > + + { const modals = useModals(); @@ -122,7 +122,7 @@ const MyShares = () => { }` ); toast.success( - "Your link was copied to the keyboard." + "The link was copied to your clipboard." ); } else { showShareLinkModal( diff --git a/frontend/src/types/share.type.ts b/frontend/src/types/share.type.ts index 5e910119a..55f04ebb6 100644 --- a/frontend/src/types/share.type.ts +++ b/frontend/src/types/share.type.ts @@ -32,6 +32,7 @@ export type MyReverseShare = { maxShareSize: string; shareExpiration: Date; remainingUses: number; + token: string; shares: MyShare[]; }; diff --git a/package.json b/package.json index 85283c695..3b47efc42 100644 --- a/package.json +++ b/package.json @@ -8,5 +8,8 @@ "release:patch": "cd backend && npm version patch --commit-hooks false && cd ../frontend && npm version patch --commit-hooks false && cd .. && git add . && npm version patch --force -m 'release: %s' && git push && git push --tags", "release:minor": "cd backend && npm version minor --commit-hooks false && cd ../frontend && npm version minor --commit-hooks false && cd .. && git add . && npm version minor --force -m 'release: %s' && git push && git push --tags", "deploy:dev": "docker buildx build --push --tag stonith404/pingvin-share:development --platform linux/amd64,linux/arm64 ." + }, + "devDependencies": { + "conventional-changelog-cli": "^3.0.0" } }