Compare commits

...

173 Commits
7.2.0 ... 7.3.2

Author SHA1 Message Date
Athou
689c20d367 release 7.3.2 2026-08-22 08:23:13 +02:00
Athou
43588df2b4 prevent users from starring/tagging entries that are not theirs 2026-08-22 08:14:21 +02:00
renovate[bot]
d2aaddea33 Update dependency vitest to v4.1.11 2026-08-21 18:52:50 +00:00
Jérémie Panzer
de233f8ae5 Merge pull request #2280 from Athou/renovate/patch-testing-library-monorepo
Update dependency @testing-library/user-event to v14.6.5
2026-08-21 15:06:31 +02:00
renovate[bot]
3179e74dc7 Update dependency @testing-library/user-event to v14.6.5 2026-08-21 04:47:20 +00:00
renovate[bot]
6f5e9f5d49 Update dependency @biomejs/biome to v2.5.9 2026-08-21 00:00:07 +00:00
Jérémie Panzer
8a43fdf200 Merge pull request #2279 from Athou/renovate/protobuf-monorepo
Update dependency com.google.protobuf:protobuf-java to v4.36.0
2026-08-21 01:59:09 +02:00
renovate[bot]
69051e5bbb Update dependency com.google.protobuf:protobuf-java to v4.36.0 2026-08-20 18:54:00 +00:00
renovate[bot]
c648e7e0ec Update dependency dayjs to v1.11.23 2026-08-20 15:32:41 +00:00
renovate[bot]
c91cf376ad Update ibm-semeru-runtimes:open-jdk-25.0.4.0-jre Docker digest to 524f0d0 2026-08-20 09:23:52 +00:00
Jérémie Panzer
f4e07597d0 Merge pull request #2278 from canoine/patch-11
Update fr/messages.po
2026-08-20 11:22:57 +02:00
CNE
64b64d3340 Update fr/messages.po
3 new fields
2026-08-20 10:47:45 +02:00
Jérémie Panzer
57ea87871e Merge pull request #2276 from Athou/renovate/querydsl.version
Update querydsl.version to v7.6
2026-08-20 09:06:03 +02:00
renovate[bot]
6154d80bb9 Update querydsl.version to v7.6 2026-08-20 06:17:16 +00:00
renovate[bot]
ad85745f85 Update quarkus.version to v3.38.3 2026-08-20 00:35:52 +00:00
renovate[bot]
41fc77322c Update dependency dayjs to v1.11.22 2026-08-19 20:44:22 +00:00
Jérémie Panzer
1b83c26417 Merge pull request #2274 from Athou/renovate/docker-setup-buildx-action-4.x
Update docker/setup-buildx-action action to v4.3.0
2026-08-19 22:43:38 +02:00
Athou
10ea5f0b93 move exception to its own package 2026-08-19 22:32:37 +02:00
Jérémie Panzer
032684de68 Merge pull request #2272 from n200534/fix/issue-2016-translate-backend-errors
Translate login authentication errors
2026-08-19 22:31:29 +02:00
n200534
3efec5ce58 Use typed backend errors for translations 2026-08-20 01:11:30 +05:30
renovate[bot]
4ed32964d9 Update docker/setup-buildx-action action to v4.3.0 2026-08-19 16:16:18 +00:00
renovate[bot]
05c1d0cc6e Update ibm-semeru-runtimes:open-jdk-25.0.4.0-jre Docker digest to 27d8480 2026-08-18 22:09:48 +00:00
Jérémie Panzer
3c54924971 Merge pull request #2273 from Athou/renovate/com.puppycrawl.tools-checkstyle-14.x
Update dependency com.puppycrawl.tools:checkstyle to v14
2026-08-18 21:48:54 +02:00
renovate[bot]
e57dfc0e3f Update dependency com.puppycrawl.tools:checkstyle to v14 2026-08-18 17:49:50 +00:00
n200534
eff8bb16a0 Translate login authentication errors 2026-08-18 15:33:42 +05:30
Jérémie Panzer
87e681b71e Merge pull request #2271 from Athou/renovate/dev.cel-cel-0.x
Update dependency dev.cel:cel to v0.14.0
2026-08-18 07:13:13 +02:00
renovate[bot]
ac73ef4ea7 Update dependency dev.cel:cel to v0.14.0 2026-08-18 02:44:30 +00:00
Jérémie Panzer
20945e7443 Merge pull request #2270 from Athou/renovate/react-querybuilder
Update react-querybuilder to v8.23.0
2026-08-17 23:16:27 +02:00
Jérémie Panzer
b7b1278111 Merge pull request #2269 from Athou/renovate/org.mock-server-mockserver-junit-jupiter-7.x
Update dependency org.mock-server:mockserver-junit-jupiter to v7.6.0
2026-08-17 23:14:40 +02:00
renovate[bot]
6f9378404f Update react-querybuilder to v8.23.0 2026-08-17 20:36:06 +00:00
renovate[bot]
79787aca6e Update dependency org.mock-server:mockserver-junit-jupiter to v7.6.0 2026-08-17 20:35:51 +00:00
Athou
2d90ccf856 release 7.3.1 2026-08-17 22:32:32 +02:00
Athou
7f77cf0268 prevent Host header injection attacks 2026-08-17 22:27:46 +02:00
Jérémie Panzer
f3c390e0e0 Merge pull request #2267 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-3.x
Update dependency com.diffplug.spotless:spotless-maven-plugin to v3.10.0
2026-08-17 08:49:07 +02:00
Jérémie Panzer
1fdc471197 Merge pull request #2266 from Athou/renovate/com.puppycrawl.tools-checkstyle-13.x
Update dependency com.puppycrawl.tools:checkstyle to v13.11.0
2026-08-17 07:45:37 +02:00
renovate[bot]
ecf5d9e50e Update dependency com.diffplug.spotless:spotless-maven-plugin to v3.10.0 2026-08-17 05:44:41 +00:00
renovate[bot]
97a49e8faa Lock file maintenance 2026-08-17 00:41:26 +00:00
renovate[bot]
f5a020cdc2 Update dependency com.puppycrawl.tools:checkstyle to v13.11.0 2026-08-17 00:40:24 +00:00
renovate[bot]
1f0507ee65 Update dependency @testing-library/user-event to v14.6.4 2026-08-15 01:00:48 +00:00
renovate[bot]
393c90f334 Update react-querybuilder to v8.22.5 2026-08-14 23:10:07 +00:00
renovate[bot]
03ecc2f49b Update dependency @biomejs/biome to v2.5.8 2026-08-14 09:15:31 +00:00
renovate[bot]
17743adce6 Update quarkus.version to v3.38.2 2026-08-13 17:05:44 +00:00
renovate[bot]
126dde103a Update dependency @testing-library/jest-dom to v7.0.1 2026-08-13 00:07:02 +00:00
renovate[bot]
14a25581b4 Update react-querybuilder to v8.22.4 2026-08-11 06:18:20 +00:00
Athou
c7c95efb3a release 7.3.0 2026-08-11 08:17:05 +02:00
Athou
4c1293d357 change the default value of blockLocalAddresses 2026-08-11 08:07:56 +02:00
Athou
76a92ea44c more SSRF protection regarding IPv6 2026-08-11 07:46:02 +02:00
Jérémie Panzer
ba454322db Merge pull request #2263 from Athou/renovate/org.apache.commons-commons-collections4-4.x
fix(deps): update dependency org.apache.commons:commons-collections4 to v4.6.0
2026-08-10 16:55:55 +02:00
renovate[bot]
a3b9f471e1 fix(deps): update dependency org.apache.commons:commons-collections4 to v4.6.0 2026-08-10 13:47:04 +00:00
Athou
d58ddc888e fix flaky tests 2026-08-10 09:45:00 +02:00
Athou
fe9837c45c fix typo 2026-08-10 09:30:31 +02:00
Athou
332d126bd7 reduce log verbosity during tests 2026-08-10 09:08:15 +02:00
Athou
0c66bf2695 speed up tests 2026-08-10 09:05:11 +02:00
Athou
4d6d07c98b remove warning 2026-08-10 09:02:07 +02:00
renovate[bot]
8f7d4bfa10 chore(deps): lock file maintenance 2026-08-10 05:05:39 +00:00
renovate[bot]
7b3f39001f fix(deps): update react-querybuilder to v8.22.3 2026-08-10 03:27:17 +00:00
Jérémie Panzer
b9630809a0 Merge pull request #2262 from Athou/renovate/com.puppycrawl.tools-checkstyle-13.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.10.0
2026-08-10 05:26:27 +02:00
renovate[bot]
ce3244da5e chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.10.0 2026-08-09 21:51:02 +00:00
renovate[bot]
4067297d2a chore(deps): update dependency vite to v8.2.1 2026-08-09 17:40:42 +00:00
renovate[bot]
03c11fa181 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.6.4 2026-08-09 09:42:31 +00:00
renovate[bot]
3676e78eb9 fix(deps): update react-querybuilder to v8.22.2 2026-08-08 16:44:38 +00:00
Athou
1e08c4486f fix google reader api icon url 2026-08-08 16:06:47 +02:00
Athou
fd8bb60daa google reader api support 2026-08-08 10:22:58 +02:00
renovate[bot]
557d56ffc5 fix(deps): update react-querybuilder to v8.22.1 2026-08-08 04:30:28 +08:00
renovate[bot]
30f76a2349 chore(deps): update dependency @biomejs/biome to v2.5.7 2026-08-07 15:07:29 +00:00
renovate[bot]
cf0fa5e22e chore(deps): update dependency @testing-library/user-event to v14.6.3 2026-08-07 04:00:58 +00:00
Jérémie Panzer
f16becbd82 Merge pull request #2259 from Athou/renovate/graalvm-setup-graalvm-1.6.x
chore(deps): update graalvm/setup-graalvm action to v1.6.4
2026-08-07 06:00:37 +02:00
Jérémie Panzer
4855450ddc Merge pull request #2260 from Athou/renovate/react-querybuilder
fix(deps): update react-querybuilder to v8.22.0
2026-08-07 06:00:33 +02:00
Jérémie Panzer
0733aedce5 Merge pull request #2257 from Athou/renovate/lock-file-maintenance
chore(deps): lock file maintenance
2026-08-07 06:00:25 +02:00
renovate[bot]
399ad14d9b chore(deps): lock file maintenance 2026-08-07 02:59:35 +00:00
renovate[bot]
7881ea3c5c fix(deps): update react-querybuilder to v8.22.0 2026-08-07 02:58:54 +00:00
renovate[bot]
7e9de622da chore(deps): update graalvm/setup-graalvm action to v1.6.4 2026-08-07 02:58:46 +00:00
Athou
c6655078f2 fix build 2026-08-07 04:58:06 +02:00
Athou
b86cef9499 package-lock refresh 2026-08-06 21:47:31 +02:00
Athou
5375ab6e97 profile menu now works again on mobile when action buttons are at the bottom of the screen 2026-08-06 21:46:47 +02:00
renovate[bot]
75920a6473 fix(deps): update mantine monorepo to v9.5.1 2026-08-05 08:38:05 +00:00
renovate[bot]
f474e76866 chore(deps): update debian:13.6 docker digest to 34cd9e9 2026-08-05 04:50:23 +00:00
renovate[bot]
d0ae27c4ce fix(deps): update quarkus.version to v3.38.1 2026-08-04 17:07:29 +00:00
renovate[bot]
ab191dded6 chore(deps): update ibm-semeru-runtimes:open-jdk-25.0.4.0-jre docker digest to 02888a2 2026-08-04 10:32:11 +00:00
renovate[bot]
950b571a9f chore(deps): update ibm-semeru-runtimes docker tag to open-jdk-25.0.4.0-jre 2026-08-04 04:59:45 +00:00
Jérémie Panzer
7a153ca69a Merge pull request #2258 from Athou/renovate/node-24.x
chore(deps): update node.js to v24.19.0
2026-08-03 19:08:30 +02:00
renovate[bot]
effd8946de chore(deps): update node.js to v24.19.0 2026-08-03 16:42:20 +00:00
Athou
ae3ad3745c move global System.setProperty calls in CommaFeedApplication 2026-08-03 09:15:23 +02:00
Athou
2e1e5257b4 release 7.2.1 2026-08-03 09:06:32 +02:00
Athou
bc6e767953 prevent XXS in third party apps
CommaFeed React client already strips malicious "javascript:" urls but we might as well not store those in the database
2026-08-03 08:47:01 +02:00
Jérémie Panzer
b9eceaae73 Merge pull request #2255 from Athou/renovate/vite-8.x
chore(deps): update dependency vite to v8.2.0
2026-08-03 08:46:22 +02:00
renovate[bot]
8ad9ba7d74 chore(deps): update react monorepo 2026-08-03 01:41:07 +00:00
renovate[bot]
10bb4b7936 chore(deps): update dependency vite to v8.2.0 2026-08-02 12:46:43 +00:00
renovate[bot]
ab3127cef9 chore(deps): update dependency @vitejs/plugin-react to v6.0.5 2026-08-02 12:46:33 +00:00
Athou
5d64e2f21e correctly handle root favicons for non-default ports 2026-08-02 07:26:44 +02:00
renovate[bot]
e404c9ce3b chore(deps): update dependency npm to v12.0.2 2026-08-01 22:16:06 +00:00
Jérémie Panzer
0c5a71650c Merge pull request #2254 from Athou/renovate/axios-1.x
fix(deps): update dependency axios to v1.19.0
2026-08-02 00:15:20 +02:00
renovate[bot]
8ce9eb8537 fix(deps): update dependency axios to v1.19.0 2026-08-01 20:46:05 +00:00
renovate[bot]
1ce0e4af97 chore(deps): update dependency jsdom to v30.0.1 2026-08-01 10:11:03 +00:00
Jérémie Panzer
44ad42a8a5 Merge pull request #2252 from Athou/renovate/patch-react-router-monorepo
fix(deps): update dependency react-router-dom to v7.18.2
2026-08-01 12:09:31 +02:00
Jérémie Panzer
f213726c40 Merge pull request #2251 from Athou/renovate/react-draggable-4.7.x
fix(deps): update dependency react-draggable to v4.7.1
2026-08-01 12:09:08 +02:00
renovate[bot]
972d424846 fix(deps): update dependency react-router-dom to v7.18.2 2026-08-01 09:19:12 +00:00
renovate[bot]
6049263137 fix(deps): update dependency react-draggable to v4.7.1 2026-08-01 09:19:02 +00:00
Athou
ae2dc7f066 update google java format and let renovate know about it 2026-08-01 11:17:50 +02:00
Athou
503d129f22 increase timeout even more because tests are still flaky 2026-08-01 11:13:41 +02:00
renovate[bot]
543ec3bbb1 fix(deps): update dependency org.apache.httpcomponents.client5:httpclient5 to v5.6.3 2026-07-31 17:48:01 +00:00
renovate[bot]
bed45127c4 chore(deps): update dependency @biomejs/biome to v2.5.6 2026-07-31 15:42:20 +00:00
Jérémie Panzer
71f10b0a62 Merge pull request #2250 from Athou/renovate/patch-react-querybuilder
fix(deps): update react-querybuilder to v8.21.2
2026-07-31 07:42:57 +02:00
renovate[bot]
cb235289c4 fix(deps): update react-querybuilder to v8.21.2 2026-07-31 03:05:02 +00:00
renovate[bot]
0b07c65320 chore(deps): update dependency io.quarkiverse.playwright:quarkus-playwright to v2.3.8 2026-07-30 23:29:02 +00:00
Jérémie Panzer
868f65d7c9 Merge pull request #2249 from Athou/renovate/jsdom-30.x
chore(deps): update dependency jsdom to v30
2026-07-30 11:02:50 +02:00
Jérémie Panzer
07715383f4 Merge pull request #2248 from Athou/renovate/mantine-monorepo
fix(deps): update mantine monorepo to v9.5.0
2026-07-30 11:02:48 +02:00
renovate[bot]
29d10debdb chore(deps): update dependency jsdom to v30 2026-07-30 08:36:37 +00:00
renovate[bot]
cd640da960 fix(deps): update mantine monorepo to v9.5.0 2026-07-30 08:36:26 +00:00
Jérémie Panzer
56ecb4a2f4 Merge pull request #2247 from Athou/renovate/org.jsoup-jsoup-1.x
fix(deps): update dependency org.jsoup:jsoup to v1.23.1
2026-07-30 07:23:53 +02:00
renovate[bot]
00161fd549 fix(deps): update dependency org.jsoup:jsoup to v1.23.1 2026-07-30 04:54:33 +00:00
renovate[bot]
a602ce17cd fix(deps): update dependency io.github.hakky54:ayza-for-apache5 to v10.0.6 2026-07-29 23:04:12 +00:00
renovate[bot]
672588d08b chore(deps): update node.js to v24.18.1 2026-07-29 21:06:29 +00:00
renovate[bot]
5fa2579275 chore(deps): update dependency com.github.eirslett:frontend-maven-plugin to v2.0.2 2026-07-29 20:12:39 +00:00
Jérémie Panzer
09bc317797 Merge pull request #2246 from Athou/renovate/org.mock-server-mockserver-junit-jupiter-7.x
chore(deps): update dependency org.mock-server:mockserver-junit-jupiter to v7.5.0
2026-07-29 22:12:10 +02:00
renovate[bot]
440c1ada50 chore(deps): update dependency org.mock-server:mockserver-junit-jupiter to v7.5.0 2026-07-29 18:38:26 +00:00
Athou
911a5ca099 reorder imports using google java format 2026-07-29 20:36:03 +02:00
Jérémie Panzer
65017f6b76 Merge pull request #2244 from Athou/renovate/quarkus.version
fix(deps): update quarkus.version to v3.38.0
2026-07-29 20:33:12 +02:00
Athou
64fb5ef3a2 fix warning 2026-07-29 18:24:14 +02:00
Jérémie Panzer
dda389a50f Merge pull request #2245 from Athou/renovate/react-querybuilder
fix(deps): update react-querybuilder to v8.21.0
2026-07-29 17:15:10 +02:00
renovate[bot]
419ad4fb6a fix(deps): update react-querybuilder to v8.21.0 2026-07-29 14:10:05 +00:00
Jérémie Panzer
ebae46f06b Merge pull request #2243 from Athou/renovate/docker-login-action-4.x
chore(deps): update docker/login-action action to v4.6.0
2026-07-29 16:09:58 +02:00
renovate[bot]
ac25accb31 fix(deps): update quarkus.version to v3.38.0 2026-07-29 14:09:50 +00:00
Jérémie Panzer
3c7eb90e50 Merge pull request #2242 from Athou/renovate/com.diffplug.spotless-spotless-maven-plugin-3.x
chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.9.0
2026-07-29 16:09:03 +02:00
renovate[bot]
4b3973f3fa chore(deps): update docker/login-action action to v4.6.0 2026-07-29 12:34:35 +00:00
renovate[bot]
6ddbe40c3c chore(deps): update dependency com.diffplug.spotless:spotless-maven-plugin to v3.9.0 2026-07-29 12:34:30 +00:00
Jérémie Panzer
d5164750e4 Merge pull request #2241 from Athou/renovate/linguijs-monorepo
fix(deps): update linguijs monorepo to v6.6.0
2026-07-27 17:40:01 +02:00
renovate[bot]
822fbd8add fix(deps): update linguijs monorepo to v6.6.0 2026-07-27 14:46:27 +00:00
Jérémie Panzer
3a341d0707 Merge pull request #2240 from Athou/renovate/com.puppycrawl.tools-checkstyle-13.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.9.0
2026-07-27 07:42:59 +02:00
renovate[bot]
23884fcbda chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.9.0 2026-07-27 05:15:46 +00:00
renovate[bot]
3b16674f98 chore(deps): lock file maintenance 2026-07-27 00:51:21 +00:00
renovate[bot]
d5eb3e1bb1 chore(deps): update dependency vite-plugin-checker to v0.14.5 2026-07-25 13:00:37 +00:00
renovate[bot]
8d47b38fd4 chore(deps): update dependency @vitejs/plugin-react to v6.0.4 2026-07-25 05:45:24 +00:00
renovate[bot]
04fb3282fa fix(deps): update react monorepo to v19.2.8 2026-07-25 00:34:50 +00:00
renovate[bot]
bcce130b82 chore(deps): update docker/login-action action to v4.5.1 2026-07-24 20:05:24 +00:00
renovate[bot]
e5d336f6ba fix(deps): update mantine monorepo to v9.4.2 2026-07-24 11:08:55 +00:00
renovate[bot]
2d741f6e1e chore(deps): update dependency @biomejs/biome to v2.5.5 2026-07-24 10:03:13 +00:00
Jérémie Panzer
2968dff118 Merge pull request #2237 from Athou/renovate/major-testing-library-monorepo
chore(deps): update dependency @testing-library/jest-dom to v7
2026-07-23 22:25:02 +02:00
renovate[bot]
0c244ec154 chore(deps): update dependency @testing-library/jest-dom to v7 2026-07-23 19:50:05 +00:00
Jérémie Panzer
34cd337992 Merge pull request #2235 from Athou/renovate/monaco-editor-0.x
fix(deps): update dependency monaco-editor to v0.56.0
2026-07-23 21:49:33 +02:00
Jérémie Panzer
1703cb7b93 Merge pull request #2236 from Athou/renovate/docker-login-action-4.x
chore(deps): update docker/login-action action to v4.5.0
2026-07-23 21:00:06 +02:00
Athou
dc89faa4a1 adapt to new paths 2026-07-23 20:58:07 +02:00
renovate[bot]
3eccfe8ccc chore(deps): update docker/login-action action to v4.5.0 2026-07-23 17:29:45 +00:00
renovate[bot]
6e34f6831c fix(deps): update dependency monaco-editor to v0.56.0 2026-07-23 14:01:52 +00:00
renovate[bot]
b7ebcd6a23 fix(deps): update quarkus.version to v3.37.4 2026-07-23 10:00:31 +00:00
Jérémie Panzer
8b7efe056d Merge pull request #2234 from Athou/renovate/fontsource-monorepo
fix(deps): update dependency @fontsource/open-sans to v5.3.0
2026-07-22 08:33:33 +02:00
renovate[bot]
87cb392516 fix(deps): update dependency @fontsource/open-sans to v5.3.0 2026-07-22 05:25:49 +00:00
Jérémie Panzer
aa11cb48f2 Merge pull request #2233 from Athou/renovate/querydsl.version
fix(deps): update querydsl.version to v7.5
2026-07-21 23:31:17 +02:00
renovate[bot]
36a29a393c fix(deps): update querydsl.version to v7.5 2026-07-21 21:08:45 +00:00
renovate[bot]
99f1b45866 chore(deps): update actions/checkout action to v7.0.1 2026-07-21 02:00:56 +00:00
renovate[bot]
9e8d529af3 chore(deps): lock file maintenance 2026-07-20 03:58:17 +00:00
renovate[bot]
bb80641b40 chore(deps): update dependency vite to v8.1.5 2026-07-19 10:03:19 +00:00
renovate[bot]
a2ed16c6fd chore(deps): update dependency @biomejs/biome to v2.5.4 2026-07-18 04:35:49 +00:00
renovate[bot]
4f10f57837 fix(deps): update quarkus.version to v3.37.3 2026-07-15 21:27:37 +00:00
Jérémie Panzer
28f40cd6fe Merge pull request #2230 from Athou/renovate/graalvm-setup-graalvm-1.6.x
chore(deps): update graalvm/setup-graalvm action to v1.6.3
2026-07-14 22:21:04 +02:00
renovate[bot]
89a84a0c83 chore(deps): update graalvm/setup-graalvm action to v1.6.3 2026-07-14 10:01:24 +00:00
Jérémie Panzer
ebcda50a34 Merge pull request #2229 from Athou/renovate/actions-setup-node-7.x
chore(deps): update actions/setup-node action to v7
2026-07-14 09:09:34 +02:00
renovate[bot]
8640e62b77 chore(deps): update actions/setup-node action to v7 2026-07-14 06:21:50 +00:00
Jérémie Panzer
d0418eea89 Merge pull request #2227 from Athou/renovate/actions-setup-node-6.x
chore(deps): update actions/setup-node action to v6.5.0
2026-07-14 08:20:45 +02:00
Jérémie Panzer
41ba067daf Merge pull request #2228 from Athou/renovate/debian-13.x
chore(deps): update debian docker tag to v13.6
2026-07-14 08:19:52 +02:00
renovate[bot]
53346997b6 chore(deps): update debian docker tag to v13.6 2026-07-14 05:14:26 +00:00
renovate[bot]
87a632761e chore(deps): update actions/setup-node action to v6.5.0 2026-07-14 05:14:22 +00:00
renovate[bot]
998ebc43a3 chore(deps): update dependency npm to v12.0.1 2026-07-13 19:32:59 +00:00
renovate[bot]
945e312c41 chore(deps): update dependency vite to v8.1.4 2026-07-12 07:51:07 +00:00
Jérémie Panzer
963a562100 Merge pull request #2224 from Athou/renovate/typescript-7.x
chore(deps): update dependency typescript to v7
2026-07-12 09:49:47 +02:00
Athou
4be961b68b temporary disable checker plugin until TypeScript 7 exposes a stable api 2026-07-12 08:59:24 +02:00
Jérémie Panzer
02a9140c13 Merge pull request #2226 from Athou/renovate/com.puppycrawl.tools-checkstyle-13.x
chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.8.0
2026-07-12 08:52:40 +02:00
renovate[bot]
5ea60ce6d6 chore(deps): update dependency com.puppycrawl.tools:checkstyle to v13.8.0 2026-07-12 06:03:35 +00:00
Jérémie Panzer
e9e7be0fc6 Merge pull request #2225 from Athou/renovate/npm-12.x
chore(deps): update dependency npm to v12
2026-07-12 04:39:00 +02:00
renovate[bot]
60c30f2683 chore(deps): update dependency npm to v12 2026-07-11 23:25:34 +00:00
renovate[bot]
a17e69d37d chore(deps): update dependency typescript to v7 2026-07-11 17:37:46 +00:00
renovate[bot]
157f75d33e chore(deps): update dependency @biomejs/biome to v2.5.3 2026-07-11 10:52:37 +00:00
Athou
30a14c73ff specify that docker/podman can be used if graalvm is not found 2026-07-11 09:09:27 +02:00
240 changed files with 5216 additions and 1738 deletions

View File

@@ -23,20 +23,20 @@ jobs:
steps:
# Checkout
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
# Setup
- name: Set up GraalVM
uses: graalvm/setup-graalvm@186d0493a2df5eb62df5ecc498883d18fd58c303 # v1.6.2
uses: graalvm/setup-graalvm@5298d94fb55a4f185c602eeac5de1b553882abe2 # v1.6.4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: "graalvm"
cache: "maven"
- name: Set up NodeJS cache
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
cache: "npm"
cache-dependency-path: 'commafeed-client/package-lock.json'
@@ -104,7 +104,7 @@ jobs:
steps:
# Checkout
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
@@ -113,7 +113,7 @@ jobs:
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0
- name: Install required packages
run: sudo apt-get install -y rename unzip
@@ -141,7 +141,7 @@ jobs:
# Docker
- name: Login to Container Registry
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
if: ${{ env.DOCKERHUB_USERNAME != '' }}
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
@@ -221,7 +221,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
@@ -255,7 +255,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0

View File

@@ -1,5 +1,31 @@
# Changelog
## [7.3.2]
- Prevent users from starring/tagging entries that are not theirs and subsequently reading them (GHSA-prfv-88mm-5gpg)
## [7.3.1]
- Prevent Host header injection attacks on the password recovery endpoint. A new setting
`commafeed.password-recovery-public-base-url` has been added to specify the base URL to use in password recovery
(GHSA-hp8h-jqfm-v7x5)
emails. This setting is only required when the password recovery feature is enabled, which is not the default.
## [7.3.0]
- Add support for the Google Reader API for native mobile apps that don't support the Fever API
- The profile menu now works again on mobile when action buttons are at the bottom of the screen
- More SSRF protection regarding IPv6 (GHSA-q5qw-345w-55xg)
- Changed the default value of `blockLocalAddresses` to make CommaFeed more secure out-of-the-box. See the "Access to
local address blocked" section of the README if you subscribe to feeds that are only available on your local network.
## [7.2.1]
- correctly handle favicons hosted at the root of the domain for feeds with non-default ports
- prevent XXS injections in third party apps. The CommaFeed React client was already stripping malicious "javascript:"
URLs, they are now filtered during feed parsing and no longer stored in the database/served through the REST API
(GHSA-44pq-9929-f8mq)
## [7.2.0]
- Add support for icons declared in feeds. This is useful for feeds exposed by RSS bridges (#2048)
@@ -8,26 +34,36 @@
- Small performance improvements to the feed refresh engine
- Removed the Pocket sharing feature because the Pocket service has been discontinued
- Prevent the image proxy feature to access any URL to avoid SSRF attacks
- Strengthened the SSRF protection by also blocking ULA and CGNAT ranges
- Prevent DDOS attacks by filtering OPML files during imports
- Strengthened the SSRF protection by also blocking ULA and CGNAT ranges (GHSA-hgrr-mjfp-gmr6)
- Prevent DDOS attacks by filtering OPML files during imports (GHSA-83jp-rww3-57rr)
## [7.1.0]
- Display the unread count in the header on mobile, since the tree is hidden by default and the unread count is not visible otherwise (#2055)
- Display the unread count in the header on mobile, since the tree is hidden by default and the unread count is not
visible otherwise (#2055)
- The feed refresh engine is now a little bit more performant (#2089)
- On shutdown, give the feed refresh engine some time to finish refreshing feeds before killing it. This is controlled by the new `commafeed.shutdown-timeout` setting, which defaults to 2 seconds
- On shutdown, give the feed refresh engine some time to finish refreshing feeds before killing it. This is controlled
by the new `commafeed.shutdown-timeout` setting, which defaults to 2 seconds
## [7.0.0]
- Replaced the JEXL filter expression for marking feed entries as read automatically with a user-friendly visual query builder. Expressions are now evaluated with Common Expression Language, which is safer than JEXL and sanboxed by default.
- Added a per-feed setting for sending push notifications to ntfy, Gotify or Pushover when new feed entries are discovered (#1610)
- Replaced the JEXL filter expression for marking feed entries as read automatically with a user-friendly visual query
builder. Expressions are now evaluated with Common Expression Language, which is safer than JEXL and sanboxed by
default.
- Added a per-feed setting for sending push notifications to ntfy, Gotify or Pushover when new feed entries are
discovered (#1610)
- Added a per-feed setting for marking entries as read after a number of days (#2041)
- The default value of `commafeed.http-client.block-local-addresses` is now false, allowing users to subscribe to feeds only available on their local network. This may be a security risk (SSRF) if your instance is accessible by untrusted users, so you may want to set it to true if you host a public instance of CommaFeed with user registeration enabled.
- When `commafeed.http-client.block-local-addresses` is enabled, SSRF is now also mitigated by blocking public websites redirecting to local ones.
- The default value of `commafeed.http-client.block-local-addresses` is now false, allowing users to subscribe to feeds
only available on their local network. This may be a security risk (SSRF) if your instance is accessible by untrusted
users, so you may want to set it to true if you host a public instance of CommaFeed with user registeration enabled.
- When `commafeed.http-client.block-local-addresses` is enabled, SSRF is now also mitigated by blocking public websites
redirecting to local ones.
## [6.2.0]
- Starred entries are no longer deleted after a certain amount of time, they are now kept indefinitely. The new `commafeed.database.cleanup.keep-starred-entries` setting can be disabled to restore the previous behavior if you want to keep deleting starred entries during normal entries cleanup (#1581)
- Starred entries are no longer deleted after a certain amount of time, they are now kept indefinitely. The new
`commafeed.database.cleanup.keep-starred-entries` setting can be disabled to restore the previous behavior if you want
to keep deleting starred entries during normal entries cleanup (#1581)
## [6.1.1]
@@ -35,16 +71,21 @@
## [6.1.0]
- When clicking on the password reset link, a random password is no longer generated automatically. The user is now redirected to a page where they can set their own password (#2023)
- When clicking on the password reset link, a random password is no longer generated automatically. The user is now
redirected to a page where they can set their own password (#2023)
- Use browser preferred language instead of English when using CommaFeed for the first time (#2018)
- The profile menu is now closed when scrolling the page (#2019)
- The "disable pull to refresh" feature is now disabled by default (#2030)
## [6.0.0]
- When booting CommaFeed for the first time, the default "admin" account is no longer created automatically. A setup wizard will guide you through the creation of an admin account
- Default password complexity requirements have been lowered for local network deployments, where strict password rules are often unnecessary. The `commafeed.users.strict-password-policy` setting has been replaced by `commafeed.users.minimum-password-length` with a default value of `4` (#1916)
- Email addresses are no longer required when creating users and when they update their profile. The `commafeed.users.email-address-required` setting has been added to restore the previous behavior (#1914)
- When booting CommaFeed for the first time, the default "admin" account is no longer created automatically. A setup
wizard will guide you through the creation of an admin account
- Default password complexity requirements have been lowered for local network deployments, where strict password rules
are often unnecessary. The `commafeed.users.strict-password-policy` setting has been replaced by
`commafeed.users.minimum-password-length` with a default value of `4` (#1916)
- Email addresses are no longer required when creating users and when they update their profile. The
`commafeed.users.email-address-required` setting has been added to restore the previous behavior (#1914)
- Java 25+ is now required to build and run CommaFeed
## [5.12.1]
@@ -74,15 +115,18 @@
## [5.10.0]
- Add an indicator next to each feed's unread count in the tree to show when new entries are discovered while the app is open (#1762)
- Add an indicator next to each feed's unread count in the tree to show when new entries are discovered while the app is
open (#1762)
- Feeds with uppercase HTTP:// or HTTPS:// URLs are now correctly handled again
- The aarch64 native executable now also works on the Raspberry Pi 5 (#1795)
- Improve general performance of the UI by reducing the number of re-renders, especially when a lot of entries are displayed (#1087)
- Improve general performance of the UI by reducing the number of re-renders, especially when a lot of entries are
displayed (#1087)
## [5.9.0]
- A lot of CSS classes have been added to the elements of the application to ease custom CSS rules (#1757)
- Added a link in the README to the [documentation](https://athou.github.io/commafeed/documentation/custom-css/) of the new CSS classes
- Added a link in the README to the [documentation](https://athou.github.io/commafeed/documentation/custom-css/) of the
new CSS classes
- Static resources are now cached for much longer (#1782)
## [5.8.0]
@@ -91,7 +135,8 @@
- A font size slider is now available to change the size of the text of feed entries (#1462)
- The "mark all as read" confirmation setting now also applies to the "shift+a" keyboard shortcut (#1744)
- CommaFeed wil try to match the language of the browser before defaulting to english (#1767)
- The default value for the number of entries to keep above the selected entry when scrolling is now 1 instead of 0 to match what other feed readers do
- The default value for the number of entries to keep above the selected entry when scrolling is now 1 instead of 0 to
match what other feed readers do
## [5.7.0]
@@ -110,14 +155,22 @@
## [5.6.0]
- To better respect the bandwidth of feed owners, the default value of `commafeed.feed-refresh.interval-empirical` is now true. This means feeds no longer refresh exactly every 5 minutes (the default value of `commafeed.feed-refresh.interval`) but between 5 minutes and 4 hours (the default value of the new `commafeed.feed-refresh.max-interval` setting). The interval is calculated based on feed activity, so highly active feeds refresh more often (#1677)
- To better respect the bandwidth of feed owners, the default value of `commafeed.feed-refresh.interval-empirical` is
now true. This means feeds no longer refresh exactly every 5 minutes (the default value of
`commafeed.feed-refresh.interval`) but between 5 minutes and 4 hours (the default value of the new
`commafeed.feed-refresh.max-interval` setting). The interval is calculated based on feed activity, so highly active
feeds refresh more often (#1677)
- Many previously hardcoded values used in feed refresh interval calculation are now exposed as settings (#1677)
- Access to local addresses is now blocked to mitigate server-side request forgery (SSRF) attacks, which could potentially expose internal resources. You might want to disable the new `commafeed.http-client.block-local-addresses` setting if you subscribe to feeds only available on your local network and you trust all your users
- If a feed responds with a "429 - Too many requests" response, a backoff mechanism is triggered when the response does not contain a "Retry-After" header
- Access to local addresses is now blocked to mitigate server-side request forgery (SSRF) attacks, which could
potentially expose internal resources. You might want to disable the new `commafeed.http-client.block-local-addresses`
setting if you subscribe to feeds only available on your local network and you trust all your users
- If a feed responds with a "429 - Too many requests" response, a backoff mechanism is triggered when the response does
not contain a "Retry-After" header
## [5.5.0]
- CommaFeed now honors the Retry-After response header and will not try to refresh a feed sooner than the value of this header
- CommaFeed now honors the Retry-After response header and will not try to refresh a feed sooner than the value of this
header
- Audio enclosures (e.g. podcasts) now fill available entry width
- Fix an issue with some labels not correctly internationalized
@@ -134,8 +187,10 @@
## [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)
- 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]
@@ -162,19 +217,22 @@
- Added an option to keep a number of entries above the selected entry when scrolling
- Added a cache to the HTTP client to reduce the number of requests made to feeds when subscribing (#1431)
- Feeds are no longer refreshed between the moment its last user unsubscribes and the moment the feed is cleaned up (every hour)
- Feeds are no longer refreshed between the moment its last user unsubscribes and the moment the feed is cleaned up
(every hour)
- Fixed an issue that could cause entries to not correctly load when using keyboard navigation (#1557)
## [5.1.1]
- Fixed database migration issue when upgrading from 5.0.0 to 5.1.0 on MariaDB (#1544)
- When feeds without unread entries are hidden from the tree, the feed is displayed in the tree until another one is selected (#1543)
- When feeds without unread entries are hidden from the tree, the feed is displayed in the tree until another one is
selected (#1543)
## [5.1.0]
- Added a setting for showing/hiding unread count in the browser's tab title/favicon (#1518)
- Fixed an issue that could prevent the app from starting on some systems (#1532)
- Added a cache busting filter for the webapp index.html and openapi documentation to make sure they are always up to date
- Added a cache busting filter for the webapp index.html and openapi documentation to make sure they are always up to
date
- Reduced database cleanup log verbosity
## [5.0.2]
@@ -189,9 +247,9 @@
## [5.0.0]
CommaFeed is now powered by Quarkus instead of Dropwizard. Read the rationale behind this change in
the [announcement](https://github.com/Athou/commafeed/discussions/1517).
The gist of it is that CommaFeed can now be compiled to a native binary, resulting in blazing fast startup times (around
0.3s) and very low memory footprint (< 50M).
the [announcement](https://github.com/Athou/commafeed/discussions/1517). The gist of it is that CommaFeed can now be
compiled to a native binary, resulting in blazing fast startup times (around 0.3s) and very low memory footprint (<
50M).
- CommaFeed now has a different package for each supported database.
- If you are deploying CommaFeed with a precompiled package, please
@@ -247,8 +305,8 @@ The gist of it is that CommaFeed can now be compiled to a native binary, resulti
- add a button in the entry headers to open links in a new tab (#1333)
- add two options in the settings to toggle those buttons
- accept .opml file extension when importing and export with the .opml extension
- the "mark as read" option is no longer shown in the context menu for entries that are too old to be marked as read (
older than `keepStatusDays`) (#1303)
- the "mark as read" option is no longer shown in the context menu for entries that are too old to be marked as read
(older than `keepStatusDays`) (#1303)
## [4.3.3]
@@ -292,9 +350,8 @@ The gist of it is that CommaFeed can now be compiled to a native binary, resulti
- it is now possible to open the sidebar on mobile by swiping to the right (#1098)
- swiping to mark entries as read/unread changed from swiping right to left because swiping right now opens the sidebar
- the full hierarchy of categories are now displayed in the category dropdown (#1045)
- added a setting `maxEntriesAgeDays` to delete old entries based on their age during database cleanup.
The setting is disabled by default for existing installations, except for the docker image where it is enabled and set
to 365 days
- added a setting `maxEntriesAgeDays` to delete old entries based on their age during database cleanup. The setting is
disabled by default for existing installations, except for the docker image where it is enabled and set to 365 days
- if user registrations are disabled on your instance which is the default behavior, users are redirected on the login
page instead of the welcome page when not logged in (#1185)
- the sidebar resizer is no longer shown in the middle of the screen on mobile
@@ -320,8 +377,8 @@ The gist of it is that CommaFeed can now be compiled to a native binary, resulti
request, reducing CPU usage
- updated UI library Mantine to 7.0, improving performance
- the h2 embedded database is now compacted on shutdown to reclaim unused space
- the admin connector on port 8084 is now disabled in config.yml.example. Disabling it in your config.yml is
recommended (see https://github.com/Athou/commafeed/commit/929df60f09cce56020b0962ab111cd8349b271b0)
- the admin connector on port 8084 is now disabled in config.yml.example. Disabling it in your config.yml is recommended
(see https://github.com/Athou/commafeed/commit/929df60f09cce56020b0962ab111cd8349b271b0)
- migrated documentation from swagger 2 to openapi 3
- added a GET method to the fever api to indicate that the endpoint is working correctly when accessed from a browser
- the websocket connection can now be disabled, the websocket ping interval and the tree reload interval can now be
@@ -563,7 +620,6 @@ The gist of it is that CommaFeed can now be compiled to a native binary, resulti
## [2.0.0]
- The backend has been completely rewritten using Dropwizard instead of TomEE, resulting in a lot less memory
consumption and better overall performances.
See the README on how to build CommaFeed from now on.
consumption and better overall performances. See the README on how to build CommaFeed from now on.
- CommaFeed should no longer fetch the same feed multiple times in a row
- Users can use their username or email to log in

View File

@@ -15,7 +15,7 @@ Google Reader inspired self-hosted RSS reader, based on Quarkus and React/TypeSc
- Supports thousands of users and millions of feeds
- OPML import/export
- REST API
- Fever-compatible API for native mobile apps
- Fever and Google Reader API for native mobile apps
- Can automatically mark articles as read based on user-defined rules
- Push notifications when new articles are published
- Highly customizable with [custom CSS](https://athou.github.io/commafeed/documentation/custom-css) and JavaScript
@@ -70,8 +70,8 @@ memory usage.
./mvnw clean package [-P<database> [-Pnative]] [-DskipTests]
- `<database>` can be one of `h2`, `postgresql`, `mysql` or `mariadb`. The default is `h2`.
- `-Pnative` compiles the application to native code. This requires GraalVM to be installed (`GRAALVM_HOME` environment
variable pointing to a GraalVM installation).
- `-Pnative` compiles the application to native code. This requires either GraalVM to be installed (`GRAALVM_HOME` environment
variable pointing to a GraalVM installation) or a container environment to be available (docker/podman/...).
- `-DskipTests` to speed up the build process by skipping tests.
When the build is complete:
@@ -159,6 +159,14 @@ named [Semeru](https://developer.ibm.com/languages/java/semeru-runtimes/download
This is the JVM used in
the [Docker image](https://github.com/Athou/commafeed/blob/master/commafeed-server/src/main/docker/Dockerfile.jvm).
## FAQ
### Getting "Access to local address blocked" when adding a feed
CommaFeed blocks access to local resources by default to prevent [SSRF](https://en.wikipedia.org/wiki/Server-side_request_forgery) attacks.
If you want to subscribe to feeds that are only available on your local network, you can disable this security measure by setting the `commafeed.http-client.block-local-addresses` variable to `false`.
Do this only if you trust all users of your CommaFeed instance not to access private resources.
## Translation
Files for internationalization are

View File

@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.5.2/schema.json",
"$schema": "https://biomejs.dev/schemas/2.5.9/schema.json",
"formatter": {
"indentStyle": "space",
"indentWidth": 4,

File diff suppressed because it is too large Load Diff

View File

@@ -16,36 +16,36 @@
},
"dependencies": {
"@emotion/react": "11.14.0",
"@fontsource/open-sans": "5.2.7",
"@lingui/core": "6.5.0",
"@lingui/react": "6.5.0",
"@mantine/core": "9.4.1",
"@mantine/dates": "9.4.1",
"@mantine/form": "9.4.1",
"@mantine/hooks": "9.4.1",
"@mantine/modals": "9.4.1",
"@mantine/notifications": "9.4.1",
"@mantine/spotlight": "9.4.1",
"@fontsource/open-sans": "5.3.0",
"@lingui/core": "6.6.0",
"@lingui/react": "6.6.0",
"@mantine/core": "9.5.1",
"@mantine/dates": "9.5.1",
"@mantine/form": "9.5.1",
"@mantine/hooks": "9.5.1",
"@mantine/modals": "9.5.1",
"@mantine/notifications": "9.5.1",
"@mantine/spotlight": "9.5.1",
"@monaco-editor/react": "4.7.0",
"@react-querybuilder/mantine": "8.20.2",
"@react-querybuilder/mantine": "8.23.0",
"@reduxjs/toolkit": "2.12.0",
"@rolldown/plugin-babel": "0.2.3",
"axios": "1.18.1",
"dayjs": "1.11.21",
"axios": "1.19.0",
"dayjs": "1.11.23",
"escape-string-regexp": "5.0.0",
"interweave": "13.1.1",
"monaco-editor": "0.55.1",
"monaco-editor": "0.56.0",
"mousetrap": "1.6.5",
"react": "19.2.7",
"react": "19.2.8",
"react-async-hook": "4.0.0",
"react-contexify": "6.0.0",
"react-dom": "19.2.7",
"react-draggable": "4.7.0",
"react-dom": "19.2.8",
"react-draggable": "4.7.1",
"react-icons": "5.7.0",
"react-infinite-scroller": "1.2.6",
"react-querybuilder": "8.20.2",
"react-querybuilder": "8.23.0",
"react-redux": "9.3.0",
"react-router-dom": "7.18.1",
"react-router-dom": "7.18.2",
"react-swipeable": "7.0.2",
"style-to-object": "2.0.2",
"throttle-debounce": "5.0.2",
@@ -54,31 +54,32 @@
"websocket-heartbeat-js": "1.1.3"
},
"devDependencies": {
"@biomejs/biome": "2.5.2",
"@lingui/babel-plugin-lingui-macro": "6.5.0",
"@lingui/cli": "6.5.0",
"@lingui/vite-plugin": "6.5.0",
"@testing-library/jest-dom": "6.9.1",
"@babel/types": "^8.0.4",
"@biomejs/biome": "2.5.9",
"@lingui/babel-plugin-lingui-macro": "6.6.0",
"@lingui/cli": "6.6.0",
"@lingui/vite-plugin": "6.6.0",
"@testing-library/jest-dom": "7.0.1",
"@testing-library/react": "16.3.2",
"@testing-library/user-event": "14.6.1",
"@testing-library/user-event": "14.6.5",
"@types/mousetrap": "1.6.15",
"@types/react": "19.2.17",
"@types/react-dom": "19.2.3",
"@types/react": "19.2.18",
"@types/react-dom": "19.2.4",
"@types/react-infinite-scroller": "1.2.5",
"@types/throttle-debounce": "5.0.2",
"@types/tinycon": "0.6.7",
"@vitejs/plugin-react": "6.0.3",
"@vitejs/plugin-react": "6.0.5",
"babel-plugin-react-compiler": "1.0.0",
"jsdom": "29.1.1",
"typescript": "6.0.3",
"vite": "8.1.3",
"vite-plugin-checker": "0.14.4",
"vitest": "4.1.10",
"jsdom": "30.0.1",
"typescript": "7.0.2",
"vite": "8.2.1",
"vite-plugin-checker": "0.14.5",
"vitest": "4.1.11",
"yaml": "2.9.0"
},
"overrides": {
"react-infinite-scroller": {
"react": "19.2.7"
"react": "19.2.8"
}
}
}

View File

@@ -6,16 +6,16 @@
<parent>
<groupId>com.commafeed</groupId>
<artifactId>commafeed</artifactId>
<version>7.2.0</version>
<version>7.3.2</version>
</parent>
<artifactId>commafeed-client</artifactId>
<name>CommaFeed Client</name>
<properties>
<!-- renovate: datasource=node-version depName=node -->
<node.version>v24.18.0</node.version>
<node.version>v24.19.0</node.version>
<!-- renovate: datasource=npm depName=npm -->
<npm.version>11.18.0</npm.version>
<npm.version>12.0.2</npm.version>
</properties>
<build>
@@ -23,7 +23,7 @@
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>2.0.1</version>
<version>2.0.2</version>
<?m2e ignore?>
<executions>
<execution>

View File

@@ -0,0 +1,36 @@
import { i18n } from "@lingui/core"
import type { AxiosError } from "axios"
import { afterEach, describe, expect, it, vi } from "vitest"
import { errorToStrings } from "./client"
const axiosError = (status: number, data: unknown) =>
({
isAxiosError: true,
response: { status, data },
}) as AxiosError
describe("errorToStrings", () => {
afterEach(() => vi.restoreAllMocks())
it("translates known application error types", () => {
vi.spyOn(i18n, "_").mockReturnValue("Translated authentication error")
const error = axiosError(401, {
type: "WRONG_USERNAME_OR_PASSWORD",
message: "wrong username or password",
})
expect(errorToStrings(error)).toEqual(["Translated authentication error"])
})
it("preserves backend messages for unexpected errors", () => {
const error = axiosError(500, { message: "unexpected error" })
expect(errorToStrings(error)).toEqual(["unexpected error"])
})
it("preserves backend messages for unknown application error types", () => {
const error = axiosError(400, { type: "UNKNOWN_ERROR", message: "unknown error" })
expect(errorToStrings(error)).toEqual(["unknown error"])
})
})

View File

@@ -1,3 +1,5 @@
import { i18n, type MessageDescriptor } from "@lingui/core"
import { msg } from "@lingui/core/macro"
import axios, { type AxiosError } from "axios"
import type {
AddCategoryRequest,
@@ -6,6 +8,8 @@ import type {
Category,
CategoryModificationRequest,
CollapseRequest,
CommaFeedApplicationError,
CommaFeedExceptionType,
Entries,
FeedInfo,
FeedInfoRequest,
@@ -31,6 +35,10 @@ import type {
UserModel,
} from "./types"
const applicationErrorMessages = {
WRONG_USERNAME_OR_PASSWORD: msg`Wrong username or password`,
} satisfies Record<CommaFeedExceptionType, MessageDescriptor>
const axiosInstance = axios.create({ baseURL: "./rest", withCredentials: true })
axiosInstance.interceptors.response.use(
response => response,
@@ -128,14 +136,25 @@ export const errorToStrings = (err: unknown) => {
let strings: string[] = []
if (axios.isAxiosError(err) && err.response) {
if (typeof err.response.data === "string") strings.push(err.response.data)
if (isMessageError(err)) strings.push(err.response.data.message)
if (isMessageArrayError(err)) strings = [...strings, ...err.response.data.errors]
if (isCommaFeedApplicationError(err)) {
strings.push(i18n._(applicationErrorMessages[err.response.data.type]))
} else {
if (typeof err.response.data === "string") strings.push(err.response.data)
if (isMessageError(err)) strings.push(err.response.data.message)
if (isMessageArrayError(err)) strings = [...strings, ...err.response.data.errors]
}
}
return strings
}
function isCommaFeedApplicationError(err: AxiosError): err is AxiosError<CommaFeedApplicationError> {
const data = err.response?.data
if (!data || typeof data !== "object" || !("type" in data)) return false
const type = data.type
return typeof type === "string" && Object.hasOwn(applicationErrorMessages, type)
}
function isMessageError(err: AxiosError): err is AxiosError<{ message: string }> {
return !!err.response && !!err.response.data && typeof err.response.data === "object" && "message" in err.response.data
}

View File

@@ -166,7 +166,6 @@ export const starEntry = createAppAsyncThunk(
(arg: { entry: Entry; starred: boolean }) => {
client.entry.star({
id: arg.entry.id,
feedId: +arg.entry.feedId,
starred: arg.starred,
})
},

View File

@@ -297,7 +297,6 @@ export interface LocalSettings {
export interface StarRequest {
id: string
feedId: number
starred: boolean
}
@@ -338,3 +337,10 @@ export interface AuthenticationError {
message: string
allowRegistrations: boolean
}
export type CommaFeedExceptionType = "WRONG_USERNAME_OR_PASSWORD"
export interface CommaFeedApplicationError {
type: CommaFeedExceptionType
message: string
}

View File

@@ -7,11 +7,11 @@ const init = async () => {
async getWorker(_, label) {
let worker: typeof import("*?worker")
if (label === "css") {
worker = await import("monaco-editor/esm/vs/language/css/css.worker?worker")
worker = await import("monaco-editor/language/css/css.worker?worker")
} else if (label === "javascript") {
worker = await import("monaco-editor/esm/vs/language/typescript/ts.worker?worker")
worker = await import("monaco-editor/language/typescript/ts.worker?worker")
} else {
worker = await import("monaco-editor/esm/vs/editor/editor.worker?worker")
worker = await import("monaco-editor/editor/editor.worker?worker")
}
return new worker.default()
},

View File

@@ -124,7 +124,7 @@ export function ProfileMenu(props: Readonly<ProfileMenuProps>) {
}
return (
<Menu position="bottom-end" closeOnItemClick={false} opened={opened} onChange={setOpened}>
<Menu position="bottom-end" closeOnItemClick={false} opened={opened} onChange={setOpened} preventPositionChangeWhenVisible={false}>
<Menu.Target>{props.control}</Menu.Target>
<Menu.Dropdown>
{profile && <Menu.Label>{profile.name}</Menu.Label>}

View File

@@ -91,8 +91,8 @@ export function ProfileSettings() {
label={<Trans>API key</Trans>}
description={
<Trans>
This is your API key. It can be used for some read-only API operations and grants access to the Fever API.
Use the form at the bottom of the page to generate a new API key
This is your API key. It can be used for some read-only API operations and grants access to the Fever API
and the Google Reader API. Use the form at the bottom of the page to generate a new API key
</Trans>
}
readOnly
@@ -130,6 +130,22 @@ export function ProfileSettings() {
</Box>
</Input.Wrapper>
<Input.Wrapper
label={<Trans>Google Reader API</Trans>}
description={
<Trans>
CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible
mobile client. Login with your username and your <u>API key</u>.
</Trans>
}
>
<Box>
<Anchor href="rest/googlereader" target="_blank">
<Trans>Google Reader API URL</Trans>
</Anchor>
</Box>
</Input.Wrapper>
<Divider />
<PasswordInput

View File

@@ -210,6 +210,10 @@ msgstr "إصدار إضافة متصفح CommaFeed هو {browserExtensionVersion
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed متوافق مع Fever API. استخدم عنوان URL التالي في تطبيق الهاتف المتوافق مع Fever. قم بتسجيل الدخول باستخدام اسم المستخدم و <0>مفتاح API</0> الخاص بك."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed متوافق مع Google Reader API. استخدم عنوان URL التالي في تطبيق الهاتف المتوافق مع Google Reader. قم بتسجيل الدخول باستخدام اسم المستخدم و <0>مفتاح API</0> الخاص بك."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed التالي العنصر غير المقروء"
@@ -454,6 +458,14 @@ msgstr "انتقل إلى وثائق API."
msgid "Goodies"
msgstr "الأشياء الجيدة"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "عنبي"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "تحتوي هذه الخلاصة على فلتر قديم لا يمكن تحريره ولا يتم تطبيقه. يرجى إعادة إنشاء الفلتر باستخدام محرر التعبيرات الجديد. كان تعبير الفلتر القديم هو: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "هذا هو مفتاح API الخاص بك. يمكن استخدامه لبعض عمليات API للقراءة فقط ويمنح الوصول إلى Fever API. استخدم النموذج الموجود في أسفل الصفحة لإنشاء مفتاح API جديد"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "هذا هو مفتاح API الخاص بك. يمكن استخدامه لبعض عمليات API للقراءة فقط ويمنح حق الوصول إلى Fever API و Google Reader API. استخدم النموذج الموجود أسفل الصفحة لإنشاء مفتاح API جديد"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "موقع الكتروني"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "مرحباً! يبدو أن هذه هي المرة الأولى التي تقوم فيها بتشغيل CommaFeed. يرجى إنشاء حساب مسؤول للبدء."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "أصفر"

View File

@@ -210,6 +210,10 @@ msgstr "Versió de l'extensió del navegador CommaFeed {browserExtensionVersion}
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed és compatible amb l'API Fever. Utilitzeu l'URL següent al vostre client mòbil compatible amb Fever. Inicieu sessió amb el vostre nom d'usuari i la vostra <0>clau API</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed és compatible amb l'API de Google Reader. Utilitzeu l'URL següent al vostre client mòbil compatible amb Google Reader. Inicieu sessió amb el vostre nom d'usuari i la vostra <0>clau API</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed següent element no llegit"
@@ -454,6 +458,14 @@ msgstr "Vés a la documentació de l'API."
msgid "Goodies"
msgstr "Extres"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Raïm"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Aquest feed té un filtre heretat que no es pot editar i no s'aplica. Torneu a crear el filtre amb el nou editor d'expressions. L'expressió del filtre heretat era: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Aquesta és la vostra clau de l'API. Es pot utilitzar per a algunes operacions de l'API de només lectura i permet accedir a l'API Fever. Utilitzeu el formulari de la part inferior de la pàgina per generar una nova clau d'API."
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Aquesta és la vostra clau API. Es pot utilitzar per a algunes operacions de l'API de només lectura i dona accés a l'API Fever i a l'API de Google Reader. Utilitzeu el formulari a la part inferior de la pàgina per generar una nova clau API"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Lloc web"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Benvingut! Sembla que aquesta és la primera vegada que executeu CommaFeed. Creeu un compte d'administrador per començar."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Groc"

View File

@@ -210,6 +210,10 @@ msgstr "Verze rozšíření prohlížeče CommaFeed {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed je kompatibilní s Fever API. Použijte následující URL ve svém mobilním klientovi kompatibilním s Fever. Přihlaste se pomocí svého uživatelského jména a svého <0>klíče API</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed je kompatibilní s Google Reader API. Použijte následující URL ve svém mobilním klientovi kompatibilním s Google Reader. Přihlaste se pomocí svého uživatelského jména a svého <0>klíče API</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed další nepřečtená položka"
@@ -454,6 +458,14 @@ msgstr "Přejděte na dokumentaci API."
msgid "Goodies"
msgstr "Dobroty"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Hroznová"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Tento zdroj má zastaralý filtr, který nelze upravovat a není aplikován. Znovu vytvořte filtr pomocí nového editoru výrazů. Původní výraz filtru byl: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Toto je váš klíč API. Lze jej použít pro některé operace API pouze pro čtení a poskytuje přístup k Fever API. Pro vygenerování nového klíče API použijte formulář v dolní části stránky."
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Toto je váš klíč API. Lze jej použít pro některé operace API pouze pro čtení a uděluje přístup k Fever API a Google Reader API. Použijte formulář v dolní části stránky k vygenerování nového klíče API"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Webová stránka"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Vítejte! Zdá se, že je to poprvé, co spouštíte CommaFeed. Chcete-li začít, vytvořte si účet správce."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Žlutá"

View File

@@ -210,6 +210,10 @@ msgstr "Fersiwn estyniad porwr CommaFeed {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "Mae CommaFeed yn gydnaws â'r Fever API. Defnyddiwch y URL canlynol yn eich cleient symudol sy'n gydnaws â Fever. Mewngofnodwch gyda'ch enw defnyddiwr a'ch <0>allwedd API</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "Mae CommaFeed yn gydnaws â Google Reader API. Defnyddiwch y URL canlynol yn eich cleient symudol sy'n gydnaws â Google Reader. Mewngofnodwch gyda'ch enw defnyddiwr a'ch <0>allwedd API</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed eitem nesaf heb ei darllen"
@@ -454,6 +458,14 @@ msgstr "Ewch i'r ddogfennaeth API."
msgid "Goodies"
msgstr "nwyddau"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Grawnwin"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Mae gan y porthiant hwn hen hidlydd na ellir ei olygu ac nid yw'n cael ei gymhwyso. Crëwch yr hidlydd eto gan ddefnyddio'r golygydd mynegiant newydd. Yr hen fynegiant hidlo oedd: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dyma'ch allwedd API. Gellir ei ddefnyddio ar gyfer rhai gweithrediadau API darllen-yn-unig ac mae'n caniatáu mynediad i'r Fever API. Defnyddiwch y ffurflen ar waelod y dudalen i gynhyrchu allwedd API newydd"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dyma eich allwedd API. Gellir ei defnyddio ar gyfer rhai gweithrediadau API darllen-yn-unig ac mae'n rhoi mynediad i'r Fever API a'r Google Reader API. Defnyddiwch y ffurflen ar waelod y dudalen i gynhyrchu allwedd API newydd"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Gwefan"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Croeso! Ymddengys mai dyma'r tro cyntaf i chi redeg CommaFeed. Creuwch gyfrif gweinyddwr i ddechrau."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Melyn"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed browserudvidelse version {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed er kompatibel med Fever API. Brug følgende URL i din Fever-kompatible mobilklient. Log ind med dit brugernavn og din <0>API-nøgle</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed er kompatibel med Google Reader API. Brug følgende URL i din Google Reader-kompatible mobilklient. Log ind med dit brugernavn og din <0>API-nøgle</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed næste ulæste element"
@@ -454,6 +458,14 @@ msgstr "Gå til API-dokumentationen."
msgid "Goodies"
msgstr "Godbidder"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Grape"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Dette feed har et ældre filter, der ikke kan redigeres og ikke anvendes. Genopret venligst filteret ved hjælp af den nye udtrykseditor. Det ældre filterudtryk var: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dette er din API-nøgle. Den kan bruges til visse skrivebeskyttede API-operationer og giver adgang til Fever API. Brug formularen nederst på siden til at generere en ny API-nøgle"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dette er din API-nøgle. Den kan bruges til nogle skrivebeskyttede API-operationer og giver adgang til Fever API og Google Reader API. Brug formularen nederst på siden for at generere en ny API-nøgle"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Hjemmeside"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Velkommen! Det ser ud til at være første gang, du kører CommaFeed. Opret venligst en administratorkonto for at komme i gang."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Gul"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed Browser Erweiterung Version {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed ist mit der Fever-API kompatibel. Verwenden Sie die folgende URL in Ihrem Fever-kompatiblen mobilen Client. Melden Sie sich mit Ihrem Benutzernamen und Ihrem <0>API-Schlüssel</0> an."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed ist mit der Google-Reader-API kompatibel. Verwenden Sie die folgende URL in Ihrem Google-Reader-kompatiblen mobilen Client. Melden Sie sich mit Ihrem Benutzernamen und Ihrem <0>API-Schlüssel</0> an."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed nächstes ungelesenes Element"
@@ -454,6 +458,14 @@ msgstr "Gehen Sie zur API-Dokumentation."
msgid "Goodies"
msgstr "Goodies"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Traube"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Dieser Feed verfügt über einen veralteten Filter, der nicht bearbeitet werden kann und nicht angewendet wird. Bitte erstellen Sie den Filter mit dem neuen Ausdruckseditor neu. Der veraltete Filterausdruck war: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dies ist Ihr API-Schlüssel. Er kann für einige schreibgeschützte API-Vorgänge verwendet werden und ermöglicht den Zugriff auf die Fever-API. Verwenden Sie das Formular unten auf der Seite, um einen neuen API-Schlüssel zu generieren"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dies ist Ihr API-Schlüssel. Er kann für einige schreibgeschützte API-Vorgänge verwendet werden und gewährt Zugriff auf die Fever-API und die Google-Reader-API. Verwenden Sie das Formular am Ende der Seite, um einen neuen API-Schlüssel zu generieren"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Webseite"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Willkommen! Dies scheint das erste Mal zu sein, dass Sie CommaFeed ausführen. Bitte erstellen Sie ein Administrator-Konto, um zu beginnen."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Gelb"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed browser extension version {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed next unread item"
@@ -454,6 +458,14 @@ msgstr "Go to the API documentation."
msgid "Goodies"
msgstr "Goodies"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr "Google Reader API"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr "Google Reader API URL"
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Grape"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "This feed has a legacy filter that cannot be edited and is not applied. Please recreate the filter using the new expression editor. The legacy filter expression was: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Website"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr "Wrong username or password"
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Yellow"

View File

@@ -211,6 +211,10 @@ msgstr "Versión de la extensión del navegador CommaFeed {browserExtensionVersi
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed es compatible con Fever API. Utilice la siguiente URL en su cliente móvil compatible con Fever. Inicie sesión con su nombre de usuario y su <0>clave API</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed es compatible con Google Reader API. Utilice la siguiente URL en su cliente móvil compatible con Google Reader. Inicie sesión con su nombre de usuario y su <0>clave API</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed siguiente elemento no leído"
@@ -455,6 +459,14 @@ msgstr "Ir a la documentación de la API."
msgid "Goodies"
msgstr "Golosinas"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Uva"
@@ -1066,8 +1078,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Este feed tiene un filtro heredado que no se puede editar y no se aplica. Por favor, vuelve a crear el filtro usando el nuevo editor de expresiones. La expresión del filtro heredado era: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Esta es su clave API. Se puede utilizar para algunas operaciones API de solo lectura y otorga acceso a Fever API. Utilice el formulario en la parte inferior de la página para generar una nueva clave API"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Esta es su clave API. Se puede utilizar para algunas operaciones API de solo lectura y otorga acceso a la API Fever y a la API de Google Reader. Utilice el formulario en la parte inferior de la página para generar una nueva clave API"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1139,6 +1151,10 @@ msgstr "Sitio web"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "¡Bienvenido! Parece que esta es la primera vez que ejecutas CommaFeed. Por favor, crea una cuenta de administrador para empezar."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Amarillo"

View File

@@ -210,6 +210,10 @@ msgstr "نسخه افزونه مرورگر CommaFeed {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed با Fever API سازگار است. از آدرس زیر در کلاینت موبایل سازگار با Fever استفاده کنید. با نام کاربری و <0>کلید API</0> خود وارد شوید."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed با Google Reader API سازگار است. از آدرس زیر در کلاینت موبایل سازگار با Google Reader استفاده کنید. با نام کاربری و <0>کلید API</0> خود وارد شوید."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "مورد خوانده نشده بعدی CommaFeed"
@@ -454,6 +458,14 @@ msgstr "به مستندات API بروید."
msgid "Goodies"
msgstr "خوبی ها"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "عنبی"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "این فید دارای یک فیلتر قدیمی است که قابل ویرایش نیست و اعمال نمی‌شود. لطفاً فیلتر را با استفاده از ویرایشگر جدید بازسازی کنید. عبارت فیلتر قدیمی: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "این کلید API شماست. می‌توان از آن برای برخی عملیات API فقط خواندنی استفاده کرد و دسترسی به Fever API را فراهم می‌کند. از فرم پایین صفحه برای تولید کلید جدید استفاده کنید"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "این کلید API شماست. می‌توان از آن برای برخی عملیات فقط خواندنی API استفاده کرد و دسترسی به Fever API و Google Reader API را می‌دهد. از فرم پایین صفحه برای ایجاد کلید API جدید استفاده کنید"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "وب سایت"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "خوش آمدید! به نظر می‌رسد این اولین بار است که CommaFeed را اجرا می‌کنید. لطفاً برای شروع یک حساب مدیر ایجاد کنید."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "زرد"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed-selainlaajennuksen versio {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed on yhteensopiva Fever-API:n kanssa. Käytä seuraavaa URL-osoitetta Fever-yhteensopivassa mobiiliohjelmassasi. Kirjaudu sisään käyttäjätunnuksellasi ja <0>API-avaimellasi</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed on yhteensopiva Google Reader -API:n kanssa. Käytä seuraavaa URL-osoitetta Google Reader -yhteensopivassa mobiiliohjelmassasi. Kirjaudu sisään käyttäjätunnuksellasi ja <0>API-avaimellasi</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed seuraava lukematon kohde"
@@ -454,6 +458,14 @@ msgstr "Siirry API-dokumentaatioon."
msgid "Goodies"
msgstr "Hyvää"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Viinirypäle"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Tässä syötteessä on vanha suodatin, jota ei voi muokata ja jota ei sovelleta. Luo suodatin uudelleen käyttämällä uutta lauseke-editoria. Vanha suodatinlauseke oli: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Tämä on API-avaimesi. Sitä voidaan käyttää joihinkin vain luku -API-toimintoihin ja se antaa pääsyn Fever-API:iin. Käytä sivun alareunassa olevaa lomaketta uuden API-avaimen luomiseen"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Tämä on API-avaimesi. Sitä voidaan käyttää joihinkin vain luku -API-toimintoihin, ja se myöntää pääsyn Fever-API:hin ja Google Reader -API:hin. Käytä sivun alareunassa olevaa lomaketta luodaksesi uuden API-avaimen"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Verkkosivusto"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Tervetuloa! Näyttää siltä, että suoritat CommaFeediä ensimmäistä kertaa. Luo ylläpitäjän tili aloittaaksesi."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Keltainen"

View File

@@ -210,6 +210,10 @@ msgstr "Extension CommaFeed pour navigateur version {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "Commafeed est compatible avec l'API Fever, en inscrivant l'URL suivante dans votre client mobile compatible. Entrez votre nom d'utilisateur habituel, et votre <0>clef API</0> comme mot de passe."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "Commafeed est compatible avec l'API Google Reader, en inscrivant l'URL suivante dans votre client mobile compatible. Entrez votre nom d'utilisateur habituel, et votre <0>clef API</0> comme mot de passe."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed prochain article non lu"
@@ -454,6 +458,14 @@ msgstr "Aller à la documentation de l'API."
msgid "Goodies"
msgstr "Extensions"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr "API Google Reader"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr "URL de l'API Google Reader"
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Bordeaux"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Ce flux est configuré avec un filtre obsolète, qui ne peut être ni modifié ni appliqué. Vous devez recréer ce filtre à l'aide du nouvel éditeur d'expressions régulières. Le filtre configuré était : <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Ceci est votre clef API. Elle peut être utilisée pour certaines opérations en lecture seule et donne accès à l'API Fever. Utilisez le formulaire en bas de la page pour générer une nouvelle clef API"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Ceci est votre clef API. Elle peut être utilisée pour certaines opérations en lecture seule et donne accès à l'API Fever et à l'API Google Reader. Utilisez le formulaire en bas de la page pour générer une nouvelle clef API"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Site web"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Bienvenue ! Il semble que ce soit le premier démarrage de Commafeed. Avant tout, vous devez créer un compte administrateur."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr "Utilisateur ou mot de passe incorrect"
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Jaune"

View File

@@ -211,6 +211,10 @@ msgstr "Versión do complemento do navegador para CommaFeed {browserExtensionVer
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed é compatible coa API de Fever. Usa o seguinte URL no teu cliente móbil compatible con Fever. Accede co identificador e a túa <0>clave API</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed é compatible coa API de Google Reader. Usa o seguinte URL no teu cliente móbil compatible con Google Reader. Accede co identificador e a túa <0>clave API</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "Seguinte elemento non lido en CommaFeed"
@@ -455,6 +459,14 @@ msgstr "Ir á documentación da API."
msgid "Goodies"
msgstr "Agasallos"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Bago"
@@ -1066,8 +1078,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Esta canle ten un filtro antigo que non se pode editar e que non se aplica. Volve crear o filtro usando o novo editor de expresións. A expresión do filtro antigo era: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Esta é a túa clave da API. Pode usarse para algunhas operacións da API de só-lectura e concede acceso á API Fever. Usa o formulario da parte inferior da páxina para crear unha nova clave da API"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Esta é a túa clave da API. Pode usarse para algunhas operacións da API de só-lectura e concede acceso á API Fever e á API de Google Reader. Usa o formulario da parte inferior da páxina para crear unha nova clave da API"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1139,6 +1151,10 @@ msgstr "Páxina web"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Benvida! Semella que é a primeira vez que executas CommaFeed. Para comezar, crea unha conta de administración."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Amarelo"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed böngészőbővítmény {browserExtensionVersion} verzió."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "A CommaFeed kompatibilis a Fever API-val. Használja a következő URL-t Fever-kompatibilis mobilkliensében. Jelentkezzen be felhasználónevével és <0>API-kulcsával</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "A CommaFeed kompatibilis a Google Reader API-val. Használja a következő URL-t Google Reader-kompatibilis mobilkliensében. Jelentkezzen be felhasználónevével és <0>API-kulcsával</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed következő olvasatlan elem"
@@ -454,6 +458,14 @@ msgstr "Nyissa meg az API dokumentációját."
msgid "Goodies"
msgstr "Jók"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Szőlő"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Ez a feed egy régi szűrővel rendelkezik, amely nem szerkeszthető és nem kerül alkalmazásra. Kérjük, hozza létre újra a szűrőt az új kifejezésszerkesztővel. A régi szűrőkifejezés a következő volt: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Ez az Ön API-kulcsa. Felhasználható néhány írásvédett API-művelethez, és hozzáférést biztosít a Fever API-hoz. Használja az oldal alján található űrlapot egy új API-kulcs létrehozásához"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Ez az Ön API-kulcsa. Néhány csak olvasható API-művelethez használható, és hozzáférést biztosít a Fever API-hoz és a Google Reader API-hoz. Használja az oldal alján található űrlapot új API-kulcs létrehozásához"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Webhely"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Üdvözöljük! Úgy tűnik, ez az első alkalom, hogy a CommaFeedet futtatja. Kérjük, hozzon létre egy rendszergazdai fiókot a kezdéshez."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Sárga"

View File

@@ -210,6 +210,10 @@ msgstr "Ekstensi browser CommaFeed versi {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed kompatibel dengan Fever API. Gunakan URL berikut di klien seluler Anda yang kompatibel dengan Fever. Login dengan nama pengguna dan <0>kunci API</0> Anda."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed kompatibel dengan Google Reader API. Gunakan URL berikut di klien seluler Anda yang kompatibel dengan Google Reader. Login dengan nama pengguna dan <0>kunci API</0> Anda."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed item yang belum dibaca berikutnya"
@@ -454,6 +458,14 @@ msgstr "Buka dokumentasi API."
msgid "Goodies"
msgstr "Pernak-pernik"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Anggur"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Umpan ini memiliki filter lama yang tidak dapat diedit dan tidak diterapkan. Silakan buat ulang filter menggunakan editor ekspresi baru. Ekspresi filter lama adalah: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Ini adalah kunci API Anda. Ini dapat digunakan untuk beberapa operasi API baca-saja dan memberikan akses ke Fever API. Gunakan formulir di bagian bawah halaman untuk membuat kunci API baru"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Ini adalah kunci API Anda. Ini dapat digunakan untuk beberapa operasi API yang hanya-baca dan memberikan akses ke Fever API dan Google Reader API. Gunakan formulir di bagian bawah halaman untuk membuat kunci API baru"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Situs Web"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Selamat datang! Ini sepertinya pertama kalinya Anda menjalankan CommaFeed. Silakan buat akun administrator untuk memulai."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Kuning"

View File

@@ -210,6 +210,10 @@ msgstr "Versione dell'estensione del browser CommaFeed {browserExtensionVersion}
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed è compatibile con l'API Fever. Utilizza il seguente URL nel tuo client mobile compatibile con Fever. Accedi con il tuo nome utente e la tua <0>chiave API</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed è compatibile con l'API Google Reader. Utilizza il seguente URL nel tuo client mobile compatibile con Google Reader. Accedi con il tuo nome utente e la tua <0>chiave API</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed successivo elemento non letto"
@@ -454,6 +458,14 @@ msgstr "Vai alla documentazione dell'API."
msgid "Goodies"
msgstr "Chicche"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Uva"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Questo feed ha un filtro legacy che non può essere modificato e non viene applicato. Ricrea il filtro utilizzando il nuovo editor di espressioni. L'espressione del filtro legacy era: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Questa è la tua chiave API. Può essere utilizzata per alcune operazioni API di sola lettura e garantisce l'accesso all'API Fever. Utilizza il modulo in fondo alla pagina per generare una nuova chiave API"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Questa è la tua chiave API. Può essere utilizzata per alcune operazioni API di sola lettura e concede l'accesso all'API Fever e all'API Google Reader. Usa il modulo in fondo alla pagina per generare una nuova chiave API"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Sito web"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Benvenuto! Sembra che sia la prima volta che esegui CommaFeed. Crea un account amministratore per iniziare."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Giallo"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed ブラウザー拡張機能のバージョンは {browserExten
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeedはFever APIと互換性があります。Fever互換のモバイルクライアントで次のURLを使用してください。ユーザー名と <0>API キー</0> でログインしてください。"
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeedはGoogle Reader APIと互換性があります。Google Reader互換のモバイルクライアントで次のURLを使用してください。ユーザー名と <0>API キー</0> でログインしてください。"
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed 次の未読アイテム"
@@ -454,6 +458,14 @@ msgstr "APIドキュメントに移動します。"
msgid "Goodies"
msgstr "グッズ"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "グレープ"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "このフィードには、編集できず適用もされない古い形式のフィルタがあります。新しい式エディタを使用してフィルタを再作成してください。古いフィルタ式は次のとおりでした: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "これはあなたのAPIキーです。いくつかの読み取り専用API操作に使用できます。これにより、Fever APIへのアクセスが可能になります。ページの下部のフォームを使用して新しいAPIキーを生成します。"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "これはあなたのAPIキーです。一部の読み取り専用API操作に使用でき、Fever APIおよびGoogle Reader APIへのアクセスを許可します。新しいAPIキーを生成するには、ページ下部のフォームを使用してください"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "ウェブサイト"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "ようこそ!CommaFeedを初めて実行するようです。開始するには管理者アカウントを作成してください。"
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "イエロー"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed 브라우저 확장 프로그램 버전 {browserExtensionVersi
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed는 Fever API와 호환됩니다. Fever 호환 모바일 클라이언트에서 다음 URL을 사용하십시오. 사용자 이름과 <0>API 키</0>로 로그인하십시오."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed는 Google Reader API와 호환됩니다. Google Reader 호환 모바일 클라이언트에서 다음 URL을 사용하십시오. 사용자 이름과 <0>API 키</0>로 로그인하십시오."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "다음 읽지 않은 항목을 쉼표로 피드"
@@ -454,6 +458,14 @@ msgstr "API 문서로 이동합니다."
msgid "Goodies"
msgstr "굿즈"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "그레이프"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "이 피드에는 편집할 수 없고 적용되지 않는 기존 필터가 있습니다. 새 표현식 편집기를 사용하여 필터를 다시 만드십시오. 기존 필터 표현식은 <0>{0}</0>이었습니다."
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "이것은 귀하의 API 키입니다. 일부 읽기 전용 API 작업에 사용할 수 있으며 Fever API에 대한 액세스 권한을 부여합니다. 새 API 키를 생성하려면 페이지 하단의 양식을 사용하십시오."
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "이것은 회원님의 API 키입니다. 일부 읽기 전용 API 작업에 사용할 수 있으며 Fever API 및 Google Reader API에 대한 액세스 권한을 부여합니다. 새 API 키를 생성하려면 페이지 하단의 양식을 사용하십시오"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "웹사이트"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "환영합니다! CommaFeed를 처음 실행하는 것 같습니다. 시작하려면 관리자 계정을 만드십시오."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "옐로우"

View File

@@ -210,6 +210,10 @@ msgstr "Ekstensi penyemak imbas CommaFeed versi {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed serasi dengan Fever API. Gunakan URL berikut dalam klien mudah alih serasi Fever anda. Log masuk dengan nama pengguna anda dan <0>kunci API</0> anda."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed serasi dengan Google Reader API. Gunakan URL berikut dalam klien mudah alih serasi Google Reader anda. Log masuk dengan nama pengguna anda dan <0>kunci API</0> anda."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed item belum dibaca seterusnya"
@@ -454,6 +458,14 @@ msgstr "Pergi ke dokumentasi API."
msgid "Goodies"
msgstr "Barangan"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Anggur"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Suapan ini mempunyai penapis warisan yang tidak boleh diedit dan tidak digunakan. Sila buat semula penapis menggunakan editor ungkapan baharu. Ungkapan penapis warisan ialah: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Ini ialah kunci API anda. Ia boleh digunakan untuk beberapa operasi API baca sahaja dan memberikan akses kepada Fever API. Gunakan borang di bahagian bawah halaman untuk menjana kunci API baharu"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Ini ialah kunci API anda. Ia boleh digunakan untuk sesetengah operasi API baca sahaja dan memberikan akses kepada Fever API dan Google Reader API. Gunakan borang di bahagian bawah halaman untuk menjana kunci API baharu"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Laman web"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Selamat datang! Ini nampaknya kali pertama anda menjalankan CommaFeed. Sila cipta akaun pentadbir untuk bermula."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Kuning"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed nettleserutvidelse versjon {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed er kompatibel med Fever API. Bruk følgende URL i din Fever-kompatible mobilklient. Logg inn med brukernavn og din <0>API-nøkkel</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed er kompatibel med Google Reader API. Bruk følgende URL i din Google Reader-kompatible mobilklient. Logg inn med brukernavn og din <0>API-nøkkel</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed neste uleste element"
@@ -454,6 +458,14 @@ msgstr "Gå til API-dokumentasjonen."
msgid "Goodies"
msgstr "Godbiter"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Drue"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Denne feeden har et utdatert filter som ikke kan redigeres og ikke blir brukt. Vennligst opprett filteret på nytt med den nye uttrykkseditoren. Det utdaterte filteruttrykket var: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dette er API-nøkkelen din. Den kan brukes til enkelte skrivebeskyttede API-operasjoner og gir tilgang til Fever API. Bruk skjemaet nederst på siden for å generere en ny API-nøkkel"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dette er din API-nøkkel. Den kan brukes til noen skrivebeskyttede API-operasjoner og gir tilgang til Fever API og Google Reader API. Bruk skjemaet nederst på siden for å generere en ny API-nøkkel"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Nettsted"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Velkommen! Det ser ut til å være første gang du kjører CommaFeed. Vennligst opprett en administratorkonto for å komme i gang."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Gul"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed browser extensie versie {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed is compatibel met de Fever API. Gebruik de volgende URL in uw Fever-compatibele mobiele client. Log in met uw gebruikersnaam en uw <0>API-sleutel</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed is compatibel met de Google Reader API. Gebruik de volgende URL in uw Google Reader-compatibele mobiele client. Log in met uw gebruikersnaam en uw <0>API-sleutel</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed volgende ongelezen item"
@@ -454,6 +458,14 @@ msgstr "Ga naar de API-documentatie."
msgid "Goodies"
msgstr "Goederen"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Druif"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Deze feed heeft een legacy-filter dat niet kan worden bewerkt en niet wordt toegepast. Maak het filter opnieuw met de nieuwe expressie-editor. De legacy-filterexpressie was: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dit is je API-sleutel. Het kan worden gebruikt voor sommige alleen-lezen API-bewerkingen en geeft toegang tot de Fever API. Gebruik het formulier onderaan de pagina om een nieuwe API-sleutel te genereren"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dit is uw API-sleutel. Deze kan worden gebruikt voor sommige alleen-lezen API-bewerkingen en geeft toegang tot de Fever API en de Google Reader API. Gebruik het formulier onderaan de pagina om een nieuwe API-sleutel te genereren"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Website"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Welkom! Dit lijkt de eerste keer te zijn dat je CommaFeed draait. Maak een beheerdersaccount aan om aan de slag te gaan."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Geel"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed nettlesarutviding versjon {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed er kompatibel med Fever API. Bruk følgjande URL i din Fever-kompatible mobilklient. Logg inn med brukarnamn og din <0>API-nøkkel</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed er kompatibel med Google Reader API. Bruk følgjande URL i din Google Reader-kompatible mobilklient. Logg inn med brukarnamn og din <0>API-nøkkel</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed neste ulesne element"
@@ -454,6 +458,14 @@ msgstr "Gå til API-dokumentasjonen."
msgid "Goodies"
msgstr "Godbitar"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Drue"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Denne suapen har eit gamalt filter som ikkje kan redigerast og som ikkje vert brukt. Ver venleg og lag filteret på nytt med den nye uttrykkseditoren. Det gamle filteruttrykket var: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dette er API-nøkkelen din. Han kan brukast til enkelte skrivebeskytta API-handlingar og gjev tilgang til Fever API. Bruk skjemaet nedst på sida for å laga ein ny API-nøkkel"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Dette er din API-nøkkel. Ho kan brukast til nokre skrivebeskytta API-operasjonar og gir tilgang til Fever API og Google Reader API. Bruk skjemaet nedst på sida for å generere ein ny API-nøkkel"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Nettstad"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Velkomen! Det ser ut til å vera fyrste gongen du køyrer CommaFeed. Ver venleg og opprett ein administratorkonto for å koma i gang."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Gul"

View File

@@ -210,6 +210,10 @@ msgstr "Wersja rozszerzenia przeglądarki CommaFeed {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed jest kompatybilny z API Fever. Użyj następującego adresu URL w swoim kliencie mobilnym zgodnym z Fever. Zaloguj się przy użyciu swojej nazwy użytkownika i <0>klucza API</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed jest kompatybilny z API Google Reader. Użyj następującego adresu URL w swoim kliencie mobilnym zgodnym z Google Reader. Zaloguj się przy użyciu swojej nazwy użytkownika i <0>klucza API</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "Przecinek następny nieprzeczytany element"
@@ -454,6 +458,14 @@ msgstr "Przejdź do dokumentacji API."
msgid "Goodies"
msgstr "Gadżety"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Winogronowy"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Ten kanał ma stary filtr, którego nie można edytować i który nie jest stosowany. Proszę utworzyć filtr ponownie, korzystając z nowego edytora wyrażeń. Stare wyrażenie filtra to: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "To jest Twój klucz API. Może być używany do niektórych operacji API tylko do odczytu i zapewnia dostęp do API Fever. Użyj formularza na dole strony, aby wygenerować nowy klucz API"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "To jest Twój klucz API. Może być używany do niektórych operacji API tylko do odczytu i zapewnia dostęp do API Fever i API Google Reader. Użyj formularza na dole strony, aby wygenerować nowy klucz API"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Strona internetowa"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Witaj! Wygląda na to, że uruchamiasz CommaFeed po raz pierwszy. Aby rozpocząć, utwórz konto administratora."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Żółty"

View File

@@ -210,6 +210,10 @@ msgstr "Extensão de navegador CommaFeed versão {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed é compatível com a API Fever. Use a URL a seguir no seu aplicativo móvel compatível com Fever. Entre com seu nome de usuário e sua <0>chave de API</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed é compatível com a API Google Reader. Use a URL a seguir no seu aplicativo móvel compatível com Google Reader. Entre com seu nome de usuário e sua <0>chave de API</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed próximo item não lido"
@@ -454,6 +458,14 @@ msgstr "Vá para a documentação da API."
msgid "Goodies"
msgstr "Brindes"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Uva"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Este feed tem um filtro legado que não pode ser editado e não é aplicado. Recrie o filtro usando o novo editor de expressões. A expressão do filtro legado era: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Esta é sua chave de API. Ela pode ser usada para algumas operações somente leitura da API e concede acesso à API do Fever. Use o formulário abaixo para gerar uma nova chave de API"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Esta é sua chave de API. Ela pode ser usada para algumas operações de API somente leitura e concede acesso à API Fever e à API Google Reader. Use o formulário na parte inferior da página para gerar uma nova chave de API"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Site"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Bem-vindo! Esta parece ser a primeira vez que você está executando o CommaFeed. Crie uma conta de administrador para começar."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Amarelo"

View File

@@ -210,6 +210,10 @@ msgstr "Версия расширения браузера CommaFeed {browserExt
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed совместим с API Fever. Используйте следующий URL-адрес в мобильном клиенте, совместимом с Fever. Войдите в систему, указав свое имя пользователя и <0>API-ключ</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed совместим с API Google Reader. Используйте следующий URL-адрес в мобильном клиенте, совместимом с Google Reader. Войдите в систему, указав свое имя пользователя и <0>API-ключ</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed следующий непрочитанный элемент"
@@ -454,6 +458,14 @@ msgstr "Перейдите к документации по API."
msgid "Goodies"
msgstr "Сладости"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Виноградный"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Этот фид имеет устаревший фильтр, который нельзя редактировать и который не применяется. Пожалуйста, создайте фильтр заново, используя новый редактор выражений. Устаревшее выражение фильтра было: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Это ваш ключ API. Он может использоваться для некоторых операций API только для чтения и предоставляет доступ к API Fever. Чтобы сгенерировать новый ключ API, воспользуйтесь формой в нижней части страницы"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Это ваш ключ API. Он может использоваться для некоторых операций API только для чтения и предоставляет доступ к API Fever и API Google Reader. Используйте форму внизу страницы, чтобы сгенерировать новый ключ API"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Веб-сайт"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Добро пожаловать! Похоже, вы запускаете CommaFeed в первый раз. Пожалуйста, создайте учетную запись администратора, чтобы начать работу."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Желтый"

View File

@@ -210,6 +210,10 @@ msgstr "Rozšírenie prehliadača CommaFeed verzie {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed je kompatibilný s Fever API. Vo svojom mobilnom klientovi kompatibilnom s Fever použite nasledujúcu adresu URL. Prihláste sa pomocou svojho používateľského mena a <0>kľúča API</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed je kompatibilný s Google Reader API. Vo svojom mobilnom klientovi kompatibilnom s Google Reader použite nasledujúcu adresu URL. Prihláste sa pomocou svojho používateľského mena a <0>kľúča API</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed ďalšia neprečítaná položka"
@@ -454,6 +458,14 @@ msgstr "Prejdite na dokumentáciu API."
msgid "Goodies"
msgstr "Dobrôtky"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Hroznová"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Tento kanál má starší filter, ktorý sa nedá upravovať a nepoužíva sa. Znova vytvorte filter pomocou nového editora výrazov. Pôvodný výraz filtra bol: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Toto je váš kľúč API. Môže sa použiť na niektoré operácie rozhrania API len na čítanie a poskytuje prístup k rozhraniu Fever API. Na vygenerovanie nového kľúča API použite formulár v dolnej časti stránky."
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Toto je váš kľúč API. Môže sa použiť pre niektoré operácie API iba na čítanie a udeľuje prístup k Fever API a Google Reader API. Na vygenerovanie nového kľúča API použite formulár v spodnej časti stránky"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Webová stránka"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Vitajte! Zdá sa, že CommaFeed spúšťate prvýkrát. Ak chcete začať, vytvorte si účet správcu."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Žltá"

View File

@@ -210,6 +210,10 @@ msgstr "Webbläsartillägget CommaFeed version {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed är kompatibelt med Fever API. Använd följande URL i din Fever-kompatibla mobilklient. Logga in med ditt användarnamn och din <0>API-nyckel</0>."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed är kompatibelt med Google Reader API. Använd följande URL i din Google Reader-kompatibla mobilklient. Logga in med ditt användarnamn och din <0>API-nyckel</0>."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed nästa olästa objekt"
@@ -454,6 +458,14 @@ msgstr "Gå till API-dokumentationen."
msgid "Goodies"
msgstr "Godsaker"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Lila"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Detta flöde har ett gammalt filter som inte kan redigeras och inte tillämpas. Skapa filtret på nytt med den nya uttryckseditorern. Det gamla filteruttrycket var: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Detta är din API-nyckel. Den kan användas för vissa skrivskyddade API-operationer och ger åtkomst till Fever API. Använd formuläret längst ner på sidan för att generera en ny API-nyckel"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Det här är din API-nyckel. Den kan användas för vissa skrivskyddade API-åtgärder och ger åtkomst till Fever API och Google Reader API. Använd formuläret längst ner på sidan för att generera en ny API-nyckel"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Webbplats"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Välkommen! Det verkar vara första gången du kör CommaFeed. Skapa ett administratörskonto för att komma igång."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Gul"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed tarayıcı eklentisi sürüm {browserExtensionVersion}."
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed, Fever API ile uyumludur. Fever uyumlu mobil istemcinizde aşağıdaki URL'yi kullanın. Kullanıcı adınız ve <0>API anahtarınız</0> ile giriş yapın."
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed, Google Reader API ile uyumludur. Google Reader uyumlu mobil istemcinizde aşağıdaki URL'yi kullanın. Kullanıcı adınız ve <0>API anahtarınız</0> ile giriş yapın."
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed sonraki okunmamış öğe"
@@ -454,6 +458,14 @@ msgstr "API belgelerine gidin."
msgid "Goodies"
msgstr "İyilikler"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "Üzüm"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "Bu beslemenin düzenlenemeyen ve uygulanmayan eski bir filtresi var. Lütfen yeni ifade düzenleyiciyi kullanarak filtreyi yeniden oluşturun. Eski filtre ifadesi şuydu: <0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "Bu sizin API anahtarınızdır. Bazı salt okunur API işlemleri için kullanılabilir ve Fever API'sine erişim sağlar. Yeni bir API anahtarı oluşturmak için sayfanın altındaki formu kullanın"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "Bu, API anahtarınızdır. Bazı salt okunur API işlemleri için kullanılabilir ve Fever API ile Google Reader API'ye erişim sağlar. Yeni bir API anahtarı oluşturmak için sayfanın altındaki formu kullanın"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "Web sitesi"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "Hoş geldiniz! Görünüşe göre CommaFeed'i ilk kez çalıştırıyorsunuz. Başlamak için lütfen bir yönetici hesabı oluşturun."
#: src/app/client.ts
msgid "Wrong username or password"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "Sarı"

View File

@@ -210,6 +210,10 @@ msgstr "CommaFeed的浏览器扩展版本:{browserExtensionVersion}。"
msgid "CommaFeed is compatible with the Fever API. Use the following URL in your Fever-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed 和 Fever API 兼容,可以在您Fever兼容的移动客户端中使用以下网址,通过用户名和<0>API密钥</0>登录。"
#: src/components/settings/ProfileSettings.tsx
msgid "CommaFeed is compatible with the Google Reader API. Use the following URL in your Google Reader-compatible mobile client. Login with your username and your <0>API key</0>."
msgstr "CommaFeed 和 Google Reader API 兼容,可以在您Google Reader兼容的移动客户端中使用以下网址,通过用户名和<0>API密钥</0>登录。"
#: src/pages/app/AboutPage.tsx
msgid "CommaFeed next unread item"
msgstr "CommaFeed 下一个未读项目"
@@ -454,6 +458,14 @@ msgstr "API 文档"
msgid "Goodies"
msgstr "好东西"
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API"
msgstr ""
#: src/components/settings/ProfileSettings.tsx
msgid "Google Reader API URL"
msgstr ""
#: src/components/settings/DisplaySettings.tsx
msgid "Grape"
msgstr "深紫"
@@ -1065,8 +1077,8 @@ msgid "This feed has a legacy filter that cannot be edited and is not applied. P
msgstr "此信息流具有无法编辑且未应用的旧版过滤器。请使用新的表达式编辑器重新创建过滤器。旧版过滤器表达式为:<0>{0}</0>"
#: src/components/settings/ProfileSettings.tsx
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API. Use the form at the bottom of the page to generate a new API key"
msgstr "这是您的API 密钥,它可以被用于Fever API的只读操作及访问授权。使用页面底部的表单生成一个新的API密钥。"
msgid "This is your API key. It can be used for some read-only API operations and grants access to the Fever API and the Google Reader API. Use the form at the bottom of the page to generate a new API key"
msgstr "这是您的 API 密钥。它可用于某些只读 API 操作,并授予对 Fever API 和 Google Reader API 的访问权限。使用页面底部的表单生成新的 API 密钥"
#: src/components/settings/DisplaySettings.tsx
msgid "This setting can cause scrolling issues on some browsers (e.g. Safari)"
@@ -1138,6 +1150,10 @@ msgstr "网站"
msgid "Welcome! This appears to be the first time you're running CommaFeed. Please create an administrator account to get started."
msgstr "欢迎!当前页仅当您第一次使用CommaFeed时出现,请创建一个管理员帐号以开始使用。"
#: src/app/client.ts
msgid "Wrong username or password"
msgstr "用户名或密码错误"
#: src/components/settings/DisplaySettings.tsx
msgid "Yellow"
msgstr "黄"

View File

@@ -15,9 +15,10 @@ dayjs.extend(relativeTime)
dayjs.extend(duration)
const root = document.getElementById("root")
root &&
ReactDOM.createRoot(root).render(
<Provider store={store}>
<App />
</Provider>
)
if (!root) throw new Error("root element not found")
ReactDOM.createRoot(root).render(
<Provider store={store}>
<App />
</Provider>
)

View File

@@ -13,7 +13,8 @@ export default defineConfig(() => ({
}),
lingui(),
checker({
typescript: true,
// temporary disabled until TypeScript 7 exposes a stable api
// typescript: true,
biome: {
command: "check",
flags: "--error-on-warnings",

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
FROM ibm-semeru-runtimes:open-jdk-25.0.3.0-jre@sha256:43ec947fee9c4c2ed880620ae9e78911ac5eef66391e5a2c43f956dcc9000491
FROM ibm-semeru-runtimes:open-jdk-25.0.4.0-jre@sha256:524f0d04723aff42ed4142ab2621fa55f22cb691763cd75b59eee86749e2e872
EXPOSE 8082
RUN mkdir -p /commafeed/data

View File

@@ -1,4 +1,4 @@
FROM debian:13.5@sha256:d07d1b51c39f51188e60be9b64e6bf769fa94e187f092bc32b91305cfa34ba5a
FROM debian:13.6@sha256:34cd9e9fd437c0a095ec39cb2e73422c9f30821b0d0848ed74fd0d43bae4d958
ARG TARGETARCH
EXPOSE 8082

View File

@@ -93,3 +93,12 @@ Tags are of the form `<version>-<database>[-jvm]` where:
- `master` (always points to the latest git commit)
- `<database>` is the database to use (`h2`, `postgresql`, `mysql` or `mariadb`)
- `-jvm` is optional and indicates that CommaFeed is running on a JVM, and not compiled natively.
## FAQ
### Getting "Access to local address blocked" when adding a feed
CommaFeed blocks access to local resources by default to prevent [SSRF](https://en.wikipedia.org/wiki/Server-side_request_forgery) attacks.
If you want to subscribe to feeds that are only available on your local network, you can disable this security measure by setting the `COMMAFEED_HTTP_CLIENT_BLOCK_LOCAL_ADDRESSES` variable to `false`.
Do this only if you trust all users of your CommaFeed instance not to access private resources.

View File

@@ -4,13 +4,18 @@ import com.commafeed.backend.feed.FeedRefreshEngine;
import com.commafeed.backend.feed.ImageProxyUrl;
import com.commafeed.backend.task.TaskScheduler;
import com.commafeed.security.password.PasswordConstraintValidator;
import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;
import jakarta.enterprise.event.Observes;
import jakarta.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.SystemProperties;
@Slf4j
@Singleton
@RequiredArgsConstructor
@@ -23,6 +28,12 @@ public class CommaFeedApplication {
public void start(@Observes StartupEvent ev) {
log.info("starting up...");
// disable entity expansion limits added in JDK24+ (#1961)
// we already strip doctype declarations in XMLCleaner to prevent xxe attacks
// we also already limit the size of feeds we download in HttpGetter
System.setProperty(SystemProperties.JDK_XML_MAX_GENERAL_ENTITY_SIZE_LIMIT, "0");
System.setProperty(SystemProperties.JDK_XML_TOTAL_ENTITY_SIZE_LIMIT, "0");
PasswordConstraintValidator.setMinimumPasswordLength(
config.users().minimumPasswordLength());
@@ -30,6 +41,11 @@ public class CommaFeedApplication {
ImageProxyUrl.generateKey();
}
if (config.passwordRecoveryEnabled() && config.passwordRecoveryPublicBaseUrl().isEmpty()) {
throw new IllegalStateException(
"password recovery is enabled but no public base url is set");
}
feedRefreshEngine.start();
taskScheduler.start();
}

View File

@@ -1,14 +1,17 @@
package com.commafeed;
import com.commafeed.backend.feed.FeedRefreshIntervalCalculator;
import io.quarkus.runtime.annotations.ConfigDocSection;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.quarkus.runtime.configuration.MemorySize;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.Positive;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
@@ -46,6 +49,13 @@ public interface CommaFeedConfiguration {
@WithDefault("false")
boolean passwordRecoveryEnabled();
/**
* The base URL of the application to use in the password recovery link in the email. We can't
* use the URL sent by the browser of the user because of malicious Host header injection
* attacks.
*/
Optional<String> passwordRecoveryPublicBaseUrl();
/** Message displayed in a notification at the bottom of the page. */
Optional<String> announcement();
@@ -127,7 +137,7 @@ public interface CommaFeedConfiguration {
* <p>You may want to enable this if you host a public instance of CommaFeed with
* registrations open.
*/
@WithDefault("false")
@WithDefault("true")
boolean blockLocalAddresses();
/** HTTP client cache configuration */

View File

@@ -1,8 +1,10 @@
package com.commafeed;
import com.codahale.metrics.MetricRegistry;
import jakarta.enterprise.inject.Produces;
import jakarta.inject.Singleton;
import java.time.InstantSource;
@Singleton

View File

@@ -1,10 +1,12 @@
package com.commafeed;
import jakarta.inject.Singleton;
import lombok.Getter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import lombok.Getter;
@Singleton
@Getter

View File

@@ -1,14 +1,20 @@
package com.commafeed;
import com.commafeed.frontend.exception.CommaFeedApplicationException;
import com.commafeed.frontend.exception.CommaFeedExceptionType;
import com.commafeed.security.CookieService;
import io.quarkus.runtime.annotations.RegisterForReflection;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.UnauthorizedException;
import jakarta.annotation.Priority;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.NewCookie;
import jakarta.ws.rs.ext.Provider;
import lombok.RequiredArgsConstructor;
import org.jboss.resteasy.reactive.RestResponse;
import org.jboss.resteasy.reactive.RestResponse.ResponseBuilder;
import org.jboss.resteasy.reactive.RestResponse.Status;
@@ -22,6 +28,18 @@ public class ExceptionMappers {
private final CookieService cookieService;
private final CommaFeedConfiguration config;
@ServerExceptionMapper(CommaFeedApplicationException.class)
public RestResponse<CommaFeedApplicationError> applicationError(
CommaFeedApplicationException e) {
ResponseBuilder<CommaFeedApplicationError> response =
ResponseBuilder.create(
e.type().status(), new CommaFeedApplicationError(e.type(), e.getMessage()));
if (e.type().status() == Status.UNAUTHORIZED) {
response.cookie(cookieService.buildLogoutCookie());
}
return response.build();
}
@ServerExceptionMapper(UnauthorizedException.class)
public RestResponse<UnauthorizedResponse> unauthorized(UnauthorizedException e) {
return RestResponse.status(
@@ -51,4 +69,7 @@ public class ExceptionMappers {
@RegisterForReflection
public record ValidationFailed(String message) {}
@RegisterForReflection
public record CommaFeedApplicationError(CommaFeedExceptionType type, String message) {}
}

View File

@@ -5,8 +5,11 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import io.quarkus.jackson.ObjectMapperCustomizer;
import jakarta.inject.Singleton;
import java.util.concurrent.TimeUnit;
@Singleton

View File

@@ -6,6 +6,7 @@ import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Timer;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection(

View File

@@ -2,9 +2,11 @@ package com.commafeed.backend;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import java.nio.charset.StandardCharsets;
import lombok.experimental.UtilityClass;
import java.nio.charset.StandardCharsets;
@UtilityClass
@SuppressWarnings("deprecation")
public class Digests {

View File

@@ -3,21 +3,20 @@ package com.commafeed.backend;
import com.commafeed.CommaFeedConfiguration;
import com.commafeed.CommaFeedVersion;
import com.google.common.net.HttpHeaders;
import inet.ipaddr.IPAddress;
import inet.ipaddr.IPAddressNetwork;
import inet.ipaddr.IPAddressString;
import inet.ipaddr.ipv4.IPv4Address;
import inet.ipaddr.ipv6.IPv6Address;
import jakarta.inject.Singleton;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.SequencedMap;
import java.util.zip.GZIPInputStream;
import lombok.RequiredArgsConstructor;
import nl.altindag.ssl.SSLFactory;
import nl.altindag.ssl.apache5.util.Apache5SslUtils;
import org.apache.hc.client5.http.DnsResolver;
import org.apache.hc.client5.http.SystemDefaultDnsResolver;
import org.apache.hc.client5.http.config.ConnectionConfig;
@@ -42,6 +41,15 @@ import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;
import org.brotli.dec.BrotliInputStream;
import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.SequencedMap;
import java.util.zip.GZIPInputStream;
@Singleton
@RequiredArgsConstructor
public class HttpClientFactory {
@@ -131,8 +139,38 @@ public class HttpClientFactory {
}
private static boolean isLocalAddress(InetAddress address) {
IPAddress ip = new IPAddressNetwork.IPAddressGenerator().from(address);
return ip.isLocal() || ip.isLoopback() || ip.isMulticast() || CGNAT_RANGE.contains(ip);
return isLocalAddress(new IPAddressNetwork.IPAddressGenerator().from(address));
}
private static boolean isLocalAddress(IPAddress ip) {
if (ip.isLocal() || ip.isLoopback() || ip.isMulticast() || CGNAT_RANGE.contains(ip)) {
return true;
}
if (!ip.isIPv6()) {
return false;
}
// IPv6 transition mechanisms embed an IPv4 address that must be validated too, otherwise
// they could be used to smuggle a blocked IPv4 target past the IPv6-only checks above
IPv6Address ipv6 = ip.toIPv6();
if (ipv6.isIPv4Mapped() || ipv6.isIPv4Compatible() || ipv6.isWellKnownIPv4Translatable()) {
// IPv4-mapped (::ffff:x.x.x.x), IPv4-compatible (::x.x.x.x) and NAT64
// (64:ff9b::/96, RFC 6052) addresses all embed the IPv4 address in the lowest 32 bits
return isLocalAddress(ipv6.getEmbeddedIPv4Address());
}
if (ipv6.is6To4()) {
// 6to4 (2002::/16, RFC 3056) embeds the IPv4 address in bits 16-47
return isLocalAddress(ipv6.get6To4IPv4Address());
}
if (ipv6.isTeredo()) {
// Teredo (2001::/32, RFC 4380) embeds the IPv4 address in the lowest 32 bits,
// obfuscated with a bitwise complement
IPv4Address obfuscated = ipv6.getEmbeddedIPv4Address();
return isLocalAddress(new IPv4Address(~obfuscated.intValue()));
}
return false;
}
private record BlockLocalAddressesDnsResolver(DnsResolver delegate) implements DnsResolver {

View File

@@ -8,22 +8,17 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Iterables;
import com.google.common.io.ByteStreams;
import com.google.common.net.HttpHeaders;
import jakarta.inject.Singleton;
import jakarta.ws.rs.core.CacheControl;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.time.InstantSource;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Lombok;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.hc.client5.http.config.RequestConfig;
@@ -39,6 +34,15 @@ import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
import org.apache.hc.core5.util.Timeout;
import org.jboss.resteasy.reactive.common.headers.CacheControlDelegate;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.time.InstantSource;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
/** Smart HTTP getter: handles gzip, ssl, last modified and etag headers */
@Singleton
@Slf4j

View File

@@ -1,13 +1,16 @@
package com.commafeed.backend;
import java.net.URI;
import java.util.regex.Pattern;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.Strings;
import org.netpreserve.urlcanon.Canonicalizer;
import org.netpreserve.urlcanon.ParsedUrl;
import java.net.URI;
import java.util.Locale;
import java.util.regex.Pattern;
@UtilityClass
@Slf4j
public class Urls {
@@ -15,17 +18,38 @@ public class Urls {
private static final Pattern QUESTION_MARK = Pattern.compile(Pattern.quote("?"));
public static boolean isHttp(String url) {
return url.startsWith("http://");
if (url == null) {
return false;
}
return url.toLowerCase(Locale.ROOT).startsWith("http://");
}
public static boolean isHttps(String url) {
return url.startsWith("https://");
if (url == null) {
return false;
}
return url.toLowerCase(Locale.ROOT).startsWith("https://");
}
public static boolean isAbsolute(String url) {
return isHttp(url) || isHttps(url);
}
/** remove malicious 'javascript: 'URLs * */
public static String sanitize(String url) {
if (url == null) {
return null;
}
if (!isHttp(url) && !isHttps(url)) {
return null;
}
return url;
}
/**
* @param relativeUrl the url of the entry
* @param feedLink the url of the feed as described in the feed

View File

@@ -5,8 +5,10 @@ import com.commafeed.backend.model.QFeedCategory;
import com.commafeed.backend.model.QUser;
import com.commafeed.backend.model.User;
import com.querydsl.core.types.Predicate;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import java.util.List;
import java.util.Objects;

View File

@@ -5,11 +5,14 @@ import com.commafeed.backend.model.QFeed;
import com.commafeed.backend.model.QFeedSubscription;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQuery;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import org.apache.commons.lang3.Strings;
import java.time.Instant;
import java.util.List;
import org.apache.commons.lang3.Strings;
@Singleton
public class FeedDAO extends GenericDAO<Feed> {

View File

@@ -3,8 +3,10 @@ package com.commafeed.backend.dao;
import com.commafeed.backend.model.FeedEntryContent;
import com.commafeed.backend.model.QFeedEntry;
import com.commafeed.backend.model.QFeedEntryContent;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import java.util.List;
@Singleton

View File

@@ -7,8 +7,10 @@ import com.google.common.collect.Lists;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.jpa.impl.JPAQuery;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;

View File

@@ -21,14 +21,17 @@ import com.querydsl.core.Tuple;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.jpa.impl.JPAQuery;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import org.apache.commons.collections4.CollectionUtils;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
@Singleton
public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {

View File

@@ -4,8 +4,10 @@ import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedEntryTag;
import com.commafeed.backend.model.QFeedEntryTag;
import com.commafeed.backend.model.User;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

View File

@@ -8,12 +8,10 @@ import com.commafeed.backend.model.Models;
import com.commafeed.backend.model.QFeedSubscription;
import com.commafeed.backend.model.User;
import com.querydsl.jpa.JPQLQuery;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventType;
@@ -21,6 +19,11 @@ import org.hibernate.event.spi.PostCommitInsertEventListener;
import org.hibernate.event.spi.PostInsertEvent;
import org.hibernate.persister.entity.EntityPersister;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@Singleton
public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {

View File

@@ -6,11 +6,15 @@ import com.querydsl.jpa.impl.JPADeleteClause;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.querydsl.jpa.impl.JPAUpdateClause;
import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;
import org.hibernate.jpa.SpecHints;
import java.time.Duration;
import java.util.Collection;
import lombok.RequiredArgsConstructor;
import org.hibernate.jpa.SpecHints;
@RequiredArgsConstructor
public abstract class GenericDAO<T extends AbstractModel> {

View File

@@ -4,6 +4,7 @@ import com.commafeed.backend.model.QFeedEntry;
import com.commafeed.backend.model.QFeedEntryStatus;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.JPAExpressions;
import lombok.experimental.UtilityClass;
@UtilityClass

View File

@@ -1,7 +1,9 @@
package com.commafeed.backend.dao;
import io.quarkus.narayana.jta.QuarkusTransaction;
import jakarta.inject.Singleton;
import java.util.concurrent.Callable;
@Singleton

View File

@@ -2,6 +2,7 @@ package com.commafeed.backend.dao;
import com.commafeed.backend.model.QUser;
import com.commafeed.backend.model.User;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;

View File

@@ -4,8 +4,10 @@ import com.commafeed.backend.model.QUserRole;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole;
import com.commafeed.backend.model.UserRole.Role;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

View File

@@ -3,6 +3,7 @@ package com.commafeed.backend.dao;
import com.commafeed.backend.model.QUserSettings;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserSettings;
import jakarta.inject.Singleton;
import jakarta.persistence.EntityManager;

View File

@@ -3,15 +3,19 @@ package com.commafeed.backend.favicon;
import com.commafeed.backend.HttpGetter;
import com.commafeed.backend.HttpGetter.HttpResult;
import com.commafeed.backend.model.Feed;
import jakarta.annotation.Priority;
import jakarta.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.net.URIBuilder;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.net.URIBuilder;
@Slf4j
@RequiredArgsConstructor

View File

@@ -1,6 +1,7 @@
package com.commafeed.backend.favicon;
import jakarta.ws.rs.core.MediaType;
import lombok.extern.slf4j.Slf4j;
@Slf4j

View File

@@ -3,8 +3,10 @@ package com.commafeed.backend.favicon;
import com.commafeed.backend.HttpGetter;
import com.commafeed.backend.HttpGetter.HttpResult;
import com.commafeed.backend.model.Feed;
import jakarta.annotation.Priority;
import jakarta.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

View File

@@ -3,10 +3,13 @@ package com.commafeed.backend.favicon;
import com.commafeed.backend.HttpGetter;
import com.commafeed.backend.HttpGetter.HttpResult;
import com.commafeed.backend.model.Feed;
import jakarta.annotation.Priority;
import jakarta.inject.Singleton;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

View File

@@ -3,12 +3,15 @@ package com.commafeed.backend.favicon;
import com.commafeed.backend.HttpGetter;
import com.commafeed.backend.HttpGetter.HttpResult;
import com.commafeed.backend.model.Feed;
import jakarta.annotation.Priority;
import jakarta.inject.Singleton;
import java.net.URI;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.net.URI;
/** Fetches favicon from root of the domain (e.g. https://example.com/favicon.ico) */
@Slf4j
@RequiredArgsConstructor
@@ -27,7 +30,12 @@ public class RootFaviconFetcher implements FaviconFetcher {
try {
URI uri = URI.create(url.trim());
String faviconUrl = "%s://%s/favicon.ico".formatted(uri.getScheme(), uri.getHost());
String faviconUrl =
"%s://%s%s/favicon.ico"
.formatted(
uri.getScheme(),
uri.getHost(),
uri.getPort() > 0 ? ":" + uri.getPort() : "");
log.debug("getting root icon at {}", faviconUrl);
HttpResult result = getter.get(faviconUrl);

View File

@@ -10,18 +10,22 @@ import com.commafeed.backend.model.Feed;
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Priority;
import jakarta.inject.Singleton;
import jakarta.ws.rs.core.UriBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.net.URIBuilder;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.net.URIBuilder;
@Slf4j
@RequiredArgsConstructor

View File

@@ -1,8 +1,9 @@
package com.commafeed.backend.feed;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
/** A keyword used in a search query */
public record FeedEntryKeyword(String keyword, Mode mode) {

View File

@@ -11,16 +11,21 @@ import com.commafeed.backend.feed.parser.FeedParser;
import com.commafeed.backend.feed.parser.FeedParser.FeedParsingException;
import com.commafeed.backend.feed.parser.FeedParserResult;
import com.commafeed.backend.urlprovider.FeedURLProvider;
import io.quarkus.arc.All;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
/** Fetches a feed then parses it */
@Slf4j

View File

@@ -11,7 +11,11 @@ import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedSubscription;
import com.google.common.util.concurrent.MoreExecutors;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import java.time.Instant;
import java.util.List;
import java.util.concurrent.BlockingDeque;
@@ -23,7 +27,6 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Singleton

View File

@@ -3,12 +3,15 @@ package com.commafeed.backend.feed;
import com.commafeed.CommaFeedConfiguration;
import com.commafeed.CommaFeedConfiguration.FeedRefreshErrorHandling;
import com.google.common.primitives.Longs;
import jakarta.inject.Singleton;
import org.apache.commons.lang3.ObjectUtils;
import java.time.Duration;
import java.time.Instant;
import java.time.InstantSource;
import java.time.temporal.ChronoUnit;
import org.apache.commons.lang3.ObjectUtils;
@Singleton
public class FeedRefreshIntervalCalculator {

View File

@@ -14,7 +14,13 @@ import com.commafeed.backend.model.Models;
import com.commafeed.backend.service.FeedEntryService;
import com.commafeed.backend.service.FeedService;
import com.google.common.util.concurrent.Striped;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -25,8 +31,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
/** Updates the feed in the database and inserts new entries */
@Slf4j

View File

@@ -8,14 +8,18 @@ import com.commafeed.backend.HttpGetter.TooManyRequestsException;
import com.commafeed.backend.feed.FeedFetcher.FeedFetcherResult;
import com.commafeed.backend.feed.parser.FeedParserResult.Entry;
import com.commafeed.backend.model.Feed;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.Strings;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.Strings;
/**
* Calls {@link FeedFetcher} and updates the Feed object, but does not update the database, ({@link

View File

@@ -9,11 +9,14 @@ import com.commafeed.backend.model.UserSettings;
import com.commafeed.backend.service.PushNotificationService;
import com.commafeed.frontend.ws.WebSocketMessageBuilder;
import com.commafeed.frontend.ws.WebSocketSessions;
import jakarta.inject.Singleton;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
@Singleton
@RequiredArgsConstructor

View File

@@ -7,16 +7,19 @@ import com.rometools.rome.feed.synd.SyndContentImpl;
import com.rometools.rome.feed.synd.SyndEnclosureImpl;
import com.rometools.rome.feed.synd.SyndEntry;
import com.rometools.rome.feed.synd.SyndEntryImpl;
import java.util.Collections;
import java.util.Date;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.Collections;
import java.util.Date;
/** Utility methods related to feed handling */
@UtilityClass
@Slf4j

View File

@@ -1,15 +1,19 @@
package com.commafeed.backend.feed;
import com.google.common.primitives.Bytes;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.RandomUtils;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.RandomUtils;
@UtilityClass
public class ImageProxyUrl {

View File

@@ -2,11 +2,14 @@ package com.commafeed.backend.feed.parser;
import com.ibm.icu.text.CharsetDetector;
import com.ibm.icu.text.CharsetMatch;
import jakarta.inject.Singleton;
import java.nio.charset.Charset;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Strings;
import java.nio.charset.Charset;
@Singleton
public class EncodingDetector {

View File

@@ -18,7 +18,16 @@ import com.rometools.rome.feed.synd.SyndFeed;
import com.rometools.rome.feed.synd.SyndLink;
import com.rometools.rome.feed.synd.SyndLinkImpl;
import com.rometools.rome.io.SyndFeedInput;
import jakarta.inject.Singleton;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.xml.sax.InputSource;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.text.DateFormat;
@@ -28,13 +37,6 @@ import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemProperties;
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.xml.sax.InputSource;
/** Parses raw xml into a FeedParserResult object */
@Singleton
@@ -55,12 +57,6 @@ public class FeedParser {
public FeedParser(EncodingDetector encodingDetector, XMLCleaner xmlCleaner) {
this.encodingDetector = encodingDetector;
this.xmlCleaner = xmlCleaner;
// disable entity expansion limits added in JDK24+ (#1961)
// we already strip doctype declarations in XMLCleaner to prevent xxe attacks
// we also already limit the size of feeds we download in HttpGetter
System.setProperty(SystemProperties.JDK_XML_MAX_GENERAL_ENTITY_SIZE_LIMIT, "0");
System.setProperty(SystemProperties.JDK_XML_TOTAL_ENTITY_SIZE_LIMIT, "0");
}
public FeedParserResult parse(String feedUrl, byte[] xml) throws FeedParsingException {
@@ -77,8 +73,8 @@ public class FeedParser {
handleForeignMarkup(feed);
String title = feed.getTitle();
String link = feed.getLink();
String iconUrl = feed.getIcon() != null ? feed.getIcon().getUrl() : null;
String link = Urls.sanitize(feed.getLink());
String iconUrl = Urls.sanitize(feed.getIcon() != null ? feed.getIcon().getUrl() : null);
List<Entry> entries = buildEntries(feed, feedUrl);
Instant lastEntryDate = entries.stream().findFirst().map(Entry::published).orElse(null);
Instant lastPublishedDate = toValidInstant(feed.getPublishedDate(), false);
@@ -142,7 +138,7 @@ public class FeedParser {
Instant publishedDate = buildEntryPublishedDate(item);
Content content = buildContent(item);
entries.add(new Entry(guid, url, publishedDate, content));
entries.add(new Entry(guid, Urls.sanitize(url), publishedDate, content));
}
entries.sort(ENTRY_COMPARATOR);
@@ -170,7 +166,7 @@ public class FeedParser {
return null;
}
return new Enclosure(enclosure.getUrl(), enclosure.getType());
return new Enclosure(Urls.sanitize(enclosure.getUrl()), enclosure.getType());
}
private Instant buildEntryPublishedDate(SyndEntry item) {
@@ -274,7 +270,7 @@ public class FeedParser {
return null;
}
return new Media(description, thumbnailUrl, thumbnailWidth, thumbnailHeight);
return new Media(description, Urls.sanitize(thumbnailUrl), thumbnailWidth, thumbnailHeight);
}
private Long averageTimeBetweenEntries(List<Entry> entries) {

View File

@@ -1,10 +1,11 @@
package com.commafeed.backend.feed.parser;
import lombok.experimental.UtilityClass;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import lombok.experimental.UtilityClass;
@UtilityClass
class HtmlEntities {

View File

@@ -1,8 +1,9 @@
package com.commafeed.backend.feed.parser;
import org.apache.commons.lang3.math.NumberUtils;
import java.text.Bidi;
import java.util.regex.Pattern;
import org.apache.commons.lang3.math.NumberUtils;
public class TextDirectionDetector {

View File

@@ -1,13 +1,15 @@
package com.commafeed.backend.feed.parser;
import jakarta.inject.Singleton;
import java.util.Collection;
import java.util.regex.Pattern;
import org.ahocorasick.trie.Emit;
import org.ahocorasick.trie.Trie;
import org.apache.commons.lang3.StringUtils;
import org.jdom2.Verifier;
import java.util.Collection;
import java.util.regex.Pattern;
@Singleton
public class XMLCleaner {

View File

@@ -5,10 +5,12 @@ import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.TableGenerator;
import java.io.Serializable;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/** Abstract model for all entities, defining id and table generator */
@SuppressWarnings("serial")
@MappedSuperclass

View File

@@ -4,12 +4,15 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import java.sql.Types;
import java.time.Instant;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.JdbcTypeCode;
import java.sql.Types;
import java.time.Instant;
@Entity
@Table(name = "FEEDS")
@SuppressWarnings("serial")

View File

@@ -6,6 +6,7 @@ import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;

View File

@@ -8,11 +8,13 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.Instant;
import java.util.Set;
import lombok.Getter;
import lombok.Setter;
import java.time.Instant;
import java.util.Set;
@Entity
@Table(name = "FEEDENTRIES")
@SuppressWarnings("serial")

View File

@@ -1,18 +1,22 @@
package com.commafeed.backend.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import java.sql.Types;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.hibernate.annotations.JdbcTypeCode;
import java.sql.Types;
@Entity
@Table(name = "FEEDENTRYCONTENTS")
@SuppressWarnings("serial")

View File

@@ -7,11 +7,13 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import lombok.Getter;
import lombok.Setter;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "FEEDENTRYSTATUSES")

View File

@@ -6,6 +6,7 @@ import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;

View File

@@ -8,10 +8,12 @@ import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.Set;
import lombok.Getter;
import lombok.Setter;
import java.util.Set;
@Entity
@Table(name = "FEEDSUBSCRIPTIONS")
@SuppressWarnings("serial")

Some files were not shown because too many files have changed in this diff Show More