Compare commits

...

80 Commits
5.3.4 ... 5.3.6

Author SHA1 Message Date
Athou
cd24e412e3 release 5.3.6 2024-12-02 18:50:14 +01:00
Athou
a073d843ab ignore invalid cache control values (#1619) 2024-12-02 18:43:46 +01:00
renovate[bot]
8ccb59ed18 chore(deps): update dependency vitest to ^2.1.8 2024-12-02 14:56:45 +00:00
renovate[bot]
e6dc7d2d0d chore(deps): lock file maintenance 2024-12-02 03:59:25 +00:00
Athou
f7b21ca3f6 release 5.3.5 2024-12-02 04:57:26 +01:00
Athou
df3a1bcdb6 update changelog 2024-12-02 04:54:58 +01:00
renovate[bot]
5bec494a7c fix(deps): update dependency org.jsoup:jsoup to v1.18.3 2024-12-02 03:18:47 +00:00
renovate[bot]
d8eef4dd9f chore(deps): lock file maintenance 2024-12-02 02:00:17 +00:00
renovate[bot]
d80138caf3 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.20.2 2024-12-01 06:04:51 +00:00
Athou
d26c103aa5 migrate to markdown documentation 2024-12-01 06:04:08 +01:00
Athou
249231f57e add support for JDK 23 compilation (#1618) 2024-12-01 05:43:35 +01:00
Athou
7a838cddad honor Cache-Control response header (#1615) 2024-11-29 17:06:57 +01:00
renovate[bot]
477f2cd6db fix(deps): update dependency io.quarkus.platform:quarkus-bom to v3.17.2 2024-11-29 13:10:54 +00:00
Athou
9915f05f73 remove lingui warnings 2024-11-29 14:08:25 +01:00
Athou
0a16bb2fba if width is specified, keep images aspect ratio (#1595) 2024-11-29 13:30:48 +01:00
Jérémie Panzer
3d4faf2406 Merge pull request #1616 from Athou/renovate/major-linguijs-monorepo
chore(deps): update linguijs monorepo to v5 (major)
2024-11-29 07:42:28 +01:00
Jérémie Panzer
63de6fe833 Merge pull request #1617 from Athou/renovate/reduxjs-toolkit-2.x
fix(deps): update dependency @reduxjs/toolkit to ^2.4.0
2024-11-29 07:42:17 +01:00
renovate[bot]
9c6219a58a fix(deps): update dependency @reduxjs/toolkit to ^2.4.0 2024-11-28 22:00:49 +00:00
renovate[bot]
3e664d4287 chore(deps): update linguijs monorepo to v5 2024-11-28 19:15:26 +00:00
renovate[bot]
4c4ffd84f3 chore(deps): update linguijs monorepo to ^4.14.1 2024-11-28 15:13:09 +00:00
renovate[bot]
f555f0e392 fix(deps): update mantine monorepo to ^7.14.3 2024-11-28 14:43:41 +00:00
renovate[bot]
124166738b fix(deps): update dependency io.dropwizard.metrics:metrics-json to v4.2.29 2024-11-28 09:55:36 +00:00
Jérémie Panzer
8b32dcc576 Merge pull request #1614 from Athou/renovate/quarkus.version
fix(deps): update dependency io.quarkus.platform:quarkus-bom to v3.17.0
2024-11-27 16:13:19 +01:00
renovate[bot]
105651215a fix(deps): update dependency io.quarkus.platform:quarkus-bom to v3.17.0 2024-11-27 14:52:32 +00:00
renovate[bot]
d9c6cbd072 fix(deps): update dependency org.jsoup:jsoup to v1.18.2 2024-11-27 13:00:42 +00:00
renovate[bot]
b4c52e06fe chore(deps): update dependency vitest to ^2.1.6 2024-11-27 11:35:05 +00:00
Athou
2565dfe528 remove workaround because quarkus.http.auth.form.cookie-max-age is now available 2024-11-27 10:05:26 +01:00
Athou
b5036c9148 Merge branch 'renovate/quarkus.version' 2024-11-27 10:00:53 +01:00
renovate[bot]
e2c8ddb8f7 chore(deps): update quarkus.version to v3.16.4 2024-11-27 10:00:32 +01:00
renovate[bot]
85fbd284fa chore(deps): update dependency @vitejs/plugin-react to ^4.3.4 2024-11-26 11:15:33 +00:00
renovate[bot]
559fb69a64 fix(deps): update dependency axios to ^1.7.8 2024-11-25 23:25:26 +00:00
renovate[bot]
054c76716a chore(deps): lock file maintenance 2024-11-25 00:49:27 +00:00
renovate[bot]
ba17c9350f fix(deps): update mantine monorepo to ^7.14.2 2024-11-24 14:33:06 +00:00
Jérémie Panzer
781015eea4 Merge pull request #1608 from Athou/renovate/major-react-router-monorepo
fix(deps): update dependency react-router-dom to v7
2024-11-23 15:40:57 +01:00
Jérémie Panzer
13e5c0e8d2 Merge pull request #1607 from Athou/renovate/com.microsoft.playwright-playwright-1.x
chore(deps): update dependency com.microsoft.playwright:playwright to v1.49.0
2024-11-23 15:40:41 +01:00
Jérémie Panzer
4d88a30848 Merge pull request #1597 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.20.1
2024-11-23 15:40:05 +01:00
Jérémie Panzer
19c03de9e4 Merge pull request #1604 from Athou/renovate/debian-12.x
chore(deps): update debian docker tag to v12.8
2024-11-23 15:39:57 +01:00
Jérémie Panzer
e3169c9f2d Merge pull request #1609 from Athou/renovate/querydsl.version
fix(deps): update querydsl.version to v6.9 (minor)
2024-11-23 15:39:46 +01:00
Jérémie Panzer
e90fb0b56f Merge pull request #1611 from Athou/renovate/typescript-5.x
chore(deps): update dependency typescript to ^5.7.2
2024-11-23 15:39:31 +01:00
renovate[bot]
69607a5122 chore(deps): update dependency typescript to ^5.7.2 2024-11-22 19:13:41 +00:00
renovate[bot]
21eb8e6d9f fix(deps): update dependency react-router-dom to v7 2024-11-22 16:56:53 +00:00
renovate[bot]
a28a6b9dc4 fix(deps): update dependency io.github.openfeign.querydsl:querydsl-jpa to v6.9 2024-11-22 14:10:54 +00:00
renovate[bot]
a9cadbafeb chore(deps): update dependency com.microsoft.playwright:playwright to v1.49.0 2024-11-22 03:47:15 +00:00
renovate[bot]
d491af5a8d chore(deps): update dependency npm to v10.9.1 2024-11-22 00:38:41 +00:00
renovate[bot]
39c7934fb8 fix(deps): update dependency @emotion/react to ^11.13.5 2024-11-20 10:41:11 +00:00
renovate[bot]
76eba8cc63 chore(deps): update dependency vite-tsconfig-paths to ^5.1.3 2024-11-19 23:22:57 +00:00
renovate[bot]
7549ff2491 chore(deps): update dependency @types/tinycon to ^0.6.7 2024-11-19 18:55:08 +00:00
renovate[bot]
66cd18bc4b chore(deps): update dependency io.swagger.core.v3:swagger-maven-plugin-jakarta to v2.2.26 2024-11-19 06:34:58 +00:00
renovate[bot]
44d7a2c340 chore(deps): update dependency io.quarkus.platform:quarkus-maven-plugin to v3.15.2 2024-11-19 02:12:42 +00:00
renovate[bot]
d6ee63a01f chore(deps): update ibm-semeru-runtimes docker tag to open-21.0.5_11-jre 2024-11-18 22:02:31 +00:00
renovate[bot]
a495c9cacd fix(deps): update mantine monorepo to ^7.14.1 2024-11-18 04:24:54 +00:00
renovate[bot]
530185d15c chore(deps): lock file maintenance 2024-11-18 01:29:43 +00:00
renovate[bot]
8dd28c25a7 fix(deps): update dependency org.projectlombok:lombok to v1.18.36 2024-11-15 22:09:25 +00:00
renovate[bot]
50884b236c chore(deps): update dependency vitest to ^2.1.5 2024-11-13 16:06:06 +00:00
renovate[bot]
da9fe09e58 chore(deps): update dependency @types/tinycon to ^0.6.6 2024-11-12 09:54:28 +00:00
renovate[bot]
3c24c9aa7a chore(deps): update debian docker tag to v12.8 2024-11-12 02:04:08 +00:00
renovate[bot]
9d10a4b46f fix(deps): update dependency react-router-dom to ^6.28.0 2024-11-12 02:04:06 +00:00
renovate[bot]
d56ed3bd06 chore(deps): update linguijs monorepo to ^4.14.0 2024-11-11 21:19:20 +00:00
renovate[bot]
41c1c429d0 chore(deps): update dependency vite-tsconfig-paths to ^5.1.2 2024-11-11 19:43:20 +00:00
renovate[bot]
1a3d890b40 chore(deps): lock file maintenance (#1603)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-11 19:42:44 +00:00
renovate[bot]
e3ec9b2ccd chore(deps): update dependency vite to ^5.4.11 2024-11-11 13:43:13 +00:00
renovate[bot]
f69878a242 fix(deps): update mantine monorepo to ^7.13.5 2024-11-09 02:31:03 +00:00
renovate[bot]
ea766706fb chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.20.1 2024-11-07 19:31:05 +00:00
renovate[bot]
306507af80 fix(deps): update dependency react-swipeable to ^7.0.2 2024-11-04 17:47:41 +00:00
renovate[bot]
67084783b2 chore(deps): lock file maintenance 2024-11-04 00:09:27 +00:00
renovate[bot]
7cbb75f717 chore(deps): update dependency org.apache.maven.plugins:maven-surefire-plugin to v3.5.2 2024-11-02 21:48:13 +00:00
renovate[bot]
1c335492d5 chore(deps): update dependency org.apache.maven.plugins:maven-failsafe-plugin to v3.5.2 2024-11-02 20:25:15 +00:00
Jérémie Panzer
de92e74c8e Merge pull request #1594 from Athou/renovate/node-22.x
chore(deps): update dependency node to v22
2024-10-29 18:07:01 +01:00
renovate[bot]
9cbbd30618 chore(deps): update dependency node to v22 2024-10-29 16:43:49 +00:00
Jérémie Panzer
f14f1493c4 Merge pull request #1593 from Athou/renovate/patch-vitest-monorepo
chore(deps): update dependency vitest to ^2.1.4
2024-10-29 00:09:00 +01:00
renovate[bot]
e68c8fdbe1 chore(deps): update dependency vitest to ^2.1.4 2024-10-28 22:13:08 +00:00
renovate[bot]
e094972aa2 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.4.1 2024-10-28 19:56:15 +00:00
renovate[bot]
ff831c6d2b chore(deps): lock file maintenance 2024-10-28 01:19:01 +00:00
Jérémie Panzer
9957cda11a Merge pull request #1592 from Athou/renovate/com.puppycrawl.tools-checkstyle-10.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.19.0
2024-10-26 16:33:49 +02:00
renovate[bot]
6809822000 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v10.19.0 2024-10-26 13:58:03 +00:00
Jérémie Panzer
8048b1a9aa Merge pull request #1591 from Athou/renovate/org.apache.maven.plugins-maven-checkstyle-plugin-3.x
chore(deps): update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.6.0
2024-10-26 05:57:45 +02:00
renovate[bot]
8557bd018a chore(deps): update dependency org.apache.maven.plugins:maven-checkstyle-plugin to v3.6.0 2024-10-25 18:25:58 +00:00
Jérémie Panzer
183d5fd162 Merge pull request #1590 from Athou/renovate/com.ibm.icu-icu4j-76.x
fix(deps): update dependency com.ibm.icu:icu4j to v76
2024-10-25 17:22:54 +02:00
renovate[bot]
411f86fbeb fix(deps): update dependency com.ibm.icu:icu4j to v76 2024-10-25 06:17:19 +00:00
renovate[bot]
5493046f25 fix(deps): update mantine monorepo to ^7.13.4 2024-10-23 18:02:39 +00:00
64 changed files with 2430 additions and 2689 deletions

View File

@@ -1,5 +1,15 @@
# Changelog
## [5.3.6]
- Ignore invalid Cache-Control header values (#1619)
## [5.3.5]
- Fixed an issue with the aspect ratio of images of some feeds (#1595)
- CommaFeed now honors the Cache-Control response header and will not try to refresh a feed sooner than its max-age property (#1615)
- Added support for compilation with JDK 23+. If you're building CommaFeed from sources with a JDK 17 or 21, you may need to update it to the most recent patch version to support `-proc:full` (#1618)
## [5.3.4]
- Added support for Internationalized Domain Names (#1588)

View File

@@ -100,7 +100,7 @@ There are multiple ways to configure CommaFeed:
The properties file is recommended because CommaFeed will be able to warn about invalid properties and typos.
All [CommaFeed settings](commafeed-server/doc/commafeed.adoc) are optional and have sensible default values.
All [CommaFeed settings](commafeed-server/doc/commafeed.md) are optional and have sensible default values.
When logging in, credentials are stored in an encrypted cookie. The encryption key is randomly generated at startup,
meaning that you will have to log back in after each restart of the application. To prevent this, you can set the

File diff suppressed because it is too large Load Diff

View File

@@ -15,20 +15,19 @@
"i18n:extract": "lingui extract --clean"
},
"dependencies": {
"@emotion/react": "^11.13.3",
"@emotion/react": "^11.13.5",
"@fontsource/open-sans": "^5.1.0",
"@lingui/core": "^4.13.0",
"@lingui/macro": "^4.13.0",
"@lingui/react": "^4.13.0",
"@mantine/core": "^7.13.3",
"@mantine/form": "^7.13.3",
"@mantine/hooks": "^7.13.3",
"@mantine/modals": "^7.13.3",
"@mantine/notifications": "^7.13.3",
"@mantine/spotlight": "^7.13.3",
"@lingui/core": "^5.0.0",
"@lingui/react": "^5.0.0",
"@mantine/core": "^7.14.3",
"@mantine/form": "^7.14.3",
"@mantine/hooks": "^7.14.3",
"@mantine/modals": "^7.14.3",
"@mantine/notifications": "^7.14.3",
"@mantine/spotlight": "^7.14.3",
"@monaco-editor/react": "^4.6.0",
"@reduxjs/toolkit": "^2.3.0",
"axios": "^1.7.7",
"@reduxjs/toolkit": "^2.4.0",
"axios": "^1.7.8",
"dayjs": "^1.11.13",
"escape-string-regexp": "^5.0.0",
"interweave": "^13.1.0",
@@ -45,8 +44,8 @@
"react-icons": "^5.3.0",
"react-infinite-scroller": "^1.2.6",
"react-redux": "^9.1.2",
"react-router-dom": "^6.27.0",
"react-swipeable": "^7.0.1",
"react-router-dom": "^7.0.1",
"react-swipeable": "^7.0.2",
"redoc": "^2.2.0",
"style-to-object": "^1.0.8",
"throttle-debounce": "^5.0.2",
@@ -56,8 +55,9 @@
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@lingui/cli": "^4.13.0",
"@lingui/vite-plugin": "^4.13.0",
"@lingui/babel-plugin-lingui-macro": "^5.0.0",
"@lingui/cli": "^5.0.0",
"@lingui/vite-plugin": "^5.0.0",
"@types/mousetrap": "^1.6.15",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
@@ -65,16 +65,16 @@
"@types/react-infinite-scroller": "^1.2.5",
"@types/swagger-ui-react": "^4.18.3",
"@types/throttle-debounce": "^5.0.2",
"@types/tinycon": "^0.6.5",
"@vitejs/plugin-react": "^4.3.3",
"@types/tinycon": "^0.6.7",
"@vitejs/plugin-react": "^4.3.4",
"babel-plugin-macros": "^3.1.0",
"jsdom": "^25.0.1",
"rollup-plugin-visualizer": "^5.12.0",
"typescript": "^5.6.3",
"vite": "^5.4.10",
"typescript": "^5.7.2",
"vite": "^5.4.11",
"vite-plugin-checker": "^0.8.0",
"vite-tsconfig-paths": "^5.0.1",
"vitest": "^2.1.3",
"vite-tsconfig-paths": "^5.1.3",
"vitest": "^2.1.8",
"vitest-mock-extended": "^2.0.2"
}
}

View File

@@ -6,16 +6,16 @@
<parent>
<groupId>com.commafeed</groupId>
<artifactId>commafeed</artifactId>
<version>5.3.4</version>
<version>5.3.6</version>
</parent>
<artifactId>commafeed-client</artifactId>
<name>CommaFeed Client</name>
<properties>
<!-- renovate: datasource=node-version depName=node -->
<node.version>v20.18.0</node.version>
<node.version>v22.11.0</node.version>
<!-- renovate: datasource=npm depName=npm -->
<npm.version>10.9.0</npm.version>
<npm.version>10.9.1</npm.version>
</properties>
<build>

View File

@@ -1,4 +1,4 @@
import { t } from "@lingui/macro"
import { t } from "@lingui/core/macro"
import type { IconType } from "react-icons"
import { FaAt } from "react-icons/fa"
import { SiBuffer, SiFacebook, SiGmail, SiInstapaper, SiPocket, SiTumblr, SiX } from "react-icons/si"

View File

@@ -1,4 +1,4 @@
import { t } from "@lingui/macro"
import { t } from "@lingui/core/macro"
import { showNotification } from "@mantine/notifications"
import { type PayloadAction, createSlice, isAnyOf } from "@reduxjs/toolkit"
import type { LocalSettings, Settings, UserModel, ViewMode } from "app/types"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Alert as MantineAlert } from "@mantine/core"
import { Fragment } from "react"
import { TbAlertCircle, TbAlertTriangle, TbCircleCheck } from "react-icons/tb"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Dialog, Text } from "@mantine/core"
import { useAppDispatch, useAppSelector } from "app/store"
import { setAnnouncementHash } from "app/user/slice"

View File

@@ -70,7 +70,11 @@ export function ImageWithPlaceholderWhileLoading({
width={width}
height={height}
onLoad={() => setLoading(false)}
style={{ ...style, display: loading ? "none" : (style?.display ?? "initial") }}
style={{
...style,
display: loading ? "none" : (style?.display ?? "initial"),
height: style?.width ? "auto" : style?.height,
}}
/>
</>
)

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Kbd, Stack, Table } from "@mantine/core"
import { useOs } from "@mantine/hooks"
import { Constants } from "app/constants"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Tooltip } from "@mantine/core"
import { Constants } from "app/constants"
import dayjs from "dayjs"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Button, Checkbox, Group, PasswordInput, Stack, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Box } from "@mantine/core"
import { openModal } from "@mantine/modals"
import { Constants } from "app/constants"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Group } from "@mantine/core"
import { Constants } from "app/constants"
import { markEntriesUpToEntry, markEntry, starEntry } from "app/entries/thunks"

View File

@@ -1,4 +1,4 @@
import { msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Group, Indicator, Popover, TagsInput } from "@mantine/core"
import { markEntriesUpToEntry, markEntry, starEntry, tagEntry } from "app/entries/thunks"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { ActionIcon, Box, CopyButton, Divider, SimpleGrid } from "@mantine/core"
import { Constants } from "app/constants"
import { useAppSelector } from "app/store"

View File

@@ -1,5 +1,6 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Box, Button, Group, Stack, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"

View File

@@ -1,4 +1,4 @@
import { msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Select, type SelectProps } from "@mantine/core"
import type { ComboboxItem } from "@mantine/core/lib/components/Combobox/Combobox.types"

View File

@@ -1,5 +1,6 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Box, Button, FileInput, Group, Stack } from "@mantine/core"
import { isNotEmpty, useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Button, Group, Stack, Stepper, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { ActionIcon, Anchor, Tooltip } from "@mantine/core"
import { Constants } from "app/constants"
import { markEntry } from "app/entries/thunks"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { ActionIcon, Tooltip } from "@mantine/core"
import { Constants } from "app/constants"
import { starEntry } from "app/entries/thunks"

View File

@@ -1,4 +1,4 @@
import { msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Box, Center, CloseButton, Divider, Group, Indicator, Popover, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"

View File

@@ -1,4 +1,5 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { Trans } from "@lingui/react/macro"
import { Button, Code, Group, Modal, Slider, Stack, Text } from "@mantine/core"
import { markAllEntries } from "app/entries/thunks"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import {
Box,
Divider,

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Button, Group, Stack } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"

View File

@@ -1,5 +1,6 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Divider, Group, NumberInput, Radio, Select, SimpleGrid, Stack, Switch } from "@mantine/core"
import type { ComboboxData } from "@mantine/core/lib/components/Combobox/Combobox.types"
import { Constants } from "app/constants"

View File

@@ -1,5 +1,6 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Button, Checkbox, Divider, Group, Input, PasswordInput, Stack, Text, TextInput } from "@mantine/core"
import { useForm } from "@mantine/form"
import { openConfirmModal } from "@mantine/modals"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Stack } from "@mantine/core"
import { Constants } from "app/constants"
import {

View File

@@ -1,5 +1,6 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { TextInput } from "@mantine/core"
import { Spotlight, type SpotlightActionData, spotlight } from "@mantine/spotlight"
import { redirectToFeed } from "app/redirect/thunks"

View File

@@ -1,4 +1,4 @@
import { msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { useAppSelector } from "app/store"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Box, Button, Container, Group, Text, Title } from "@mantine/core"
import { TbRefresh } from "react-icons/tb"
import { tss } from "tss"

View File

@@ -1,4 +1,4 @@
import { msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { Anchor, Box, Center, Container, Divider, Group, Image, Space, Title, useMantineColorScheme } from "@mantine/core"
import { client } from "app/client"
import { redirectToApiDocumentation, redirectToLogin, redirectToRegistration, redirectToRootCategory } from "app/redirect/thunks"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { ActionIcon, Box, Code, Container, Group, Table, Text, Title, useMantineTheme } from "@mantine/core"
import { closeAllModals, openConfirmModal, openModal } from "@mantine/modals"
import { client, errorToStrings } from "app/client"

View File

@@ -1,5 +1,6 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Container, List, NativeSelect, SimpleGrid, Title } from "@mantine/core"
import { Constants } from "app/constants"
import { redirectToApiDocumentation } from "app/redirect/thunks"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Container, Tabs } from "@mantine/core"
import { AddCategory } from "components/content/add/AddCategory"
import { ImportOpml } from "components/content/add/ImportOpml"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Button, Code, Container, Divider, Group, Input, NumberInput, Stack, Text, TextInput, Title } from "@mantine/core"
import { useForm } from "@mantine/form"
import { openConfirmModal } from "@mantine/modals"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Code, Container, Group, List, Title } from "@mantine/core"
import { Constants } from "app/constants"
import React from "react"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Button, Code, Container, Divider, Group, Input, NumberInput, Stack, Text, TextInput, Title } from "@mantine/core"
import { useForm } from "@mantine/form"
import { openConfirmModal } from "@mantine/modals"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { ActionIcon, Box, Center, Divider, Group, Title, useMantineTheme } from "@mantine/core"
import { useViewportSize } from "@mantine/hooks"
import { Constants } from "app/constants"

View File

@@ -1,4 +1,4 @@
import { msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { ActionIcon, AppShell, Box, Center, Group, ScrollArea, Title, useMantineTheme } from "@mantine/core"
import { Constants } from "app/constants"
import { redirectToAdd, redirectToRootCategory } from "app/redirect/thunks"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Container, Tabs } from "@mantine/core"
import { CustomCodeSettings } from "components/settings/CustomCodeSettings"
import { DisplaySettings } from "components/settings/DisplaySettings"

View File

@@ -1,4 +1,4 @@
import { Trans } from "@lingui/macro"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Button, Container, Group, Input, Stack, Title } from "@mantine/core"
import { Constants } from "app/constants"

View File

@@ -1,5 +1,6 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Button, Center, Container, Group, Paper, PasswordInput, Stack, TextInput, Title } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"

View File

@@ -1,5 +1,6 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Button, Center, Container, Group, Paper, Stack, TextInput, Title } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"

View File

@@ -1,5 +1,6 @@
import { Trans, msg } from "@lingui/macro"
import { msg } from "@lingui/core/macro"
import { useLingui } from "@lingui/react"
import { Trans } from "@lingui/react/macro"
import { Anchor, Box, Button, Center, Container, Group, Paper, PasswordInput, Stack, TextInput, Title } from "@mantine/core"
import { useForm } from "@mantine/form"
import { client, errorToStrings } from "app/client"

View File

@@ -10,8 +10,7 @@ export default defineConfig(() => ({
plugins: [
react({
babel: {
// babel-macro is needed for lingui
plugins: ["macros"],
plugins: ["@lingui/babel-plugin-lingui-macro"],
},
}),
lingui(),

View File

@@ -1,690 +0,0 @@
:summaryTableId: commafeed-server_commafeed
[.configuration-legend]
icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime
[.configuration-reference.searchable, cols="80,.^10,.^10"]
|===
h|[.header-title]##Configuration property##
h|Type
h|Default
a| [[commafeed-server_commafeed-hide-from-web-crawlers]] [.property-path]##link:#commafeed-server_commafeed-hide-from-web-crawlers[`commafeed.hide-from-web-crawlers`]##
[.description]
--
Whether to expose a robots.txt file that disallows web crawlers and search engine indexers.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HIDE_FROM_WEB_CRAWLERS+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HIDE_FROM_WEB_CRAWLERS+++`
endif::add-copy-button-to-env-var[]
--
|boolean
|`true`
a| [[commafeed-server_commafeed-image-proxy-enabled]] [.property-path]##link:#commafeed-server_commafeed-image-proxy-enabled[`commafeed.image-proxy-enabled`]##
[.description]
--
If enabled, images in feed entries will be proxied through the server instead of accessed directly by the browser. This is useful if commafeed is accessed through a restricting proxy that blocks some feeds that are followed.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_IMAGE_PROXY_ENABLED+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_IMAGE_PROXY_ENABLED+++`
endif::add-copy-button-to-env-var[]
--
|boolean
|`false`
a| [[commafeed-server_commafeed-password-recovery-enabled]] [.property-path]##link:#commafeed-server_commafeed-password-recovery-enabled[`commafeed.password-recovery-enabled`]##
[.description]
--
Enable password recovery via email. Quarkus mailer will need to be configured.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_PASSWORD_RECOVERY_ENABLED+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_PASSWORD_RECOVERY_ENABLED+++`
endif::add-copy-button-to-env-var[]
--
|boolean
|`false`
a| [[commafeed-server_commafeed-announcement]] [.property-path]##link:#commafeed-server_commafeed-announcement[`commafeed.announcement`]##
[.description]
--
Message displayed in a notification at the bottom of the page.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_ANNOUNCEMENT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_ANNOUNCEMENT+++`
endif::add-copy-button-to-env-var[]
--
|string
|
a| [[commafeed-server_commafeed-google-analytics-tracking-code]] [.property-path]##link:#commafeed-server_commafeed-google-analytics-tracking-code[`commafeed.google-analytics-tracking-code`]##
[.description]
--
Google Analytics tracking code.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_GOOGLE_ANALYTICS_TRACKING_CODE+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_GOOGLE_ANALYTICS_TRACKING_CODE+++`
endif::add-copy-button-to-env-var[]
--
|string
|
a| [[commafeed-server_commafeed-google-auth-key]] [.property-path]##link:#commafeed-server_commafeed-google-auth-key[`commafeed.google-auth-key`]##
[.description]
--
Google Auth key for fetching Youtube channel favicons.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_GOOGLE_AUTH_KEY+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_GOOGLE_AUTH_KEY+++`
endif::add-copy-button-to-env-var[]
--
|string
|
h|[[commafeed-server_section_commafeed-http-client]] [.section-name.section-level0]##link:#commafeed-server_section_commafeed-http-client[HTTP client configuration]##
h|Type
h|Default
a| [[commafeed-server_commafeed-http-client-user-agent]] [.property-path]##link:#commafeed-server_commafeed-http-client-user-agent[`commafeed.http-client.user-agent`]##
[.description]
--
User-Agent string that will be used by the http client, leave empty for the default one.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_USER_AGENT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_USER_AGENT+++`
endif::add-copy-button-to-env-var[]
--
|string
|
a| [[commafeed-server_commafeed-http-client-connect-timeout]] [.property-path]##link:#commafeed-server_commafeed-http-client-connect-timeout[`commafeed.http-client.connect-timeout`]##
[.description]
--
Time to wait for a connection to be established.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_CONNECT_TIMEOUT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_CONNECT_TIMEOUT+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`5S`
a| [[commafeed-server_commafeed-http-client-ssl-handshake-timeout]] [.property-path]##link:#commafeed-server_commafeed-http-client-ssl-handshake-timeout[`commafeed.http-client.ssl-handshake-timeout`]##
[.description]
--
Time to wait for SSL handshake to complete.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_SSL_HANDSHAKE_TIMEOUT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_SSL_HANDSHAKE_TIMEOUT+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`5S`
a| [[commafeed-server_commafeed-http-client-socket-timeout]] [.property-path]##link:#commafeed-server_commafeed-http-client-socket-timeout[`commafeed.http-client.socket-timeout`]##
[.description]
--
Time to wait between two packets before timeout.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_SOCKET_TIMEOUT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_SOCKET_TIMEOUT+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`10S`
a| [[commafeed-server_commafeed-http-client-response-timeout]] [.property-path]##link:#commafeed-server_commafeed-http-client-response-timeout[`commafeed.http-client.response-timeout`]##
[.description]
--
Time to wait for the full response to be received.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_RESPONSE_TIMEOUT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_RESPONSE_TIMEOUT+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`10S`
a| [[commafeed-server_commafeed-http-client-connection-time-to-live]] [.property-path]##link:#commafeed-server_commafeed-http-client-connection-time-to-live[`commafeed.http-client.connection-time-to-live`]##
[.description]
--
Time to live for a connection in the pool.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_CONNECTION_TIME_TO_LIVE+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_CONNECTION_TIME_TO_LIVE+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`30S`
a| [[commafeed-server_commafeed-http-client-idle-connections-eviction-interval]] [.property-path]##link:#commafeed-server_commafeed-http-client-idle-connections-eviction-interval[`commafeed.http-client.idle-connections-eviction-interval`]##
[.description]
--
Time between eviction runs for idle connections.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_IDLE_CONNECTIONS_EVICTION_INTERVAL+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_IDLE_CONNECTIONS_EVICTION_INTERVAL+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`1M`
a| [[commafeed-server_commafeed-http-client-max-response-size]] [.property-path]##link:#commafeed-server_commafeed-http-client-max-response-size[`commafeed.http-client.max-response-size`]##
[.description]
--
If a feed is larger than this, it will be discarded to prevent memory issues while parsing the feed.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_MAX_RESPONSE_SIZE+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_MAX_RESPONSE_SIZE+++`
endif::add-copy-button-to-env-var[]
--
|MemorySize link:#memory-size-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the MemorySize format]]
|`5M`
h|[[commafeed-server_section_commafeed-http-client-cache]] [.section-name.section-level1]##link:#commafeed-server_section_commafeed-http-client-cache[HTTP client cache configuration]##
h|Type
h|Default
a| [[commafeed-server_commafeed-http-client-cache-enabled]] [.property-path]##link:#commafeed-server_commafeed-http-client-cache-enabled[`commafeed.http-client.cache.enabled`]##
[.description]
--
Whether to enable the cache. This cache is used to avoid spamming feeds in short bursts (e.g. when subscribing to a feed for the first time or when clicking "fetch all my feeds now").
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_CACHE_ENABLED+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_CACHE_ENABLED+++`
endif::add-copy-button-to-env-var[]
--
|boolean
|`true`
a| [[commafeed-server_commafeed-http-client-cache-maximum-memory-size]] [.property-path]##link:#commafeed-server_commafeed-http-client-cache-maximum-memory-size[`commafeed.http-client.cache.maximum-memory-size`]##
[.description]
--
Maximum amount of memory the cache can use.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_CACHE_MAXIMUM_MEMORY_SIZE+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_CACHE_MAXIMUM_MEMORY_SIZE+++`
endif::add-copy-button-to-env-var[]
--
|MemorySize link:#memory-size-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the MemorySize format]]
|`10M`
a| [[commafeed-server_commafeed-http-client-cache-expiration]] [.property-path]##link:#commafeed-server_commafeed-http-client-cache-expiration[`commafeed.http-client.cache.expiration`]##
[.description]
--
Duration after which an entry is removed from the cache.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_HTTP_CLIENT_CACHE_EXPIRATION+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_HTTP_CLIENT_CACHE_EXPIRATION+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`1M`
h|[[commafeed-server_section_commafeed-feed-refresh]] [.section-name.section-level0]##link:#commafeed-server_section_commafeed-feed-refresh[Feed refresh engine settings]##
h|Type
h|Default
a| [[commafeed-server_commafeed-feed-refresh-interval]] [.property-path]##link:#commafeed-server_commafeed-feed-refresh-interval[`commafeed.feed-refresh.interval`]##
[.description]
--
Amount of time CommaFeed will wait before refreshing the same feed.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_FEED_REFRESH_INTERVAL+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_FEED_REFRESH_INTERVAL+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`5M`
a| [[commafeed-server_commafeed-feed-refresh-interval-empirical]] [.property-path]##link:#commafeed-server_commafeed-feed-refresh-interval-empirical[`commafeed.feed-refresh.interval-empirical`]##
[.description]
--
If true, CommaFeed will calculate the next refresh time based on the feed's average time between entries and the time since the last entry was published. The interval will be somewhere between the default refresh interval and 24h. See `FeedRefreshIntervalCalculator` for details.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_FEED_REFRESH_INTERVAL_EMPIRICAL+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_FEED_REFRESH_INTERVAL_EMPIRICAL+++`
endif::add-copy-button-to-env-var[]
--
|boolean
|`false`
a| [[commafeed-server_commafeed-feed-refresh-http-threads]] [.property-path]##link:#commafeed-server_commafeed-feed-refresh-http-threads[`commafeed.feed-refresh.http-threads`]##
[.description]
--
Amount of http threads used to fetch feeds.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_FEED_REFRESH_HTTP_THREADS+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_FEED_REFRESH_HTTP_THREADS+++`
endif::add-copy-button-to-env-var[]
--
|int
|`3`
a| [[commafeed-server_commafeed-feed-refresh-database-threads]] [.property-path]##link:#commafeed-server_commafeed-feed-refresh-database-threads[`commafeed.feed-refresh.database-threads`]##
[.description]
--
Amount of threads used to insert new entries in the database.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_FEED_REFRESH_DATABASE_THREADS+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_FEED_REFRESH_DATABASE_THREADS+++`
endif::add-copy-button-to-env-var[]
--
|int
|`1`
a| [[commafeed-server_commafeed-feed-refresh-user-inactivity-period]] [.property-path]##link:#commafeed-server_commafeed-feed-refresh-user-inactivity-period[`commafeed.feed-refresh.user-inactivity-period`]##
[.description]
--
Duration after which a user is considered inactive. Feeds for inactive users are not refreshed until they log in again. 0 to disable.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_FEED_REFRESH_USER_INACTIVITY_PERIOD+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_FEED_REFRESH_USER_INACTIVITY_PERIOD+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`0S`
a| [[commafeed-server_commafeed-feed-refresh-filtering-expression-evaluation-timeout]] [.property-path]##link:#commafeed-server_commafeed-feed-refresh-filtering-expression-evaluation-timeout[`commafeed.feed-refresh.filtering-expression-evaluation-timeout`]##
[.description]
--
Duration after which the evaluation of a filtering expresion to mark an entry as read is considered to have timed out.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_FEED_REFRESH_FILTERING_EXPRESSION_EVALUATION_TIMEOUT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_FEED_REFRESH_FILTERING_EXPRESSION_EVALUATION_TIMEOUT+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`500MS`
a| [[commafeed-server_commafeed-feed-refresh-force-refresh-cooldown-duration]] [.property-path]##link:#commafeed-server_commafeed-feed-refresh-force-refresh-cooldown-duration[`commafeed.feed-refresh.force-refresh-cooldown-duration`]##
[.description]
--
Duration after which the "Fetch all my feeds now" action is available again after use to avoid spamming feeds.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_FEED_REFRESH_FORCE_REFRESH_COOLDOWN_DURATION+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_FEED_REFRESH_FORCE_REFRESH_COOLDOWN_DURATION+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`0S`
h|[[commafeed-server_section_commafeed-database]] [.section-name.section-level0]##link:#commafeed-server_section_commafeed-database[Database settings]##
h|Type
h|Default
a| [[commafeed-server_commafeed-database-query-timeout]] [.property-path]##link:#commafeed-server_commafeed-database-query-timeout[`commafeed.database.query-timeout`]##
[.description]
--
Timeout applied to all database queries. 0 to disable.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_DATABASE_QUERY_TIMEOUT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_DATABASE_QUERY_TIMEOUT+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`0S`
h|[[commafeed-server_section_commafeed-database-cleanup]] [.section-name.section-level1]##link:#commafeed-server_section_commafeed-database-cleanup[Database cleanup settings]##
h|Type
h|Default
a| [[commafeed-server_commafeed-database-cleanup-entries-max-age]] [.property-path]##link:#commafeed-server_commafeed-database-cleanup-entries-max-age[`commafeed.database.cleanup.entries-max-age`]##
[.description]
--
Maximum age of feed entries in the database. Older entries will be deleted. 0 to disable.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_DATABASE_CLEANUP_ENTRIES_MAX_AGE+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_DATABASE_CLEANUP_ENTRIES_MAX_AGE+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`365D`
a| [[commafeed-server_commafeed-database-cleanup-statuses-max-age]] [.property-path]##link:#commafeed-server_commafeed-database-cleanup-statuses-max-age[`commafeed.database.cleanup.statuses-max-age`]##
[.description]
--
Maximum age of feed entry statuses (read/unread) in the database. Older statuses will be deleted. 0 to disable.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_DATABASE_CLEANUP_STATUSES_MAX_AGE+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_DATABASE_CLEANUP_STATUSES_MAX_AGE+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`0S`
a| [[commafeed-server_commafeed-database-cleanup-max-feed-capacity]] [.property-path]##link:#commafeed-server_commafeed-database-cleanup-max-feed-capacity[`commafeed.database.cleanup.max-feed-capacity`]##
[.description]
--
Maximum number of entries per feed to keep in the database. 0 to disable.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_DATABASE_CLEANUP_MAX_FEED_CAPACITY+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_DATABASE_CLEANUP_MAX_FEED_CAPACITY+++`
endif::add-copy-button-to-env-var[]
--
|int
|`500`
a| [[commafeed-server_commafeed-database-cleanup-max-feeds-per-user]] [.property-path]##link:#commafeed-server_commafeed-database-cleanup-max-feeds-per-user[`commafeed.database.cleanup.max-feeds-per-user`]##
[.description]
--
Limit the number of feeds a user can subscribe to. 0 to disable.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_DATABASE_CLEANUP_MAX_FEEDS_PER_USER+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_DATABASE_CLEANUP_MAX_FEEDS_PER_USER+++`
endif::add-copy-button-to-env-var[]
--
|int
|`0`
a| [[commafeed-server_commafeed-database-cleanup-batch-size]] [.property-path]##link:#commafeed-server_commafeed-database-cleanup-batch-size[`commafeed.database.cleanup.batch-size`]##
[.description]
--
Rows to delete per query while cleaning up old entries.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_DATABASE_CLEANUP_BATCH_SIZE+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_DATABASE_CLEANUP_BATCH_SIZE+++`
endif::add-copy-button-to-env-var[]
--
|int
|`100`
h|[[commafeed-server_section_commafeed-users]] [.section-name.section-level0]##link:#commafeed-server_section_commafeed-users[Users settings]##
h|Type
h|Default
a| [[commafeed-server_commafeed-users-allow-registrations]] [.property-path]##link:#commafeed-server_commafeed-users-allow-registrations[`commafeed.users.allow-registrations`]##
[.description]
--
Whether to let users create accounts for themselves.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_USERS_ALLOW_REGISTRATIONS+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_USERS_ALLOW_REGISTRATIONS+++`
endif::add-copy-button-to-env-var[]
--
|boolean
|`false`
a| [[commafeed-server_commafeed-users-strict-password-policy]] [.property-path]##link:#commafeed-server_commafeed-users-strict-password-policy[`commafeed.users.strict-password-policy`]##
[.description]
--
Whether to enable strict password validation (1 uppercase char, 1 lowercase char, 1 digit, 1 special char).
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_USERS_STRICT_PASSWORD_POLICY+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_USERS_STRICT_PASSWORD_POLICY+++`
endif::add-copy-button-to-env-var[]
--
|boolean
|`true`
a| [[commafeed-server_commafeed-users-create-demo-account]] [.property-path]##link:#commafeed-server_commafeed-users-create-demo-account[`commafeed.users.create-demo-account`]##
[.description]
--
Whether to create a demo account the first time the app starts.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_USERS_CREATE_DEMO_ACCOUNT+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_USERS_CREATE_DEMO_ACCOUNT+++`
endif::add-copy-button-to-env-var[]
--
|boolean
|`false`
h|[[commafeed-server_section_commafeed-websocket]] [.section-name.section-level0]##link:#commafeed-server_section_commafeed-websocket[Websocket settings]##
h|Type
h|Default
a| [[commafeed-server_commafeed-websocket-enabled]] [.property-path]##link:#commafeed-server_commafeed-websocket-enabled[`commafeed.websocket.enabled`]##
[.description]
--
Enable websocket connection so the server can notify web clients that there are new entries for feeds.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_WEBSOCKET_ENABLED+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_WEBSOCKET_ENABLED+++`
endif::add-copy-button-to-env-var[]
--
|boolean
|`true`
a| [[commafeed-server_commafeed-websocket-ping-interval]] [.property-path]##link:#commafeed-server_commafeed-websocket-ping-interval[`commafeed.websocket.ping-interval`]##
[.description]
--
Interval at which the client will send a ping message on the websocket to keep the connection alive.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_WEBSOCKET_PING_INTERVAL+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_WEBSOCKET_PING_INTERVAL+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`15M`
a| [[commafeed-server_commafeed-websocket-tree-reload-interval]] [.property-path]##link:#commafeed-server_commafeed-websocket-tree-reload-interval[`commafeed.websocket.tree-reload-interval`]##
[.description]
--
If the websocket connection is disabled or the connection is lost, the client will reload the feed tree at this interval.
ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++COMMAFEED_WEBSOCKET_TREE_RELOAD_INTERVAL+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++COMMAFEED_WEBSOCKET_TREE_RELOAD_INTERVAL+++`
endif::add-copy-button-to-env-var[]
--
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
|`30S`
|===
ifndef::no-duration-note[]
[NOTE]
[id=duration-note-anchor-commafeed-server_commafeed]
.About the Duration format
====
To write duration values, use the standard `java.time.Duration` format.
See the link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html#parse(java.lang.CharSequence)[Duration#parse() Java API documentation] for more information.
You can also use a simplified format, starting with a number:
* If the value is only a number, it represents time in seconds.
* If the value is a number followed by `ms`, it represents time in milliseconds.
In other cases, the simplified format is translated to the `java.time.Duration` format for parsing:
* If the value is a number followed by `h`, `m`, or `s`, it is prefixed with `PT`.
* If the value is a number followed by `d`, it is prefixed with `P`.
====
endif::no-duration-note[]
ifndef::no-memory-size-note[]
[NOTE]
[id=memory-size-note-anchor-commafeed-server_commafeed]
.About the MemorySize format
====
A size configuration option recognizes strings in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`.
If no suffix is given, assume bytes.
====
ifndef::no-memory-size-note[]
:!summaryTableId:

View File

@@ -0,0 +1,799 @@
🔒: Configuration property fixed at build time - All other configuration properties are overridable at runtime
<table>
<thead>
<tr>
<th align="left">Configuration property</th>
<th>Type</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr>
<td>
`commafeed.hide-from-web-crawlers`
Whether to expose a robots.txt file that disallows web crawlers and search engine indexers.
Environment variable: `COMMAFEED_HIDE_FROM_WEB_CRAWLERS`</td>
<td>
boolean
</td>
<td>
`true`
</td>
</tr>
<tr>
<td>
`commafeed.image-proxy-enabled`
If enabled, images in feed entries will be proxied through the server instead of accessed directly by the browser.
This is useful if commafeed is accessed through a restricting proxy that blocks some feeds that are followed.
Environment variable: `COMMAFEED_IMAGE_PROXY_ENABLED`</td>
<td>
boolean
</td>
<td>
`false`
</td>
</tr>
<tr>
<td>
`commafeed.password-recovery-enabled`
Enable password recovery via email.
Quarkus mailer will need to be configured.
Environment variable: `COMMAFEED_PASSWORD_RECOVERY_ENABLED`</td>
<td>
boolean
</td>
<td>
`false`
</td>
</tr>
<tr>
<td>
`commafeed.announcement`
Message displayed in a notification at the bottom of the page.
Environment variable: `COMMAFEED_ANNOUNCEMENT`</td>
<td>
string
</td>
<td>
</td>
</tr>
<tr>
<td>
`commafeed.google-analytics-tracking-code`
Google Analytics tracking code.
Environment variable: `COMMAFEED_GOOGLE_ANALYTICS_TRACKING_CODE`</td>
<td>
string
</td>
<td>
</td>
</tr>
<tr>
<td>
`commafeed.google-auth-key`
Google Auth key for fetching Youtube channel favicons.
Environment variable: `COMMAFEED_GOOGLE_AUTH_KEY`</td>
<td>
string
</td>
<td>
</td>
</tr>
<thead>
<tr>
<th align="left" colspan="3">
HTTP client configuration
</th>
</tr>
</thead>
<tr>
<td>
`commafeed.http-client.user-agent`
User-Agent string that will be used by the http client, leave empty for the default one.
Environment variable: `COMMAFEED_HTTP_CLIENT_USER_AGENT`</td>
<td>
string
</td>
<td>
</td>
</tr>
<tr>
<td>
`commafeed.http-client.connect-timeout`
Time to wait for a connection to be established.
Environment variable: `COMMAFEED_HTTP_CLIENT_CONNECT_TIMEOUT`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`5S`
</td>
</tr>
<tr>
<td>
`commafeed.http-client.ssl-handshake-timeout`
Time to wait for SSL handshake to complete.
Environment variable: `COMMAFEED_HTTP_CLIENT_SSL_HANDSHAKE_TIMEOUT`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`5S`
</td>
</tr>
<tr>
<td>
`commafeed.http-client.socket-timeout`
Time to wait between two packets before timeout.
Environment variable: `COMMAFEED_HTTP_CLIENT_SOCKET_TIMEOUT`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`10S`
</td>
</tr>
<tr>
<td>
`commafeed.http-client.response-timeout`
Time to wait for the full response to be received.
Environment variable: `COMMAFEED_HTTP_CLIENT_RESPONSE_TIMEOUT`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`10S`
</td>
</tr>
<tr>
<td>
`commafeed.http-client.connection-time-to-live`
Time to live for a connection in the pool.
Environment variable: `COMMAFEED_HTTP_CLIENT_CONNECTION_TIME_TO_LIVE`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`30S`
</td>
</tr>
<tr>
<td>
`commafeed.http-client.idle-connections-eviction-interval`
Time between eviction runs for idle connections.
Environment variable: `COMMAFEED_HTTP_CLIENT_IDLE_CONNECTIONS_EVICTION_INTERVAL`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`1M`
</td>
</tr>
<tr>
<td>
`commafeed.http-client.max-response-size`
If a feed is larger than this, it will be discarded to prevent memory issues while parsing the feed.
Environment variable: `COMMAFEED_HTTP_CLIENT_MAX_RESPONSE_SIZE`</td>
<td>
MemorySize [🛈](#memory-size-note-anchor)
</td>
<td>
`5M`
</td>
</tr>
<thead>
<tr>
<th align="left" colspan="3">
&nbsp;&nbsp;&nbsp;&nbsp;HTTP client cache configuration
</th>
</tr>
</thead>
<tr>
<td>
`commafeed.http-client.cache.enabled`
Whether to enable the cache. This cache is used to avoid spamming feeds in short bursts (e.g. when subscribing to a feed for the
first time or when clicking "fetch all my feeds now").
Environment variable: `COMMAFEED_HTTP_CLIENT_CACHE_ENABLED`</td>
<td>
boolean
</td>
<td>
`true`
</td>
</tr>
<tr>
<td>
`commafeed.http-client.cache.maximum-memory-size`
Maximum amount of memory the cache can use.
Environment variable: `COMMAFEED_HTTP_CLIENT_CACHE_MAXIMUM_MEMORY_SIZE`</td>
<td>
MemorySize [🛈](#memory-size-note-anchor)
</td>
<td>
`10M`
</td>
</tr>
<tr>
<td>
`commafeed.http-client.cache.expiration`
Duration after which an entry is removed from the cache.
Environment variable: `COMMAFEED_HTTP_CLIENT_CACHE_EXPIRATION`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`1M`
</td>
</tr>
<thead>
<tr>
<th align="left" colspan="3">
Feed refresh engine settings
</th>
</tr>
</thead>
<tr>
<td>
`commafeed.feed-refresh.interval`
Amount of time CommaFeed will wait before refreshing the same feed.
Environment variable: `COMMAFEED_FEED_REFRESH_INTERVAL`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`5M`
</td>
</tr>
<tr>
<td>
`commafeed.feed-refresh.interval-empirical`
If true, CommaFeed will calculate the next refresh time based on the feed's average time between entries and the time since the
last entry was published. The interval will be somewhere between the default refresh interval and 24h.
See <code>FeedRefreshIntervalCalculator</code> for details.
Environment variable: `COMMAFEED_FEED_REFRESH_INTERVAL_EMPIRICAL`</td>
<td>
boolean
</td>
<td>
`false`
</td>
</tr>
<tr>
<td>
`commafeed.feed-refresh.http-threads`
Amount of http threads used to fetch feeds.
Environment variable: `COMMAFEED_FEED_REFRESH_HTTP_THREADS`</td>
<td>
int
</td>
<td>
`3`
</td>
</tr>
<tr>
<td>
`commafeed.feed-refresh.database-threads`
Amount of threads used to insert new entries in the database.
Environment variable: `COMMAFEED_FEED_REFRESH_DATABASE_THREADS`</td>
<td>
int
</td>
<td>
`1`
</td>
</tr>
<tr>
<td>
`commafeed.feed-refresh.user-inactivity-period`
Duration after which a user is considered inactive. Feeds for inactive users are not refreshed until they log in again.
0 to disable.
Environment variable: `COMMAFEED_FEED_REFRESH_USER_INACTIVITY_PERIOD`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`0S`
</td>
</tr>
<tr>
<td>
`commafeed.feed-refresh.filtering-expression-evaluation-timeout`
Duration after which the evaluation of a filtering expresion to mark an entry as read is considered to have timed out.
Environment variable: `COMMAFEED_FEED_REFRESH_FILTERING_EXPRESSION_EVALUATION_TIMEOUT`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`500MS`
</td>
</tr>
<tr>
<td>
`commafeed.feed-refresh.force-refresh-cooldown-duration`
Duration after which the "Fetch all my feeds now" action is available again after use to avoid spamming feeds.
Environment variable: `COMMAFEED_FEED_REFRESH_FORCE_REFRESH_COOLDOWN_DURATION`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`0S`
</td>
</tr>
<thead>
<tr>
<th align="left" colspan="3">
Database settings
</th>
</tr>
</thead>
<tr>
<td>
`commafeed.database.query-timeout`
Timeout applied to all database queries.
0 to disable.
Environment variable: `COMMAFEED_DATABASE_QUERY_TIMEOUT`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`0S`
</td>
</tr>
<thead>
<tr>
<th align="left" colspan="3">
&nbsp;&nbsp;&nbsp;&nbsp;Database cleanup settings
</th>
</tr>
</thead>
<tr>
<td>
`commafeed.database.cleanup.entries-max-age`
Maximum age of feed entries in the database. Older entries will be deleted.
0 to disable.
Environment variable: `COMMAFEED_DATABASE_CLEANUP_ENTRIES_MAX_AGE`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`365D`
</td>
</tr>
<tr>
<td>
`commafeed.database.cleanup.statuses-max-age`
Maximum age of feed entry statuses (read/unread) in the database. Older statuses will be deleted.
0 to disable.
Environment variable: `COMMAFEED_DATABASE_CLEANUP_STATUSES_MAX_AGE`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`0S`
</td>
</tr>
<tr>
<td>
`commafeed.database.cleanup.max-feed-capacity`
Maximum number of entries per feed to keep in the database.
0 to disable.
Environment variable: `COMMAFEED_DATABASE_CLEANUP_MAX_FEED_CAPACITY`</td>
<td>
int
</td>
<td>
`500`
</td>
</tr>
<tr>
<td>
`commafeed.database.cleanup.max-feeds-per-user`
Limit the number of feeds a user can subscribe to.
0 to disable.
Environment variable: `COMMAFEED_DATABASE_CLEANUP_MAX_FEEDS_PER_USER`</td>
<td>
int
</td>
<td>
`0`
</td>
</tr>
<tr>
<td>
`commafeed.database.cleanup.batch-size`
Rows to delete per query while cleaning up old entries.
Environment variable: `COMMAFEED_DATABASE_CLEANUP_BATCH_SIZE`</td>
<td>
int
</td>
<td>
`100`
</td>
</tr>
<thead>
<tr>
<th align="left" colspan="3">
Users settings
</th>
</tr>
</thead>
<tr>
<td>
`commafeed.users.allow-registrations`
Whether to let users create accounts for themselves.
Environment variable: `COMMAFEED_USERS_ALLOW_REGISTRATIONS`</td>
<td>
boolean
</td>
<td>
`false`
</td>
</tr>
<tr>
<td>
`commafeed.users.strict-password-policy`
Whether to enable strict password validation (1 uppercase char, 1 lowercase char, 1 digit, 1 special char).
Environment variable: `COMMAFEED_USERS_STRICT_PASSWORD_POLICY`</td>
<td>
boolean
</td>
<td>
`true`
</td>
</tr>
<tr>
<td>
`commafeed.users.create-demo-account`
Whether to create a demo account the first time the app starts.
Environment variable: `COMMAFEED_USERS_CREATE_DEMO_ACCOUNT`</td>
<td>
boolean
</td>
<td>
`false`
</td>
</tr>
<thead>
<tr>
<th align="left" colspan="3">
Websocket settings
</th>
</tr>
</thead>
<tr>
<td>
`commafeed.websocket.enabled`
Enable websocket connection so the server can notify web clients that there are new entries for feeds.
Environment variable: `COMMAFEED_WEBSOCKET_ENABLED`</td>
<td>
boolean
</td>
<td>
`true`
</td>
</tr>
<tr>
<td>
`commafeed.websocket.ping-interval`
Interval at which the client will send a ping message on the websocket to keep the connection alive.
Environment variable: `COMMAFEED_WEBSOCKET_PING_INTERVAL`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`15M`
</td>
</tr>
<tr>
<td>
`commafeed.websocket.tree-reload-interval`
If the websocket connection is disabled or the connection is lost, the client will reload the feed tree at this interval.
Environment variable: `COMMAFEED_WEBSOCKET_TREE_RELOAD_INTERVAL`</td>
<td>
[Duration](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html) [🛈](#duration-note-anchor)
</td>
<td>
`30S`
</td>
</tr>
</tbody>
</table>
<a name="duration-note-anchor"></a>
> [!NOTE]
> ### About the Duration format
>
> To write duration values, use the standard `java.time.Duration` format.
> See the [Duration#parse()](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html#parse(java.lang.CharSequence)) Java API documentation] for more information.
>
> You can also use a simplified format, starting with a number:
>
> * If the value is only a number, it represents time in seconds.
> * If the value is a number followed by `ms`, it represents time in milliseconds.
>
> In other cases, the simplified format is translated to the `java.time.Duration` format for parsing:
>
> * If the value is a number followed by `h`, `m`, or `s`, it is prefixed with `PT`.
> * If the value is a number followed by `d`, it is prefixed with `P`.
<a name="memory-size-note-anchor"></a>
> [!NOTE]
> ### About the MemorySize format
>
> A size configuration option recognizes strings in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`.
>
> If no suffix is given, assume bytes.

View File

@@ -6,16 +6,16 @@
<parent>
<groupId>com.commafeed</groupId>
<artifactId>commafeed</artifactId>
<version>5.3.4</version>
<version>5.3.6</version>
</parent>
<artifactId>commafeed-server</artifactId>
<name>CommaFeed Server</name>
<properties>
<quarkus.version>3.15.1</quarkus.version>
<querydsl.version>6.8</querydsl.version>
<quarkus.version>3.17.2</quarkus.version>
<querydsl.version>6.9</querydsl.version>
<rome.version>2.1.0</rome.version>
<swagger.version>2.2.25</swagger.version>
<swagger.version>2.2.26</swagger.version>
<build.database>h2</build.database>
</properties>
@@ -104,11 +104,14 @@
<extensions>true</extensions>
<executions>
<execution>
<id>default-generate-asciidoc</id>
<id>default-generate-config-doc</id>
<phase>process-test-resources</phase>
<goals>
<goal>generate-asciidoc</goal>
<goal>generate-config-doc</goal>
</goals>
<configuration>
<format>markdown</format>
</configuration>
</execution>
</executions>
</plugin>
@@ -135,7 +138,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.1</version>
<version>3.5.2</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
@@ -146,7 +149,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.5.1</version>
<version>3.5.2</version>
<executions>
<execution>
<goals>
@@ -233,12 +236,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.5.0</version>
<version>3.6.0</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.18.2</version>
<version>10.20.2</version>
</dependency>
</dependencies>
<executions>
@@ -294,14 +297,14 @@
<dependency>
<groupId>com.commafeed</groupId>
<artifactId>commafeed-client</artifactId>
<version>5.3.4</version>
<version>5.3.6</version>
</dependency>
<!-- compile-time processors -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
<version>1.18.36</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -358,7 +361,7 @@
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-json</artifactId>
<version>4.2.28</version>
<version>4.2.29</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
@@ -430,12 +433,12 @@
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.18.1</version>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>75.1</version>
<version>76.1</version>
</dependency>
<dependency>
<groupId>net.sourceforge.cssparser</groupId>
@@ -450,7 +453,7 @@
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.4</version>
<version>5.4.1</version>
</dependency>
<!-- add brotli support for httpclient5 -->
<dependency>
@@ -489,7 +492,7 @@
<dependency>
<groupId>com.microsoft.playwright</groupId>
<artifactId>playwright</artifactId>
<version>1.48.0</version>
<version>1.49.0</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@@ -1,4 +1,4 @@
FROM ibm-semeru-runtimes:open-21.0.4_7-jre
FROM ibm-semeru-runtimes:open-21.0.5_11-jre
EXPOSE 8082
RUN mkdir -p /commafeed/data

View File

@@ -1,4 +1,4 @@
FROM debian:12.7
FROM debian:12.8
EXPOSE 8082
RUN mkdir -p /commafeed/data

View File

@@ -68,7 +68,7 @@ CommaFeed also supports:
## Configuration
All [CommaFeed settings](https://github.com/Athou/commafeed/blob/master/commafeed-server/doc/commafeed.adoc) are
All [CommaFeed settings](https://github.com/Athou/commafeed/blob/master/commafeed-server/doc/commafeed.md) are
optional and have sensible default values.
Settings are overrideable with environment variables. For instance, `commafeed.feed-refresh.interval-empirical` can be

View File

@@ -34,6 +34,7 @@ import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
import org.jboss.resteasy.reactive.common.headers.CacheControlDelegate;
import com.codahale.metrics.MetricRegistry;
import com.commafeed.CommaFeedConfiguration;
@@ -46,6 +47,7 @@ import com.google.common.io.ByteStreams;
import com.google.common.net.HttpHeaders;
import jakarta.inject.Singleton;
import jakarta.ws.rs.core.CacheControl;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@@ -123,8 +125,13 @@ public class HttpGetter {
throw new NotModifiedException("eTagHeader is the same");
}
Duration validFor = Optional.ofNullable(response.getCacheControl())
.filter(cc -> cc.getMaxAge() >= 0)
.map(cc -> Duration.ofSeconds(cc.getMaxAge()))
.orElse(Duration.ZERO);
return new HttpResult(response.getContent(), response.getContentType(), lastModifiedHeader, eTagHeader,
response.getUrlAfterRedirect());
response.getUrlAfterRedirect(), validFor);
}
private HttpResponse invoke(HttpRequest request) throws IOException {
@@ -152,6 +159,12 @@ public class HttpGetter {
.map(StringUtils::trimToNull)
.orElse(null);
CacheControl cacheControl = Optional.ofNullable(resp.getFirstHeader(HttpHeaders.CACHE_CONTROL))
.map(NameValuePair::getValue)
.map(StringUtils::trimToNull)
.map(HttpGetter::toCacheControl)
.orElse(null);
String contentType = Optional.ofNullable(resp.getEntity()).map(HttpEntity::getContentType).orElse(null);
String urlAfterRedirect = Optional.ofNullable(context.getRedirectLocations())
.map(RedirectLocations::getAll)
@@ -159,10 +172,19 @@ public class HttpGetter {
.map(URI::toString)
.orElse(request.getUrl());
return new HttpResponse(code, lastModifiedHeader, eTagHeader, content, contentType, urlAfterRedirect);
return new HttpResponse(code, lastModifiedHeader, eTagHeader, cacheControl, content, contentType, urlAfterRedirect);
});
}
private static CacheControl toCacheControl(String headerValue) {
try {
return CacheControlDelegate.INSTANCE.fromString(headerValue);
} catch (Exception e) {
log.debug("Invalid Cache-Control header: {}", headerValue);
return null;
}
}
private static byte[] toByteArray(HttpEntity entity, long maxBytes) throws IOException {
if (entity.getContentLength() > maxBytes) {
throw new IOException(
@@ -311,6 +333,7 @@ public class HttpGetter {
int code;
String lastModifiedHeader;
String eTagHeader;
CacheControl cacheControl;
byte[] content;
String contentType;
String urlAfterRedirect;
@@ -323,6 +346,7 @@ public class HttpGetter {
String lastModifiedSince;
String eTag;
String urlAfterRedirect;
Duration validFor;
}
}

View File

@@ -2,6 +2,7 @@ package com.commafeed.backend.feed;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
@@ -87,7 +88,8 @@ public class FeedFetcher {
etagHeaderValueChanged ? result.getETag() : null);
}
return new FeedFetcherResult(parserResult, result.getUrlAfterRedirect(), result.getLastModifiedSince(), result.getETag(), hash);
return new FeedFetcherResult(parserResult, result.getUrlAfterRedirect(), result.getLastModifiedSince(), result.getETag(), hash,
result.getValidFor());
}
private static String extractFeedUrl(List<FeedURLProvider> urlProviders, String url, String urlContent) {
@@ -102,7 +104,7 @@ public class FeedFetcher {
}
public record FeedFetcherResult(FeedParserResult feed, String urlAfterRedirect, String lastModifiedHeader, String lastETagHeader,
String contentHash) {
String contentHash, Duration validFor) {
}
}

View File

@@ -6,6 +6,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import com.codahale.metrics.Meter;
@@ -76,8 +77,9 @@ public class FeedRefreshWorker {
feed.setErrorCount(0);
feed.setMessage(null);
feed.setDisabledUntil(
refreshIntervalCalculator.onFetchSuccess(result.feed().lastPublishedDate(), result.feed().averageEntryInterval()));
feed.setDisabledUntil(ObjectUtils.max(
refreshIntervalCalculator.onFetchSuccess(result.feed().lastPublishedDate(), result.feed().averageEntryInterval()),
Instant.now().plus(result.validFor())));
return new FeedRefreshWorkerResult(feed, entries);
} catch (NotModifiedException e) {

View File

@@ -337,7 +337,7 @@ public class UserREST {
return Response.status(Status.UNAUTHORIZED).entity("token expired.").build();
}
String passwd = RandomStringUtils.randomAlphanumeric(10);
String passwd = RandomStringUtils.secure().nextAlphanumeric(10);
byte[] encryptedPassword = encryptionService.getEncryptedPassword(passwd, user.getSalt());
user.setPassword(encryptedPassword);
if (StringUtils.isNotBlank(user.getApiKey())) {

View File

@@ -1,44 +0,0 @@
package com.commafeed.security.mechanism;
import io.quarkus.security.identity.IdentityProviderManager;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.vertx.http.runtime.HttpConfiguration;
import io.quarkus.vertx.http.runtime.security.FormAuthenticationMechanism;
import io.quarkus.vertx.http.runtime.security.HttpAuthenticationMechanism;
import io.smallrye.mutiny.Uni;
import io.vertx.core.http.Cookie;
import io.vertx.core.http.impl.ServerCookie;
import io.vertx.ext.web.RoutingContext;
import jakarta.annotation.Priority;
import jakarta.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Delegate;
import lombok.extern.slf4j.Slf4j;
/**
* HttpAuthenticationMechanism that wraps FormAuthenticationMechanism and sets a Max-Age on the cookie because it has no value by default.
*
* This is a workaround for https://github.com/quarkusio/quarkus/issues/42463
*/
@Priority(1)
@RequiredArgsConstructor
@Singleton
@Slf4j
public class CookieMaxAgeFormAuthenticationMechanism implements HttpAuthenticationMechanism {
@Delegate
private final FormAuthenticationMechanism delegate;
private final HttpConfiguration config;
@Override
public Uni<SecurityIdentity> authenticate(RoutingContext context, IdentityProviderManager identityProviderManager) {
context.addHeadersEndHandler(v -> {
Cookie cookie = context.request().getCookie(config.auth.form.cookieName);
if (cookie instanceof ServerCookie sc && sc.isChanged()) {
cookie.setMaxAge(config.auth.form.timeout.toSeconds());
}
});
return delegate.authenticate(context, identityProviderManager);
}
}

View File

@@ -15,6 +15,7 @@ quarkus.http.auth.basic=true
quarkus.http.auth.form.enabled=true
quarkus.http.auth.form.http-only-cookie=true
quarkus.http.auth.form.timeout=P30d
quarkus.http.auth.form.cookie-max-age=P30d
quarkus.http.auth.form.landing-page=
quarkus.http.auth.form.login-page=
quarkus.http.auth.form.error-page=

View File

@@ -11,10 +11,10 @@ import org.junit.jupiter.api.Test;
class CommaFeedConfigurationTest {
@Test
void verifyAsciiDocIsUpToDate() throws IOException {
String versionedDocumentationFile = FileUtils.readFileToString(new File("doc/commafeed.adoc"), StandardCharsets.UTF_8);
String generatedDocumentationFile = FileUtils
.readFileToString(new File("target/quarkus-generated-doc/config/commafeed-server.adoc"), StandardCharsets.UTF_8);
void verifyMarkdownDocIsUpToDate() throws IOException {
String versionedDocumentationFile = FileUtils.readFileToString(new File("doc/commafeed.md"), StandardCharsets.UTF_8);
String generatedDocumentationFile = FileUtils.readFileToString(new File("target/quarkus-generated-doc/config/commafeed-server.md"),
StandardCharsets.UTF_8);
Assertions.assertLinesMatch(versionedDocumentationFile.lines(), generatedDocumentationFile.lines());
}

View File

@@ -93,16 +93,30 @@ class HttpGetterTest {
.withBody(feedContent)
.withContentType(MediaType.APPLICATION_ATOM_XML)
.withHeader(HttpHeaders.LAST_MODIFIED, "123456")
.withHeader(HttpHeaders.ETAG, "78910"));
.withHeader(HttpHeaders.ETAG, "78910")
.withHeader(HttpHeaders.CACHE_CONTROL, "max-age=60, must-revalidate"));
HttpResult result = getter.get(this.feedUrl);
Assertions.assertArrayEquals(feedContent, result.getContent());
Assertions.assertEquals(MediaType.APPLICATION_ATOM_XML.toString(), result.getContentType());
Assertions.assertEquals("123456", result.getLastModifiedSince());
Assertions.assertEquals("78910", result.getETag());
Assertions.assertEquals(Duration.ofSeconds(60), result.getValidFor());
Assertions.assertEquals(this.feedUrl, result.getUrlAfterRedirect());
}
@Test
void ignoreInvalidCacheControlValue() throws Exception {
this.mockServerClient.when(HttpRequest.request().withMethod("GET"))
.respond(HttpResponse.response()
.withBody(feedContent)
.withContentType(MediaType.APPLICATION_ATOM_XML)
.withHeader(HttpHeaders.CACHE_CONTROL, "max-age=60; must-revalidate"));
HttpResult result = getter.get(this.feedUrl);
Assertions.assertEquals(Duration.ZERO, result.getValidFor());
}
@ParameterizedTest
@ValueSource(
ints = { HttpStatus.SC_MOVED_PERMANENTLY, HttpStatus.SC_MOVED_TEMPORARILY, HttpStatus.SC_TEMPORARY_REDIRECT,

View File

@@ -1,5 +1,6 @@
package com.commafeed.backend.feed;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
@@ -46,7 +47,7 @@ class FeedFetcherTest {
String lastContentHash = Digests.sha1Hex(content);
Mockito.when(getter.get(HttpGetter.HttpRequest.builder(url).lastModified(lastModified).eTag(etag).build()))
.thenReturn(new HttpResult(content, "content-type", "last-modified-2", "etag-2", null));
.thenReturn(new HttpResult(content, "content-type", "last-modified-2", "etag-2", null, Duration.ZERO));
NotModifiedException e = Assertions.assertThrows(NotModifiedException.class,
() -> fetcher.fetch(url, false, lastModified, etag, Instant.now(), lastContentHash));

View File

@@ -5,7 +5,7 @@
<groupId>com.commafeed</groupId>
<artifactId>commafeed</artifactId>
<version>5.3.4</version>
<version>5.3.6</version>
<name>CommaFeed</name>
<packaging>pom</packaging>
@@ -27,6 +27,9 @@
<!-- https://stackoverflow.com/a/33823355/ -->
<showWarnings>true</showWarnings>
<compilerArgs>
<!-- enable annotation processing -->
<arg>-proc:full</arg>
<!-- disable the "processing" linter because we have annotations that are processed at runtime -->
<!-- https://stackoverflow.com/a/76126981/ -->
<!-- disable the "classfile" linter because it generates "file missing" warnings about annotations with the "provided" scope -->