Skip to content

Commit

Permalink
feat: add link expiration
Browse files Browse the repository at this point in the history
  • Loading branch information
poeti8 committed Aug 4, 2020
1 parent feb14fa commit 00fc1fa
Show file tree
Hide file tree
Showing 14 changed files with 204 additions and 37 deletions.
55 changes: 49 additions & 6 deletions client/components/LinksTable.tsx
Expand Up @@ -8,6 +8,8 @@ import { ifProp } from "styled-tools";
import getConfig from "next/config";
import QRCode from "qrcode.react";
import Link from "next/link";
import differenceInMilliseconds from "date-fns/differenceInMilliseconds";
import ms from "ms";

import { removeProtocol, withComma, errorMessage } from "../utils";
import { useStoreActions, useStoreState } from "../store";
Expand Down Expand Up @@ -112,7 +114,8 @@ interface BanForm {
interface EditForm {
target: string;
address: string;
description: string;
description?: string;
expire_in?: string;
}

const Row: FC<RowProps> = ({ index, link, setDeleteModal }) => {
Expand All @@ -124,7 +127,12 @@ const Row: FC<RowProps> = ({ index, link, setDeleteModal }) => {
{
target: link.target,
address: link.address,
description: link.description
description: link.description,
expire_in: link.expire_in
? ms(differenceInMilliseconds(new Date(link.expire_in), new Date()), {
long: true
})
: ""
},
{ withIds: true }
);
Expand Down Expand Up @@ -189,9 +197,20 @@ const Row: FC<RowProps> = ({ index, link, setDeleteModal }) => {
)}
</Col>
</Td>
<Td {...createdFlex}>{`${formatDistanceToNow(
new Date(link.created_at)
)} ago`}</Td>
<Td {...createdFlex} flexDirection="column" alignItems="flex-start">
<Text>{formatDistanceToNow(new Date(link.created_at))} ago</Text>
{link.expire_in && (
<Text fontSize={[13, 14]} color="#888">
Expires in{" "}
{ms(
differenceInMilliseconds(new Date(link.expire_in), new Date()),
{
long: true
}
)}
</Text>
)}
</Td>
<Td {...shortLinkFlex} withFade>
{copied ? (
<Animation
Expand Down Expand Up @@ -362,7 +381,7 @@ const Row: FC<RowProps> = ({ index, link, setDeleteModal }) => {
</Col>
</Flex>
<Flex alignItems="flex-start" width={1} mt={3}>
<Col alignItems="flex-start">
<Col alignItems="flex-start" mr={3}>
<Text
{...label("description")}
as="label"
Expand All @@ -386,6 +405,30 @@ const Row: FC<RowProps> = ({ index, link, setDeleteModal }) => {
/>
</Flex>
</Col>
<Col alignItems="flex-start">
<Text
{...label("expire_in")}
as="label"
mb={2}
fontSize={[14, 15]}
bold
>
Expire in:
</Text>
<Flex as="form">
<TextInput
{...text("expire_in")}
placeholder="2 minutes/hours/days"
placeholderSize={[13, 14]}
fontSize={[14, 15]}
height={[40, 44]}
width={[1, 210, 240]}
pl={[3, 24]}
pr={[3, 24]}
required
/>
</Flex>
</Col>
</Flex>
<Button
color="blue"
Expand Down
32 changes: 28 additions & 4 deletions client/components/Shortener.tsx
Expand Up @@ -55,6 +55,7 @@ interface Form {
customurl?: string;
password?: string;
description?: string;
expire_in?: string;
showAdvanced?: boolean;
}

Expand Down Expand Up @@ -256,7 +257,7 @@ const Shortener = () => {
mb={2}
bold
>
Domain
Domain:
</Text>
<Select
{...select("domain")}
Expand Down Expand Up @@ -323,15 +324,38 @@ const Shortener = () => {
</Col>
</Flex>
<Flex mt={[3]} flexDirection={["column", "row"]}>
<Col width={1}>
<Col>
<Text
as="description"
as="label"
{...label("expire_in")}
fontSize={[14, 15]}
mb={2}
bold
>
Expire in:
</Text>
<TextInput
{...text("expire_in")}
placeholder="2 minutes/hours/days"
data-lpignore
pl={[3, 24]}
pr={[3, 24]}
placeholderSize={[13, 14]}
fontSize={[14, 15]}
height={[40, 44]}
width={[1, 210, 240]}
maxWidth="100%"
/>
</Col>
<Col width={2 / 3} ml={[0, 26]}>
<Text
as="label"
{...label("description")}
fontSize={[14, 15]}
mb={2}
bold
>
Description
Description:
</Text>
<TextInput
{...text("description")}
Expand Down
2 changes: 2 additions & 0 deletions client/consts/consts.ts
Expand Up @@ -47,6 +47,8 @@ export enum Colors {
TableHeadBg = "hsl(200, 12%, 95%)",
TableHeadBorder = "hsl(200, 14%, 94%)",
TableRowHover = "hsl(200, 14%, 98%)",
TableRowBanned = "hsl(0, 100%, 98%)",
TableRowBannedHower = "hsl(0, 100%, 96%)",
TableShadow = "hsla(200, 20%, 70%, 0.3)",
Text = "hsl(200, 35%, 25%)",
TrashIcon = "hsl(0, 100%, 69%)",
Expand Down
4 changes: 3 additions & 1 deletion client/store/links.ts
Expand Up @@ -16,6 +16,7 @@ export interface Link {
domain_id?: number;
password?: string;
description?: string;
expire_in?: string;
target: string;
updated_at: string;
user_id?: number;
Expand Down Expand Up @@ -43,7 +44,8 @@ export interface EditLink {
id: string;
target: string;
address: string;
description: string;
description?: string;
expire_in?: string;
}

export interface LinksQuery {
Expand Down
12 changes: 12 additions & 0 deletions docs/api/api.ts
Expand Up @@ -524,6 +524,10 @@ export default {
description: {
type: "string"
},
expire_in: {
type: "string",
example: "2 minutes/hours/days"
},
password: {
type: "string"
},
Expand All @@ -547,12 +551,20 @@ export default {
}
},
body_1: {
required: ["target", "address"],
properties: {
target: {
type: "string"
},
address: {
type: "string"
},
description: {
type: "string"
},
expire_in: {
type: "string",
example: "2 minutes/hours/days"
}
}
},
Expand Down
7 changes: 4 additions & 3 deletions global.d.ts
Expand Up @@ -69,14 +69,15 @@ interface IP {
}

interface Link {
id: number;
address: string;
banned: boolean;
banned_by_id?: number;
banned: boolean;
created_at: string;
description?: string;
domain_id?: number;
expire_in: string;
id: number;
password?: string;
description?: string;
target: string;
updated_at: string;
user_id?: number;
Expand Down
36 changes: 18 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions server/cron.ts
Expand Up @@ -8,3 +8,9 @@ if (env.NON_USER_COOLDOWN) {
query.ip.clear().catch();
});
}

cron.schedule("*/15 * * * * *", () => {
query.link
.batchRemove({ expire_in: ["<", new Date().toISOString()] })
.catch();
});

1 comment on commit 00fc1fa

@poeti8
Copy link
Member Author

@poeti8 poeti8 commented on 00fc1fa Aug 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolves #68 and #43.

Please sign in to comment.