Compare commits

...
949 Commits
Author SHA1 Message Date
github-actions[bot] 6135c7e911 chore: release v2.9.0 (#968)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-09-03 22:03:03 +08:00
qwqcode 1ff0c4c10f chore(deps): upgrade deps 2024-09-03 21:18:16 +08:00
qwqcode 9cc9a6d6ab feat(config): add site_url config option (#967) 2024-09-03 20:07:43 +08:00
qwqcode d2225d565b fix(anti_spam): handle empty referer variable in anti-spam check (#853) 2024-09-03 19:37:39 +08:00
qwqcode e61911027c fix(auth): correct email verification code send button 2024-09-03 11:44:37 +08:00
qwqcode f29d2f81eb chore(sidebar/icon): swap sensitive hidden on/off icon 2024-09-02 16:52:52 +08:00
qwqcode 4b5ec39b8e feat(auth): add user profile and password changing (#966) 2024-09-02 15:56:04 +08:00
qwqcode 5dc2752cc1 fix(validator): restrict to allow only HTTP protocol 2024-09-02 14:52:57 +08:00
qwqcode cf6e687a2d fix(plugin_kit): import source path case error on linux 2024-09-02 11:16:23 +08:00
qwqcode 69ea7de22e chore(deps): update peerDependencies for plugin-auth 2024-09-01 23:03:43 +08:00
qwqcode 8fb7027186 chore(ci): add plugin-kit to artalk build process 2024-08-31 22:15:46 +08:00
qwqcode 88615f9a88 perf(auth): correct verify button position in register form 2024-08-31 21:56:25 +08:00
qwqcode f104629b40 perf(auth): add loading skeleton for login methods list 2024-08-31 21:54:28 +08:00
qwqcode 2f6b30deaf perf(auth): enhance visibility of skip button (#863) 2024-08-31 21:53:25 +08:00
qwqcode 2f7b9fa816 perf(auth): perform optical adjustment for consistent icon sizing 2024-08-31 21:45:53 +08:00
qwqcode 6d1041dc69 docs(auth): set auth.anonymous to false as default 2024-08-31 21:43:48 +08:00
qwqcode 9fb191976c refactor(ui/types): add Layer interface 2024-08-31 17:05:30 +08:00
qwqcode f20454bd00 perf(plugin_kit): improve typescript diagnostics output 2024-08-31 16:53:42 +08:00
qwqcode 64854107ef fix(plugin_kit): fix typescript lib path retrieval on win 2024-08-30 22:41:58 +08:00
qwqcode ac54eae179 chore(docs): add docker mirror tips 2024-08-30 12:05:24 +08:00
qwqcode aa92a92961 fix(api/comment_add): improve the security of comment add api (#964)
* fix(api/comment_add): refactor and improve the security of comment add api

* update
2024-08-29 23:29:36 +08:00
qwqcode d54652264b feat(ui/sidebar): add dark mode toggle for dashboard (#790) 2024-08-29 20:59:19 +08:00
qwqcode d6ececd014 fix(ui/stat): fix invalid backward compatible strategy (#880) 2024-08-29 20:54:30 +08:00
qwqcode 04ef002da1 fix(sidebar): correct total item count for pagination in sidebar 2024-08-29 18:43:49 +08:00
qwqcode a6b559d682 chore(icon): fix icon in sidebar on desktop devices 2024-08-29 18:31:39 +08:00
qwqcode 67b37b4612 chore(deps): upgrade frontend deps 2024-08-29 14:25:06 +08:00
qwqcode 3e81b2a8f2 chore(docker): resolve dockerfile rule violations 2024-08-29 14:22:03 +08:00
qwqcode 8a9480d05a feat(ui/sidebar): add page search by keywords in sidebar (#603) 2024-08-29 13:42:41 +08:00
qwqcode b3ed639be7 perf(style/sidebar): modify font-family for sidebar 2024-08-29 12:46:03 +08:00
qwqcode 6a0e06ea75 docs(ui/i18n): add more locale support for sidebar 2024-08-29 12:43:53 +08:00
qwqcode 92484cfa66 perf(ui/sidebar): enhance i18n translations for sidebar 2024-08-29 12:42:31 +08:00
qwqcode 1b0eff9568 perf(ui/sidebar): optimize setup process and i18n lazy load (#962) 2024-08-29 12:33:51 +08:00
qwqcode 2efd34248d perf(i18n): auto-load frontend i18n locale js sources 2024-08-29 11:47:57 +08:00
qwqcode c0a3026890 docs(ui/i18n): add translations for French, Korean, and Russian 2024-08-29 11:45:56 +08:00
qwqcode 392b6b15cf refactor(ui/user): rename nick to name in LocalUser data structure (#961) 2024-08-28 23:28:36 +08:00
qwqcode 6b58fd8a9d feat(ui/sidebar): add user search by keywords in sidebar (#710) 2024-08-28 19:50:38 +08:00
qwqcode 80e5ca5dc7 perf(ui/sidebar): mask sensitive input values in sidebar settings (#494) 2024-08-28 19:04:15 +08:00
qwqcode 50e967f71c feat(ui/date): add dateFormatter config option (#940) 2024-08-28 18:01:43 +08:00
qwqcode cf58a545b5 chore(deps): upgrade deps 2024-08-28 16:12:43 +08:00
qwqcode 270558129f fix(ui/dark_mode): apply dark mode config option before mounting ui (#890) 2024-08-28 12:40:47 +08:00
qwqcode 059bac8b5f perf(api/auth): add more specific error messages for login failures 2024-08-28 11:26:31 +08:00
qwqcode f1a86d59ca fix(ui/sidebar): disable admin password check dialog in sidebar 2024-08-28 11:12:30 +08:00
qwqcode adcb75a2e2 feat(ui/dashboard): new dashboard ui refresh for desktop devices (#957)
* feat(ui/dashboard): new dashboard ui refresh on desktop device

* add z-index for login dialog layer
2024-08-20 04:10:17 +08:00
qwqcode 4d7e157ff0 fix(ui/sidebar): show env variables in sidebar settings ui (#946) (#956)
* fix(ui/sidebar): show env variables in sidebar settings ui (#946)

* fix unit test
2024-08-19 16:27:20 +08:00
qwqcode 528847de7b chore(docs): add SECURITY.md 2024-08-18 23:41:31 +08:00
qwqcode 2b9d6bb573 chore(deps): upgrade docs and sidebar deps 2024-08-18 22:53:51 +08:00
qwqcode 393224cdb1 refactor(plugin_katex): use tokenizer extension of marked (#955) 2024-08-18 22:44:58 +08:00
qwqcode a925806d29 refactor(ui/marked): replace pkg-level marked with new class instance (#954)
* refactor(ui/marked): replace pkg-level marked with new class instance

* fix sidebar
2024-08-18 20:10:02 +08:00
qwqcode b97167a718 chore(docs): update FUNDING.yml 2024-08-17 16:10:48 +08:00
qwqcode 587523f0df feat(go): upgrade golang to v1.22.6 and some deps 2024-08-17 15:43:15 +08:00
qwqcode 08f58cd38b chore(deps/ui): upgrade deps for frontend 2024-08-17 15:07:56 +08:00
qwqcode 0803e235a4 chore(docker): update docker-compose.yml file sample 2024-08-07 18:50:14 +08:00
qwqcode 125a66611f chore(deps/go): upgrade gorilla/websocket 2024-08-05 17:13:11 +08:00
qwqcode 92a0e23c85 chore(plugin/katex): add artalk to peerDependencies in package.json 2024-08-02 10:54:16 +08:00
qwqcode c75b630e8a chore(plugin/lightbox): upgrade version of plugin-lightbox 2024-07-25 16:35:31 +08:00
qwqcode d22d34c223 fix(plugin/lightbox): fix import for non-browser env (#931)
* fix(plugin_lightbox): fix lightbox plugin import for non-browser env

* add artalk as peerDependency

* using default object of import result

* test and fix photoSwipe, fancyBox

* add minimal reproducible example

* refine docs
2024-07-25 16:30:34 +08:00
qwqcode 6fe8ffd2c4 chore(docs): remove obsolete cdn links 2024-07-21 19:35:30 +08:00
qwqcode f4d33fcf24 chore(auth/icon): fix missing microsoft auth icon (#929) 2024-07-16 14:28:43 +08:00
qwqcode 640f9904fb chore(docs): update config.md 2024-07-13 14:58:16 +08:00
qwqcode df62de09f3 fix(api/auth): register issue due to unremoved auth records after user deletion (#919) 2024-07-12 14:12:15 +08:00
qwqcode 68bcdbe3e8 fix(api/auth): migrate auth_identities when account merging (#920) 2024-07-12 13:26:27 +08:00
qwqcode e663893fd1 perf(notify): improve error messages for notify (#943) 2024-07-11 13:12:12 +08:00
qwqcode b85d845b71 chore(docs): revise docker compose env variable config (#933) 2024-06-21 21:20:31 +08:00
qwqcode acf7480b91 fix(api/auth): fix missing Microsoft oauth provider configuration (#929) 2024-06-19 22:10:11 +08:00
qwqcode be0dcd6b59 feat(ui/plugin): make ui plugin configurable 2024-06-19 21:00:32 +08:00
qwqcode 4d9445c84c chore(docs): refine some docs 2024-06-19 20:46:02 +08:00
qwqcode 1337e81cd4 fix(ui/plugin-kit): fix typescript lib folder for api-extractor in monorepo 2024-06-19 20:43:36 +08:00
qwqcode d053b953a6 refactor(ui/deps): remove abortcontroller-polyfill (#923) 2024-06-10 17:00:56 +08:00
qwqcode 2549052558 perf(app/init): generate translated config file by env variable ATK_LOCALE 2024-06-09 22:45:23 +08:00
qwqcode b8da04e308 chore(docs): update import-framework.md 2024-06-09 22:18:35 +08:00
github-actions[bot] c4a7162302 chore: release v2.8.7 (#918)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-06-09 19:14:50 +08:00
qwqcode 6012993fe9 chore(deps): upgrade go deps 2024-06-09 18:36:13 +08:00
qwqcode d4ed7f64b2 refactor(ui): fix linter issues for ui and docs (#917)
* refactor(ui): fix linter issues for ui and docs

* fix ci
2024-06-09 18:31:04 +08:00
qwqcode 93e3b2f184 perf(ui/dev): bump eslint to v9 (#915)
* perf(ui/dev): bump eslint to version 9

* add react eslint plugin and replace import with import-x
2024-06-09 15:20:04 +08:00
qwqcode 0e75457499 chore(deps): upgrade node and pnpm 2024-06-08 16:55:20 +08:00
zarev b8151bb789 docs(i18n): revise French translation (#913) 2024-06-08 16:50:06 +08:00
qwqcode 67922f34ad fix(api/auth): include render mustache params for verification email subject (#910) 2024-06-08 16:40:35 +08:00
qwqcode 7093e7e1c5 perf(gravatar): support both sha256 and md5 hash for gravatar (#912) 2024-06-08 16:22:26 +08:00
qwqcode c3558b7beb perf(dao): add singleflight for no-cache db find func 2024-06-08 13:48:37 +08:00
qwqcode 5fdf3a27ce fix(auth): failed to register by social account on mysql database (#902) 2024-06-06 14:57:35 +08:00
qwqcode f8f509c0de perf(gravatar): convert email to lowercase before hashing for gravatar 2024-06-04 18:39:51 +08:00
qwqcode 437d943691 chore(docs): tidy up and update links 2024-06-02 15:33:09 +08:00
qwqcode 401cf5c21a perf(conf): add cache for config metadata to boost startup speed (#892) 2024-06-02 15:04:29 +08:00
qwqcode 77e9a687ac docs(dev): refine contributing.md and translate to chinese 2024-06-01 21:27:00 +08:00
qwqcode 85f88cbba5 perf(ui/conf): exclude conf pvEl, countEl and statPageKeyAttr from remove server (#905) 2024-06-01 21:25:29 +08:00
qwqcode efb34c23e5 chore(docs): revise katex import introduction (#897) 2024-05-31 19:30:35 +08:00
qwqcode 822a85c9e3 chore(plugins): fix window not defined issue for plugin-kit 2024-05-30 21:47:46 +08:00
qwqcode 630a3b1ff8 chore(docs): fix docs katex css 2024-05-30 20:14:18 +08:00
qwqcode ca6f8ed09c fix(plugin_katex): fix event issue causing katex integration failure (#897) 2024-05-30 20:03:02 +08:00
qwqcode a0b0a33862 feat(plugin_kit): add vite plugin for developing artalk plugins (#904) 2024-05-30 19:31:55 +08:00
qwqcode 4868cd9992 docs: refine documentation 2024-05-30 19:10:55 +08:00
qwqcode 2dfee533da fix(api/stats): fix site_pv response body and add unit tests (#896) 2024-05-29 10:57:14 +08:00
qwqcode dcaaefc71b refactor(dao): add date field to the page json entity 2024-05-29 10:52:25 +08:00
qwqcode 499a57213e chore(docs): fix edit link and update cases.md 2024-05-28 17:49:47 +08:00
Ever Fu b7fc86b3c6 chore(docs): add hexo-theme-solitude to cases.md (#893) 2024-05-28 17:35:50 +08:00
qwqcode 161ff8bfc3 fix(conf_env): enhance environment variable loading for config (#892)
* fix(conf_env): enhance environment variable loading for config

* improve NumberKeysMapToSlice func and fix unit tests

* auto-generate docs table
2024-05-27 20:03:18 +08:00
qwqcode 1e36d45ec3 chore(ci): remove arm/v7 docker build 2024-05-26 17:36:00 +08:00
qwqcode d2161cc0fb refactor(dao): improve QueryDBWithCache func and concurrent unit tests (#884) 2024-05-26 17:15:32 +08:00
qwqcode abbddfe9b4 feat(sync): add keyed rw-mutex 2024-05-26 17:05:45 +08:00
qwqcode 860dd698e7 feat(go): upgrade golang to v1.22.3 and some deps 2024-05-25 18:36:52 +08:00
guangwu acb087887c fix(api/transfer_upload): close temp file in transfer upload endpoint (#877) 2024-05-25 18:22:50 +08:00
qwqcode dbb3c55148 refactor(transfer): improve the reliability of the transfer (#883) 2024-05-25 18:00:27 +08:00
qwqcode fdfeef8042 fix(ui/sidebar): unable to logout if user is not admin in control center 2024-05-24 16:39:22 +08:00
qwqcode 824f122dcb refactor(ui/stat): use class selector for pageview elements by default (#880)
The statistics UI component has been updated. The default selectors for `pvEl` and `countEl` have changed from `#ArtalkPV` and `#ArtalkCount` to `.artalk-pv-count` and `.artalk-comment-count` (see #826 for more details). However, it remains backward compatible with the `#ArtalkPV` and `#ArtalkCount` elements for older versions, no HTML client updates are necessary.

In this PR, we also introduced a configuration option called `statPageKeyAttr` (value `"data-page-key"` by default) for customizing the attribute name that the statistics component uses to fetch the page key.
2024-05-23 13:47:07 +08:00
qwqcode 53d46d82b6 perf(gravatar): use sha256 hashing algorithm for gravatar (#874) 2024-05-22 21:14:43 +08:00
qwqcode bb218d0ba4 docs(ip_region): add instructions for obtaining accurate IP under proxy 2024-05-15 21:37:16 +08:00
qwqcode 984071d4b6 refactor(transfer): strip domain from page key by default (#873) 2024-05-15 20:58:53 +08:00
qwqcode 34b24a1f36 fix(ui/height_limit): height limit issue for collapsed comments (#865) 2024-05-15 15:43:26 +08:00
qwqcode 58657524cf fix(ui/types): remove marked dependency in dts (#868) 2024-05-11 22:29:40 +08:00
Kent Liao b5db161697 chore(docs): fix syntax error in import-blog (#864)
hexo example.
2024-05-10 09:15:47 +08:00
github-actions[bot] 4dd0ae40e2 chore: release v2.8.6 (#862)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-05-09 13:43:53 +08:00
qwqcode 5dea08a3f2 feat(ci): include frontend dist files in release (#860) 2024-05-09 13:24:50 +08:00
qwqcode 92464085e6 chore(pkg_manager): upgrade pnpm to v9.1.0 2024-05-09 11:52:08 +08:00
qwqcode 28f1fa11bd chore: remove console logs 2024-05-07 14:00:28 +08:00
qwqcode 3de1f11f47 chore(docs/landing): add animation for ocean wave 2024-05-06 20:36:23 +08:00
qwqcode dff1813fa5 chore(docs/landing): fix airplane animation 2024-05-06 20:35:30 +08:00
vybfi f4475830da chore(docs): fix vue example code (#856) 2024-05-06 16:42:06 +08:00
qwqcode 9c85a85153 docs: update introduction document 2024-05-04 21:17:38 +08:00
qwqcode 5a63d4c63d fix(sidebar/site): unable to edit the new site urls 2024-05-04 16:15:02 +08:00
qwqcode b8afcbb21a fix(cache/user): user id cache from email lookup not cleared 2024-05-04 09:48:06 +08:00
qwqcode 0c0a207068 chore(deps): upgrade go and ui deps 2024-05-03 23:25:41 +08:00
qwqcode be939816aa chore(ip_region): mute ipv6 invalid log 2024-05-03 23:25:11 +08:00
qwqcode 45d1bc1241 fix(api/pv): add mutex for page pv record endpoint 2024-05-03 23:25:10 +08:00
qwqcode ef5899e079 docs(auth): add social login feature (#854) 2024-05-03 23:25:10 +08:00
qwqcode 7187d0f058 feat(ui/auth): plugin-auth for integrating social login (#854) 2024-05-03 23:24:58 +08:00
qwqcode 88aec7e767 feat(auth): user accounts merge tool (#854) 2024-05-03 21:54:15 +08:00
qwqcode a09628c4e8 feat(auth): social login api endpoints (#854) 2024-05-03 21:54:06 +08:00
qwqcode 23d0d868de feat(sync): add keyed mutex 2024-05-03 21:25:31 +08:00
qwqcode f3e356e450 chore(template): tidy up template pkg naming 2024-05-02 17:19:40 +08:00
qwqcode 170db0fc2a feat(ui/img_lazyload): add support for lazy loading images (#850) 2024-05-02 11:03:34 +08:00
qwqcode c3f730b0e7 fix(ui/height_limit): height limit not working while loading images (#849) 2024-05-01 22:53:33 +08:00
qwqcode e132c31150 fix(ui/marked): optimize same origin link judgment logic 2024-04-30 16:18:32 +08:00
qwqcode fa6648ecf5 fix(db/migrate): fix root_id migrate for database lacking recursive CTE support (#848) (#846) 2024-04-30 14:40:27 +08:00
qwqcode a9331b426e fix(dao): ensure find and create functions thread safe (#845)
* fix(dao): ensure find and create functions thread safe

* feat(db/migrator): provide tool for merging duplicate page
2024-04-30 14:17:24 +08:00
qwqcode fbd1cd984d fix(ui/dark_mode): add support for configuring dark mode in backend (#790) 2024-04-27 19:57:09 +08:00
qwqcode accd10cef4 fix(ui/dark_mode): unable to toggle dark mode for sidebar in auto mode 2024-04-27 19:55:20 +08:00
qwqcode 690eb47eaa docs(i18n): add translation for Korean and Russian 2024-04-27 19:11:29 +08:00
qwqcode fc0dcee06c feat(i18n): add incremental updates feature for i18n code scan tool 2024-04-27 19:09:34 +08:00
qwqcode 895bfbd5e2 chore(multi_push): add response status code check 2024-04-27 19:06:26 +08:00
qwqcode e254350211 feat(multi_push/lark): add card mode for lark push (#839) 2024-04-27 19:05:30 +08:00
qwqcode f226d476e5 chore(typo): fix typo for moderator.keywords.replace in conf 2024-04-27 13:26:49 +08:00
qwqcode ee131fe6ef fix(comments_get): include site_name for isolation in associated query for comment's page 2024-04-26 16:42:35 +08:00
qwqcode 43e4c901b8 chore(db_logger): increase the slow SQL warning threshold 2024-04-26 16:35:52 +08:00
qwqcode bd5da20dd6 fix(db_migrate): drop fk_comments_user foreign key constraint of the users table 2024-04-26 16:34:40 +08:00
qwqcode 116d8f1919 chore(ci): fix build workflow 2024-04-25 00:01:51 +08:00
github-actions[bot]andqwqcode 99b71a15f8 chore: release v2.8.5 (#844)
* chore: release v2.8.5

* Update CHANGELOG.md

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: qwqcode <22412567+qwqcode@users.noreply.github.com>
2024-04-24 23:19:18 +08:00
qwqcode 3255cb4b66 chore(deps): upgrade go deps 2024-04-24 23:11:29 +08:00
qwqcode 35d5f778b2 fix(transfer): retrieve root_id for imported comment data 2024-04-24 23:04:10 +08:00
qwqcode 9375ef812a fix(dao): prevent potential infinite loop in FindCommentRootID 2024-04-24 23:04:10 +08:00
qwqcode 44742c149e fix(db/migrate): issue with root id generation 2024-04-24 23:04:09 +08:00
qwqcode a4d5135379 perf(i18n): add translation for 'parameter is required' 2024-04-24 23:04:09 +08:00
qwqcode ddfaa603ca feat(conf/http): add http.proxy_header config option 2024-04-24 23:03:58 +08:00
qwqcode 6e13152fc1 fix(upload): add config option to solve request entity too large issue (#834) 2024-04-18 18:30:51 +08:00
qwqcode 0b16c9627a fix(ui/upload): unable to upload image when file extension is uppercase 2024-04-18 18:25:25 +08:00
qwqcode b613a4368c fix(log): improve log system and fix memory leaks (#843) 2024-04-18 18:25:19 +08:00
qwqcode 3098a75a05 perf(ui/version_check): beautify version upgrade notice 2024-04-15 15:05:42 +08:00
qwqcode d71ac6d156 chore(docs): update daemon.md 2024-04-15 14:42:13 +08:00
qwqcode 6c9a7e3884 chore(deps): upgrade go deps 2024-04-15 14:38:03 +08:00
qwqcode 65b440416d chore(ci): release workflow allows manual custom version 2024-04-15 14:32:36 +08:00
qwqcode f9084cbfb4 chore(changelog): skip v2.8.4 2024-04-15 14:32:36 +08:00
qwqcode 3c7ad1d0ef fix(ui/sidebar): user list not refresh when data is modified 2024-04-15 14:32:31 +08:00
qwqcode 1930d842f2 fix(ui/comment): missing reply comment data when inserting (#838) 2024-04-15 13:55:51 +08:00
qwqcode 751e4a866f fix(ui/comment): incorrect reply comment data in nested mode (#771) (#837) 2024-04-15 13:09:20 +08:00
Big_Cake 01364d1ddc docs(extras): add deploy guide for Valaxy (#836) 2024-04-15 12:20:09 +08:00
qwqcode ec6d2b2e60 fix(db/migrator): remove foreign key constraints and better root_id generation (#835)
Add function to delete all foreign key constraints when migration.

Leave relationship maintenance to the program and reduce the difficulty of database management. Because there are many different DBs and the implementation of foreign keys may be different, and the DB may not support foreign keys, so don't rely on the foreign key function of the DB system.
2024-04-14 23:46:22 +08:00
qwqcode 915b5f48b4 refactor(ui/prettier): add prettier code formatter 2024-04-14 23:42:06 +08:00
Mr.Hopeandqwqcode 16527ec4f3 perf(ui/pkg): add shorter export names (#821)
* feat(artalk): add shorter export names

* chore: tweaks

* chore: mute attw

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
2024-04-08 14:51:32 +08:00
Mr.Hope a7af2b7aaa chore(ui/deps): update deps for ui (#820) 2024-04-08 14:42:24 +08:00
github-actions[bot] 3ff891be90 chore: release v2.8.4 (#818)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-07 21:51:42 +08:00
dependabot[bot] 7d6faf6431 chore(deps/ci): bump the deps group in /.github/workflows with 4 updates (#784)
Bumps the deps group in /.github/workflows with 4 updates: [pnpm/action-setup](https://github.com/pnpm/action-setup), [github/codeql-action](https://github.com/github/codeql-action), [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) and [peter-evans/repository-dispatch](https://github.com/peter-evans/repository-dispatch).


Updates `pnpm/action-setup` from 2 to 3
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v2...v3)

Updates `github/codeql-action` from 2 to 3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

Updates `peter-evans/create-pull-request` from 5 to 6
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v5...v6)

Updates `peter-evans/repository-dispatch` from 2 to 3
- [Release notes](https://github.com/peter-evans/repository-dispatch/releases)
- [Commits](https://github.com/peter-evans/repository-dispatch/compare/v2...v3)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: deps
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: deps
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: deps
- dependency-name: peter-evans/repository-dispatch
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-07 21:47:42 +08:00
qwqcode 73d8ea97ed perf(conf/upgit): disallow custom executable path of upgit for security (#817)
BREAKING CHANGE: For UpGit users: Due to security reasons, Artalk no longer allows configuring the executable file path (img_upload.upgit.exec) for upgit. Please add it to system environment variables instead.
2024-04-07 21:43:44 +08:00
qwqcode c482e19f19 chore(sidebar): fix build type issue when upgrade deps
https://github.com/posva/unplugin-vue-router/issues/353
2024-04-07 20:10:19 +08:00
qwqcode 8c3042cdb1 chore(ui/deps): bump deps for ui 2024-04-07 19:57:03 +08:00
qwqcode ed9a78472d chore(ui/dev): bump node to v20.12.1 2024-04-07 19:49:39 +08:00
qwqcode ae5543df52 feat(go): upgrade golang to v1.22.1 and some deps 2024-04-07 19:29:47 +08:00
qwqcode c2c5a80d8d refactor(comments_get): reduce api complexity by introducing LiteDB (#800)
* refactor(comments_get): reduce interface complexity by introducing LiteDB

* test: add unit test

* add more unit test case
2024-04-07 19:17:01 +08:00
Otstar Lin de5e1b4000 fix(ui/lifecycle): keep root element during destroy (#810) 2024-04-02 22:29:08 +08:00
qwqcode b60cb585b6 perf(db): optimize N+1 query in comment list (#799) 2024-03-17 21:01:42 +08:00
qwqcode 44bca8d2f4 fix(cmd/gen): ensure directory before saving in gen cmd (#612) 2024-03-16 16:07:20 +08:00
qwqcode 9103a923a6 chore(ci/nightly): build arm64 on M1 macOS runner
https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/
https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
2024-03-16 15:23:53 +08:00
thun888 e4242512f8 chore(docs): update case link (#793)
* Update cases.md

* Update extras.md
2024-03-16 01:37:47 +08:00
zarev 0ebd16a5db docs(i18n): add French translation (#797) 2024-03-16 01:24:13 +08:00
qwqcode 0eb75f612a chore(ci/nightly): build arm64 on M1 macOS runner
https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/
https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
2024-03-16 01:12:39 +08:00
qwqcode 18e6ae5b17 chore(ci/nightly): improve nightly build workflow 2024-03-15 17:57:17 +08:00
qwqcode 1ee3c41199 feat(ci/build): add nightly build workflow 2024-03-15 12:54:19 +08:00
github-actions[bot] 8af713636c chore: release v2.8.3 (#788)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-03-04 22:13:11 +08:00
qwqcode 5bf6e5f1dc fix(exception): missing message field after refactoring exception data structure 2024-03-04 21:04:38 +08:00
qwqcode 929faf0722 fix(sidebar/login): cannot select a name with the same email upon login (#781) 2024-03-04 21:01:04 +08:00
qwqcode 5322f90383 fix(captcha/image): unable to display image captcha on initial load 2024-03-04 20:56:31 +08:00
qwqcode fa3575cbae fix(conf): skip patching IP region conf if disabled 2024-03-04 20:05:20 +08:00
qwqcode c94a34ffd7 feat(comment): add is_verified field for comment entity 2024-02-16 19:43:35 +08:00
qwqcode 50b49448b6 feat(app): add onConfUpdated hook 2024-02-15 23:02:33 +08:00
qwqcode 8ff3f5e875 refactor(dao): validate the args of the FindCreateUser function 2024-02-14 00:21:48 +08:00
qwqcode 640fa7ded4 feat(ui/plugins): support dynamic loading of ui plug-in scripts (#774) 2024-02-12 21:12:55 +08:00
qwqcode 18123f7002 refactor(origin): extract CheckURLTrusted function 2024-02-12 20:36:43 +08:00
qwqcode cf2094667d feat(api/domain): add GET /conf/domain endpoint 2024-02-11 23:47:04 +08:00
qwqcode 2cd2165f06 refactor(entity/user): extract CheckPassword function 2024-02-11 23:36:19 +08:00
qwqcode 4eada4b628 feat(api/auth): invalidate old auth tokens after changing password 2024-02-11 23:34:32 +08:00
qwqcode 05f3ad043a feat(ui/editor): add beforeSubmit hook for editor submitting 2024-02-11 23:11:04 +08:00
qwqcode 6e9083e75d feat(ui/api): add ctx.getApiHandlers() to handle error responses and expose hooks 2024-02-11 23:00:22 +08:00
qwqcode 7bbdb5900f fix(ui/layer): ensure immediate operation when calling show() after hide() 2024-02-11 22:36:18 +08:00
qwqcode 5be45315dc chore(style/icon): standardized icon css styles 2024-02-09 16:59:58 +08:00
qwqcode 5d20ff1ef5 chore(fiber_logger): correct the http status code range for err log 2024-02-06 16:03:04 +08:00
qwqcode 86e0eeafd1 perf(ui/editor): improve the icon details for editor 2024-02-05 21:49:04 +08:00
github-actions[bot] 49c1a87a67 chore: release v2.8.2 (#769)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-05 19:09:15 +08:00
qwqcode ec7f81cb83 chore(docs): import artalk css via node 2024-02-05 19:01:39 +08:00
qwqcode 4b115d7b6a perf(ui/editor): optimize editor styles for narrow-width screens 2024-02-05 17:19:53 +08:00
qwqcode 1bae6d8d2a perf(ui/editor): modify editor plug-in text buttons to icons for brevity 2024-02-05 17:19:53 +08:00
qwqcode bdafa19470 perf(ui/editor): place Cancel Reply at the bottom of editor area (#644) 2024-02-05 17:19:40 +08:00
qwqcode 342236b6a7 perf(ui/lite): disable ArtalkLite preview config option by default 2024-02-05 17:05:00 +08:00
qwqcode ffce9f9e85 fix(style): replace style break-all with break-word in content el (#644) 2024-02-05 15:05:58 +08:00
qwqcode 0097e041b1 fix(api/comments): ua field is optional and not required (#767) 2024-02-05 14:30:17 +08:00
github-actions[bot] 42da621dfc chore: release v2.8.1 (#766)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-04 22:21:43 +08:00
qwqcode 2f5dbaa022 chore(i18n): update zh-CN 2024-02-04 22:02:13 +08:00
qwqcode e181a6d5dd perf(style/sidebar): improve some detail in sidebar 2024-02-04 21:55:59 +08:00
qwqcode 7873b21fb7 fix(ui/scroll): scroll into view issue when relativeTo parameter is provided 2024-02-04 21:53:02 +08:00
qwqcode 2a219518a4 feat(ui/goto): improved solution of navigating to comment via link hash (#693) (#765) 2024-02-04 21:47:06 +08:00
qwqcode afa7888db0 chore(typo): fix comment typo 2024-02-04 20:26:34 +08:00
qwqcode f6a589d5b2 refactor(ui/list): refactor the list layout manager 2024-02-04 20:25:21 +08:00
qwqcode 41a09d5996 refactor(ui/comment): loose coupling between Comment and Context 2024-02-04 20:15:28 +08:00
qwqcode 191977c0df feat(api): add GET /comments/:id endpoint (#764) 2024-02-04 20:08:38 +08:00
qwqcode 5a4c06daee chore(ip_region): skip empty string 2024-02-04 19:48:26 +08:00
qwqcode c4942ab807 chore(Makefile): add http-client build cmd to update-swagger 2024-02-04 03:24:58 +08:00
qwqcode 6b83a9f632 chore(transfer): remove the url_resolver disabled warning msg 2024-02-04 02:25:33 +08:00
qwqcode 3c88c0c29c docs: supplement and refine fe-api.md 2024-02-04 02:22:49 +08:00
qwqcode 35aab6bedc fix(ui/list): unable to reply or delete comments after switching pagination 2024-02-04 01:40:07 +08:00
qwqcode 17033dc111 fix(ui/no_comment): always appears when creating comment 2024-02-03 23:45:48 +08:00
qwqcode 559df60f0d fix(ui/pv): missing pageTitle field in the PV request 2024-02-03 23:12:12 +08:00
qwqcode 22d4ec1c31 chore(docs): rename IP region in zh-CN 2024-02-03 21:44:37 +08:00
qwqcode d97ad5c843 fix(ip_region): unable to output the IP region correctly (#760) 2024-02-03 21:43:42 +08:00
qwqcode 34a67f647b chore(docs): update cdn source links 2024-02-03 19:58:38 +08:00
qwqcode 9c3228b8fc feat(config): add db.prepare_stmt config option (#760) (#762)
The Prepared Statement database feature is enabled by default. You can disable it in config file or a env variable `ATK_DB_PREPARE__STMT=0`.
2024-02-03 19:19:00 +08:00
qwqcode 4012d3e090 fix(cmd/admin): update user role to admin if already exists 2024-02-03 16:54:13 +08:00
qwqcode bc1c4d315c fix(api/comments): counting comments issue in PostgreSQL db (#760) (#761) 2024-02-03 15:34:25 +08:00
qwqcode 2a6f0c56a4 chore(docs): fix script cdn links 2024-02-01 21:43:52 +08:00
github-actions[bot] 46e2a15116 chore: release v2.8.0 (#756)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-02-01 00:19:18 +08:00
qwqcode c068f5a240 chore(deps): bump golang deps 2024-02-01 00:11:34 +08:00
qwqcode 29bf49958f perf(ui/pagination): replace the prev/next text on pagination buttons with icons (#743) 2024-01-31 23:59:58 +08:00
qwqcode 2fcad539ca perf(ui/i18n): refine some translation (#743) 2024-01-31 23:28:56 +08:00
qwqcode 45b79124c9 chore(ui/deps): bump deps for ui 2024-01-31 20:27:14 +08:00
qwqcode 2b44452234 refactor(ui): optimize init and update lifecycle events 2024-01-31 19:44:40 +08:00
qwqcode 0e0b53fe9e perf(ui/sidebar): prevent potential token leakage by clearing query in iframe url
The previous referrer policy was already set to `strict-origin`, but to further enhance security, this modification was made.
2024-01-30 23:07:37 +08:00
qwqcode dba5ba5277 fix(ui/no_comment): flickering when clearing list before fetch 2024-01-30 22:24:53 +08:00
qwqcode 942aaf654f fix(ui/sidebar): incorrectly increasing pv count in sidebar (#724) 2024-01-30 20:27:19 +08:00
qwqcode 37e0091502 perf(ui/conf): support for watching partial changes in config with watchConf() (#755) 2024-01-30 19:14:09 +08:00
qwqcode a7c3f1bbda feat(notify): add notify_pending config option (#728) (#754) 2024-01-29 21:22:36 +08:00
qwqcode a40a070bdb chore(fix/pin): fix pinned comment sort rule 2024-01-29 14:46:19 +08:00
Frost Ming 082bfc63d1 fix(ui/editor): prevent propagation of click event in editor (#734)
Signed-off-by: Frost Ming <me@frostming.com>
2024-01-29 14:12:21 +08:00
qwqcode 0de8009e65 feat(ui/admin): add logout button in admin panel (#488) (#753)
fixes #488
2024-01-29 13:56:02 +08:00
qwqcode a5e4c81e72 fix(ui/sidebar_layer): sidebar still displays when login is required 2024-01-29 13:34:51 +08:00
qwqcode c52c26145c fix(ui/layer): unexpected behavior with multiple items when closing 2024-01-29 00:47:50 +08:00
qwqcode f5e310a182 chore(ui/ctx): remove token public in context 2024-01-28 22:14:24 +08:00
qwqcode 0828b91602 refactor(ui/comment): rename class Comment to CommentNode 2024-01-28 22:13:20 +08:00
qwqcode c4f664e412 refactor(ui/ctx): add getComments and getCommentNodes in context (#752)
* refactor(ui/ctx): add `getComments` and `getCommentNodes` func in context

* fix import
2024-01-28 22:03:15 +08:00
qwqcode a084c50095 refactor(transfer): normalize transfer payload parameter name 2024-01-28 13:33:03 +08:00
qwqcode 9dacd0954d fix(cache): unable to change admin list after caching (#748) (#750) 2024-01-26 22:27:10 +08:00
qwqcode 50b0a6068c chore(ci): fix ui test trigger rules 2024-01-26 17:16:18 +08:00
qwqcode 4689492bf5 fix(ui/pagination): auto load list when scroll reaches bottom 2024-01-26 17:09:56 +08:00
qwqcode 6ee9ee9ea4 fix(ui/lite): correct the instance name for compiling ArtalkLite (#740) 2024-01-26 11:45:22 +08:00
qwqcode 8e3a743ed8 fix(i18n): sidebar language cannot be changed
Also follow 0d35e66
2024-01-26 11:42:39 +08:00
qwqcode 9550a16a0c chore(fetch): returns empty object when json deserialize failed 2024-01-25 01:07:48 +08:00
qwqcode a9edac3ce0 refactor(api): update swagger file of API v2
BREAKING CHANGE: For Developers: The HTTP API has now been updated to version v2, with a lot of adjustments made, such as changing to Restful API style, request type, request body, response body, etc. data structure, adding error response codes. You can refer to #735 or https://artalk.js.org/http-api Please update all your existing clients to adapt to the new v2 server. The new base path is `/api/v2/`. The UI package's HTTP client has been implemented to auto-generate based on `Swagger.json`, and there have been a lot of adjustments to the `artalk.ctx.getApi()` related code. In addition, the HTTP API no longer enforces checks on the header's `Origin` and `Referer` (to implement strict isolation of different sites) but still maintains the original CORS origin check.

For General Users: Now all administrators have the same level of authority (there is no longer super admin authority), the function of assigning sub-administrators with independent scope authority to individual sites has been removed, which can simplify the HTTP server maintenance and implementation. Upgrading only requires updating the client and server application at the same time, and there are no additional operations.
2024-01-24 21:53:34 +08:00
qwqcode 589850d311 refactor(api): refactor HTTP API to version 2 (#735)
* refactor(api): refactor HTTP API to version 2

* refactor: remove forced site_origin check

* refactor: update http client

* fix

* add more api description and error code

* reduce nestings in response structures

* separate unread

* refactor(api/comments): get comments

* refactor: frontend api module

* chore: remove vite temporary file

* chore: restore swagger file

* update

* 移除为管理员分配站点名的站点隔离功能,简化实现

* refactor pagesAllFetch

* fix ci

* remove useless codes

* limiter protected paths

* add test for version endpoint

* rename handler code files

* code file separate

* fix some bug of interacting with backend

* add fetch error class for handling

* fix and rename

* refactor: checker support both `Promise` and callback fn

* fix new checker captcha iframe url

* rename and add swagger id field

* replace tab with spaces in go comment

* chore: refine

* complete the validate tag for request fields and enable `--defaultRequired`

90% of the request fields of our API are required,100% of response fields in our API are required.
Each field add validate:"required" is easy to miss.

* replace original api client with auto-generated codes

* artalk pkg apply new api client

* artalk-sidebar pkg apply new api client

* fix issues

* fix sidebar locale conf and refactor user login

* fix and refactor captcha and limiter

* fix ui testing

* add script to build http client by swagger.json
2024-01-24 21:33:30 +08:00
qwqcode 9ba9439831 chore(typo): fix typo for login in zh 2024-01-24 21:14:50 +08:00
qwqcode 38f6b6996a docs: update multi-sites manual (#747) 2024-01-24 21:01:56 +08:00
qwqcode 1e16570b2f chore(ci): fix ui test trigger rules 2024-01-24 16:24:36 +08:00
qwqcode 889adc6bae chore(docs): update security.md 2023-12-31 23:46:34 +08:00
qwqcode 0de59911b3 chore(docs): fix broken links 2023-12-29 12:40:04 +08:00
qwqcode f22e557b1c feat(go): upgrade golang to v1.21.5 and some deps 2023-12-28 23:26:56 +08:00
qwqcode 92ff757efc chore: fix docker build ci workflow 2023-12-28 21:43:17 +08:00
github-actions[bot]andqwqcode 63165599ce chore: release v2.7.3 (#726)
* chore: release v2.7.3

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: qwqcode <22412567+qwqcode@users.noreply.github.com>
2023-12-28 17:06:57 +08:00
qwqcode a5b428d1ec refactor(test/ui): add more ui api tests 2023-12-28 16:56:00 +08:00
qwqcode cf3f9b1ac3 chore: patch pacakge.json for i18n exports 2023-12-28 15:43:30 +08:00
qwqcode c212d67f49 perf(ui/build): better dts generation (#689)
* chore: move types as a subfolder of src

* perf(ui/build): better dts generation

* chore: update pnpm-lock.yaml

* chore: fix env variable on windows

* fix i18n types
2023-12-28 15:25:01 +08:00
qwqcode b00a257699 docs: update ui api documentation 2023-12-26 22:18:43 +08:00
3698c0c593 refactor(ui/conf): better handling of mutable config (#722)
* fix(ui): mergeDeep causes some configurations to be overridden by the default configuration

* fix: config always get override by defaults

Signed-off-by: Frost Ming <me@frostming.com>

* refactor(ui/conf): better handling of mutable config

* chore: fix path issue on win env

* fix: mergeDeep avoid prototype pollution

BREAKING CHANGE: Directly referencing `artalk.conf` and `artalk.$root` is deprecated. Please use functions instead: `artalk.getConf()` and `artalk.getEl()`.

---------

Signed-off-by: Frost Ming <me@frostming.com>
Co-authored-by: syfxlin <i@ixk.me>
Co-authored-by: Frost Ming <me@frostming.com>
2023-12-26 22:13:37 +08:00
qwqcode 32a398609c chore(tsconfig): modify moduleResolution to bundler 2023-12-26 00:30:50 +08:00
qwqcode 54729fbafc chore(build): use vite internal mergeConfig func 2023-12-26 00:06:21 +08:00
qwqcode b74e5cf94c refactor(ui/test): add vitest for unit testing 2023-12-26 00:03:08 +08:00
Frost Ming 475dd933fe fix(ui/init): stack overflow when merging with config defaults (#717)
Close #716
2023-12-23 21:40:18 +08:00
qwqcode 60e0e7e61a chore(ci): fixed tag version for git checkout branch 2023-12-23 01:32:19 +08:00
qwqcode e4a42d3a90 refactor(docker): add --build-arg argument to skip ui build 2023-12-22 23:54:32 +08:00
qwqcode d86cd73ea6 refactor(ci): better release workflow 2023-12-22 22:06:09 +08:00
qwqcode 67280f2ca2 feat(ci): add dry-run mode for build workflow 2023-12-22 02:30:54 +08:00
qwqcode a8bcd41f36 refactor(ui): refactor directory structure (#712)
* refactor(ui): refactor directory structure

* update config files

* update github workflows

* update vscode settings.json

* update docs

* update build scripts

* tidy up

* fix docs build
2023-12-21 23:51:26 +08:00
qwqcode 04cf137a74 feat(cmd): support cli flag for creating admin account 2023-12-21 22:35:10 +08:00
qwqcode d542e98581 chore(eslint): fix sidebar eslint configuration 2023-12-21 22:28:24 +08:00
qwqcode dfaf95bf1d chore(docs): bump Artalk to v2.7.2 2023-12-21 01:51:36 +08:00
github-actions[bot] 0a89426c93 chore: release v2.7.2 2023-12-20 17:20:40 +00:00
qwqcode 7a026ef0e2 fix(sidebar): sidebar language switch and config save issue (#708) 2023-12-21 01:14:49 +08:00
qwqcode 855f6c261f docs(i18n): add translation for open button 2023-12-20 23:35:58 +08:00
qwqcode 7099598a92 fix(ui): add referrerpolicy attribute for iframe (#687) (#707) 2023-12-20 23:34:46 +08:00
qwqcode ad8851ea94 fix(ui/pagination): auto switch page by url hashtag issue (#693) 2023-12-20 21:44:06 +08:00
qwqcode def9dc2707 fix(ui/sidebar): refactor settings and fix save issue (#677) (#706) 2023-12-20 20:53:04 +08:00
Mr.Hopeandqwqcode 91228a9446 docs(refactor): organize the pkgs and fix some issues (#702)
* docs: rebuild docs

* chore: fix eslint

* ci: add docs build test

* update test-docs.yml

* fix script

* add netlify.toml

* fix docs:patch

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
2023-12-19 21:55:04 +08:00
qwqcode 7a0a9dbd92 chore(ci): fix ci pnpm version 2023-12-19 17:07:23 +08:00
dependabot[bot] 441c4fa6a9 chore(deps/ui): bump the dev-deps group in /ui with 3 updates (#698)
Bumps the dev-deps group in /ui with 3 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) and [@vue/tsconfig](https://github.com/vuejs/tsconfig).


Updates `@typescript-eslint/eslint-plugin` from 6.14.0 to 6.15.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.15.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 6.14.0 to 6.15.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.15.0/packages/parser)

Updates `@vue/tsconfig` from 0.5.0 to 0.5.1
- [Commits](https://github.com/vuejs/tsconfig/compare/v0.5.0...v0.5.1)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: "@vue/tsconfig"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-19 17:04:01 +08:00
Mr.Hope a16169f69d chore(docs): fix redocly config (#696) 2023-12-19 17:00:58 +08:00
da42676656 chore(deps): bump frontend deps (#679)
* chore: bump deps

* chore: add exports field

* chore: remove src folder

* fix: vite cjs deprecated warning

* chore(ci): fix test ci

* chore: update linter

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
Co-authored-by: qwqcode <22412567+qwqcode@users.noreply.github.com>
2023-12-19 16:54:34 +08:00
qwqcode f3a42e892f chore(ci): fix test ci 2023-12-18 23:59:18 +08:00
Mr.Hope 6a53597485 chore(docs): update README.md (#691) 2023-12-18 23:19:46 +08:00
qwqcode 60336e567d test(ci): migrate UI tests back to Github Actions (#692) 2023-12-18 23:16:16 +08:00
Mr.Hopeandqwqcode 8918c62ffd chore: update description and fix typos (#684)
* chore: update description

* chore: fix typos

* chore: tweaks

* chore: fix case

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
2023-12-18 21:21:42 +08:00
qwqcode 362fc19cd8 feat: patch locale config from zh-cn to zh-CN (#678) 2023-12-18 20:17:04 +08:00
qwqcode 1b938752ff fix(ui/dark-mode): potential memory leak issue in auto mode (#688) 2023-12-18 19:14:58 +08:00
qwqcode 835a886dc8 test(ssg): add SSG test case (#675) 2023-12-18 19:09:04 +08:00
qwqcode f390b57fe7 refactor(ui): move window references into function scope (#675) 2023-12-18 19:05:57 +08:00
qwqcode 6d21a0f204 refactor(ui/api): losing coupling between Api and User 2023-12-18 18:37:18 +08:00
qwqcode a1d0c37828 refactor(ui/user): user class no longer globally singleton 2023-12-18 18:37:18 +08:00
github-actions[bot] 763fbc417e chore: release v2.7.1 2023-12-17 17:24:29 +00:00
qwqcode 776d5e66fe docs(i18n): add translation of update notice 2023-12-18 01:22:53 +08:00
qwqcode 10c0975ce0 fix(build): generate source maps to ease debugging 2023-12-18 00:53:54 +08:00
qwqcode 7286642fc9 fix(ui): static method export issue in JS module (#669) 2023-12-18 00:46:56 +08:00
qwqcode 8db4fb3524 fix(cout-widget): loadCountWidget issue 2023-12-17 23:50:44 +08:00
qwqcode 08be04979d chore(docs): bump Artalk to v2.7.0 2023-12-17 20:33:21 +08:00
github-actions[bot] d7ea9ba43f chore: release v2.7.0 2023-12-17 11:57:30 +00:00
qwqcode bad248534c docs: revise and add more examples
BREAKING CHANGE: The following top-level functions exported by the 'artalk' npm package have been deprecated: `Artalk.update`, `Artalk.reload`, and `Artalk.destroy`. These methods now require invocation on an instance created by either `Artalk.init` or `new Artalk`. Please utilize instance-level methods instead, such as `artalkInstance.update`. For more information, refer to  [the documentation](https://artalk.js.org/guide/frontend/import-framework.html). The update was implemented to enable the concurrent creation of multiple instances, adapting to situations where Vue components are simultaneously referenced across various pages. Initially, only a singular instance was permitted to mitigate memory leak concerns. However, this proved limiting for scenarios involving the caching of multiple component instances through 'keep-alive.' To better suit intricate SPA application needs, the choice was made to permit the creation of multiple independent instances. It's crucial to remember to manually invoke the `artalk.destroy` method when releasing components to avoid memory leaks (Issue #660).
2023-12-17 19:16:33 +08:00
Zijing Zhang f56ac4eabc perf(cache): implement GC feature for simple_cache pkg (#656)
* feat: garbage collection feature

A new `GC()` method has been added to the `Cache` struct,
which performs garbage collection by deleting expired entries from the
cache.
2023-12-17 02:32:47 +08:00
qwqcode bbe2e8416c chore(docs): more description for VitePress example 2023-12-17 02:23:43 +08:00
qwqcode d44e79b1f4 docs(import): update the examples in import-framework.md (#665) 2023-12-17 01:54:21 +08:00
qwqcode e816dd686c fix(api/img-upload): public_path config enables the use of full url (#659) (#664) 2023-12-17 01:29:59 +08:00
qwqcode c9ea8f6162 fix(lifecycle): create multi-instances at the same time (#660) (#663) 2023-12-17 01:16:27 +08:00
qwqcode 87102cd3b0 refactor(ui/layer): better layer implements and independence (#662) 2023-12-17 01:10:22 +08:00
qwqcode 8b6bab828d fix(ui/dark-mode): setDarkMode cannot save to instance config (#661) 2023-12-17 01:04:30 +08:00
qwqcode 9fb658599a test(vue): add test cases for vue framework 2023-12-17 00:48:24 +08:00
qwqcode f8c33003a8 chore(docs): replace artalk to npm import in docs 2023-12-15 20:20:24 +08:00
qwqcode b97136b83f chore(docs): tidy up documentation 2023-12-13 19:09:14 +08:00
qwqcode df3e983e7f docs(conf): disable frontend.uaBadge config option by default 2023-12-13 19:06:57 +08:00
qwqcode 1b878fb3cc fix(ui): scroll to the center of the viewport issue 2023-12-13 18:57:03 +08:00
LeenHawk aa87ab94f5 docs(deploy): add deployment guide for render.com (#649)
* 添加render.com部署指南文章链接

* Update
2023-11-21 21:38:26 +08:00
qwqcode 4e9afd9761 fix(ui/editor): fix position of the comment box when replying (#643) (#648) 2023-11-20 19:21:44 +08:00
qwqcode 2b7d0ecb72 chore(ci): integrate with codecov 2023-11-19 23:35:12 +08:00
qwqcode 603c7d9439 docs: provide clearer and more detailed instructions in CONTRIBUTING.md 2023-11-05 22:48:00 +08:00
qwqcode fb93231b35 feat(ui/test): add end-to-end (e2e) testing using Playwright 2023-11-05 22:45:53 +08:00
qwqcode fed83263e2 fix(notify_pusher): panic when admin ids array is empty (#634) 2023-11-03 10:39:56 +08:00
qwqcode 9dc2d83486 chore(dev): fix .eslintignore in vscode
Add this config in `.vscode/settings.json`: `{"eslint.workingDirectories": ["./path/to/nested/front/project"]}` In this case, your `.eslintignore` file should be located in the nested path location (you have a front project in a nested folder inside the main project at root).
2023-11-01 10:59:58 +08:00
qwqcode d918caaf81 fix(ui/conf): sanitize noComment conf option for security (#624) 2023-10-31 20:11:47 +08:00
qwqcode d44212bd90 refactor(ui/marked): separate markdown related codes 2023-10-30 20:13:18 +08:00
qwqcode 37d4ca76fa refactor(ui): reduce coupling with ContextApi 2023-10-30 19:50:32 +08:00
qwqcode 8cc39f322c chore(ui/deps): downgrade eslint-import-resolver-typescript
Downgrade `eslint-import-resolver-typescript` to version 2.7.0 to resolve linting issue on Windows development environment.

https://github.com/ArtalkJS/Artalk/discussions/621#discussioncomment-7416173
2023-10-29 22:59:47 +08:00
qwqcode 2b4e80651a feat(ui): support scrollRelativeTo config option 2023-10-29 21:52:59 +08:00
qwqcode 415fa0f2e3 chore(ui/sidebar): fix sidebar dependant issues caused by refactoring 2023-10-29 21:51:54 +08:00
qwqcode 91809002d7 chore(ui): fix issues caused by refactoring 2023-10-29 19:01:16 +08:00
qwqcode dcaad1b2d5 chore(ui/lint): follow the import/no-cycle eslint rule 2023-10-29 13:12:36 +08:00
qwqcode 5e635bba68 chore(ui/list): let the service of list non-optional 2023-10-28 20:33:38 +08:00
qwqcode d136d086eb refactor(ui/stat): losing coupling of CountWidget 2023-10-28 20:07:55 +08:00
qwqcode 9fe765f874 refactor(ui/api): loose coupling between Api and Context 2023-10-28 00:02:17 +08:00
qwqcode 72317ead34 refactor(ui): separate standalone admin-only-elem checker 2023-10-27 22:50:24 +08:00
qwqcode 75c7914fb1 refactor(ui/types): better ArtalkType import and export (#620) 2023-10-27 22:24:53 +08:00
qwqcode 863b4deec0 refactor(ui/conf): loose coupling between config and list fetch 2023-10-27 17:23:05 +08:00
qwqcode 6e6fd8d587 refactor(ui/marked): loose coupling with marked func 2023-10-27 16:32:24 +08:00
qwqcode 1608911328 refactor(ui/list): separate list into standalone components (#618)
* refactor(ui/list): separate the functions of list

* fix

* move files
2023-10-27 14:28:58 +08:00
qwqcode 87a62961b6 fix(style/list): replace float to text-align in footer part (#619) 2023-10-27 00:24:11 +08:00
qwqcode e6a9748e70 refactor(ui/plugin): further divide functionality into plugins (#615)
* move stat to plugins folder

* move editor plugs to common plugins folder

* implement list-close-editor standalone plugin

* impl StateManager for Loose Coupling of Reply, Edit, and Submit Components

* rename

* remove Mover dep in editor edit state plugin

* rename editor state plugins

* refactor header plugin of editor

* separate header plugins

* add and remove event binding

* fix plugin btn ui refresh when conf updating

* rename editor plugins and remove plug classname suffix

* editor kit reload plugin when conf-loaded

* impl clear method in editor-kit class

* separate version-check from list

* separate unread from list

* make context maintain globally accessible `page` data

* rename plug to plugin

* wrap the options of List up

* separate functionalities of list

* rename
2023-10-20 17:14:53 +08:00
qwqcode 0f35532f0b refactor(editor): refactor plug kit and events (#613) 2023-10-17 20:11:47 +08:00
qwqcode d21e47f881 refactor(ui/event): refactor core event manager (#611) 2023-10-15 23:08:31 +08:00
qwqcode 8d11a239fa refactor(editor): refactor editor plugin manager (#609)
* refactor(editor): refactor editor plugin manager

* update

* modify editorTravelBack to editorResetUI
2023-10-15 21:05:30 +08:00
github-actions[bot] 8867eb296c chore: release v2.6.4 2023-10-12 06:19:33 +00:00
qwqcode a53ddc9f76 feat(go): upgrade golang to v1.21.3 and some deps 2023-10-12 14:14:07 +08:00
qwqcode 5ee9e76dcf fix(style): fix copyright text overlay on send button (#607) 2023-10-12 13:35:24 +08:00
qwqcode 3d5f77ab35 fix(email): sender not initialized correctly 2023-10-12 13:30:45 +08:00
qwqcode 25a4f48e5e fix(editor): fix duplicate event binding when update conf (#605) 2023-10-12 09:48:34 +08:00
qwqcode 2dc3bc8934 test(simple_cache): add unit test 2023-09-25 21:15:58 +08:00
qwqcode 7b1bb25d6a test(image_captcha): add unit test 2023-09-25 21:07:05 +08:00
qwqcode 9bed5be236 test(email): add unit test for queue 2023-09-25 20:54:22 +08:00
qwqcode ec0ef12b0e refactor(anti_spam): refactor anti_spam pkg and add unit test (#589)
* refactor(anti_spam): refactor anti_spam pkg and add unit test

* add more test
2023-09-21 21:48:56 +08:00
github-actions[bot] 5d2950f842 chore: release v2.6.3 2023-09-20 08:40:36 +00:00
qwqcode 25c2f30165 chore(deps): upgrade go app deps 2023-09-20 16:36:33 +08:00
qwqcode d8b49773b3 feat(config): add db.ssl to enable db ssl mode (#587)
* feat(config): add `db.ssl` to enable db ssl mode

* update artalk.example.simple.yml

* add docs

* modify conf
2023-09-20 16:19:19 +08:00
qwqcode 2c8107a4b7 chore: remove page accessible_url field in database storage 2023-09-20 15:24:46 +08:00
qwqcode 9f8aba068e perf(config): add error message for timezone setting (#586)
* perf(config): add error message for timezone setting

* update
2023-09-20 15:20:48 +08:00
qwqcode e40235b1c7 fix(notify_tpl): fix template render result in notify case 2023-09-20 14:15:54 +08:00
qwqcode e050544d21 refactor(renderer): abstract func of template renderer for multi-cases (#585)
* refactor(email_renderer): abstract function of template renderer for multi-cases

* abstract template loader

* add render test

* update docs

* chore: move pkg to template

* abstract template pkg
2023-09-20 12:10:20 +08:00
qwqcode da692649bc docs: new landing page 2023-09-17 17:42:51 +08:00
github-actions[bot] a0892fc4c0 chore: release v2.6.2 2023-09-12 09:43:50 +00:00
qwqcode c1e365fdfd chore: relicense from LGPLv3 to MIT 2023-09-12 17:02:41 +08:00
qwqcode e6e6d2aa54 perf(style): modify z-index less than 5 (#578) 2023-09-12 16:41:11 +08:00
qwqcode ac70cd4c9d fix(cmd): remove app instance creation when mini boot (#577) 2023-09-12 16:35:02 +08:00
qwqcode 600030b528 chore(script): move dev config from local to data folder 2023-09-12 16:09:37 +08:00
github-actions[bot] 4e1537b4f0 chore: release v2.6.1 2023-09-11 08:37:27 +00:00
Moraxyc 8a8aac945d docs(extras): add deploy guide for railway.app (#567) 2023-09-11 16:35:55 +08:00
Moraxycandqwqcode 89be748dee docs(config): add info about env variables (#566)
* doc(config): add info about env variables

* modify

* modify

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
2023-09-11 16:34:26 +08:00
qwqcode 6c35fe9ded fix(captcha): image captcha base64 response issue (#575) 2023-09-11 15:17:11 +08:00
qwqcode 9ea6e8d981 build: fix build-app workflow by disable cache 2023-09-01 21:59:57 +08:00
github-actions[bot] 2c89c2d633 chore: release v2.6.0 2023-09-01 13:15:41 +00:00
qwqcode 5eddd9ff05 feat(config): support load env variables as config (#564) 2023-09-01 19:34:57 +08:00
qwqcode 9fdfb2a043 fix(ui): fix plug cannot disable issue (#563) 2023-09-01 17:56:45 +08:00
qwqcode 2bdb806aaf refactor(conf): better config.NewFromFile with error handle 2023-09-01 17:02:05 +08:00
qwqcode a1b3f1a1f7 fix(cache): child comment ids store after comment updated 2023-09-01 17:02:05 +08:00
qwqcode dc333e5a9a refactor(core): better AppService func with error handle 2023-09-01 17:02:04 +08:00
qwqcode f0ecff9199 fix(config): fix ip region patch 2023-09-01 17:02:04 +08:00
qwqcode e3ccc655c5 fix(limiter): limiter log ignore options method req 2023-09-01 17:02:04 +08:00
qwqcode 04a96d4ab8 chore(build): upgrade pnpm and node 2023-09-01 17:02:03 +08:00
qwqcode 71e0fcec75 fix(limiter): fix limiter always mode 2023-09-01 17:02:03 +08:00
qwqcode 963d3cf3d9 fix(cmd): fix parse root cmd global flags 2023-09-01 17:02:03 +08:00
qwqcode 2669b0efe8 perf(cmd): support command mini boot mode 2023-09-01 17:02:03 +08:00
qwqcode a8b4eb6047 test(utils): add tests for utils 2023-09-01 17:02:02 +08:00
qwqcode cc7b2f574c test(ip_region): add tests for ip_region 2023-09-01 17:02:02 +08:00
qwqcode 150de6d7c0 test(limiter): add tests for limiter 2023-09-01 17:02:02 +08:00
qwqcode 1da3f6420e test(artransfer): add tests for artransfer 2023-09-01 17:02:02 +08:00
qwqcode 919dfa43d0 test(db): add tests for db 2023-09-01 17:02:01 +08:00
qwqcode b6805ce948 fix(db): fix dsn strings for mysql connections (#541) 2023-09-01 17:02:01 +08:00
qwqcode 137610aa82 test(i18n): add tests for i18n 2023-09-01 17:02:01 +08:00
qwqcode 0cbb5b2dd1 test(core): add tests for core 2023-09-01 17:02:00 +08:00
qwqcode 9e59fefc8a test(cache): add tests for cache and dao cache adaptor 2023-09-01 17:02:00 +08:00
qwqcode 6ead92db54 refactor(cache): cache code tidy-up 2023-09-01 17:02:00 +08:00
qwqcode 388b5b8b24 refactor(cache): refactor cache pkg 2023-09-01 17:02:00 +08:00
qwqcode e15e22ecda chore: move .chglog as a subfolder to .github 2023-09-01 17:01:59 +08:00
qwqcode 8336bb0345 chore: fix ci testing 2023-09-01 17:01:59 +08:00
qwqcode fc6c6286db refactor(dao_cache): add dao_cache pkg 2023-09-01 17:01:59 +08:00
qwqcode 3af4482db6 refactor(cache): refactor cache pkg 2023-09-01 17:01:59 +08:00
qwqcode c9f8e9b824 chore: modify pkged type to fs.FS 2023-09-01 17:01:58 +08:00
qwqcode d9c2813e50 chore: improve the naming of middleware code 2023-09-01 17:01:58 +08:00
qwqcode 84d6f9728e chore: fix test app 2023-09-01 17:01:58 +08:00
qwqcode d1b730113b refactor(cors): refactor cors middleware 2023-09-01 17:01:57 +08:00
qwqcode 731be57e74 refactor(main): refactor main.go 2023-09-01 17:01:57 +08:00
qwqcode 9f7fb9dad2 refactor(server/middleware): refactor server/middleware pkg 2023-09-01 17:01:57 +08:00
qwqcode 9f81879713 refactor(server/handler): refactor server/handler pkg 2023-09-01 17:01:57 +08:00
qwqcode ff8527f007 refactor(server/common): refactor server/common pkg 2023-09-01 17:01:56 +08:00
qwqcode 2e07d2a2ca refactor(limiter): add limiter pkg 2023-09-01 17:01:56 +08:00
qwqcode 8f5a84969b refactor(ip_region): refactor ip_region pkg 2023-09-01 17:01:56 +08:00
qwqcode 1e76a4d99f refactor(email): refactor email pkg 2023-09-01 17:01:55 +08:00
qwqcode 840621a6b1 refactor(cloud): refactor cloud pkg 2023-09-01 17:01:55 +08:00
qwqcode 24485f9615 refactor(captcha): refactor captcha pkg 2023-09-01 17:01:55 +08:00
qwqcode d4f0ae8ad7 feat(simple_cache): a simple thread-safe cache with sync.Map 2023-09-01 17:01:55 +08:00
qwqcode a06928378a refactor(cache): refactor cache pkg 2023-09-01 17:01:54 +08:00
qwqcode bf93ca78c8 refactor(artransfer): refactor artransfer pkg 2023-09-01 17:01:54 +08:00
qwqcode 75180877b1 refactor(anti_spam): refactor anti_spam pkg 2023-09-01 17:01:54 +08:00
qwqcode fb4aaf7ecb refactor(cmd): refactor cmd pkg 2023-09-01 17:01:53 +08:00
qwqcode d58355209a refactor(notify): add notify_pusher pkg 2023-09-01 17:01:53 +08:00
qwqcode 8488b7e18b refactor(i18n): refactor i18n pkg 2023-09-01 17:01:53 +08:00
qwqcode e7aced94dd feat(hook): add hook pkg 2023-09-01 17:01:53 +08:00
qwqcode 3dd93c33b3 feat(utils): add common random utils 2023-09-01 17:01:52 +08:00
qwqcode bd613a3304 refactor(config): refactor config pkg 2023-09-01 17:01:52 +08:00
qwqcode 7028dcd905 refactor(log): create common log pkg 2023-09-01 17:01:52 +08:00
qwqcode 9ef063cf98 refactor(db): refactor db pkg 2023-09-01 17:01:52 +08:00
qwqcode bf13e1cdba refactor(test): create common test pkg 2023-09-01 17:01:51 +08:00
qwqcode 79f5f53886 refactor(dao): refactor dao pkg 2023-09-01 17:01:51 +08:00
qwqcode 4c951d7e44 refactor(core): refactor core pkg 2023-09-01 17:01:51 +08:00
qwqcode b034e514a7 refactor(cache): remove cached fields in struct to save memory (#555) 2023-08-23 18:06:03 +08:00
qwqcode b88a26dcae fix(log): add missing log for web server listen func (#556) 2023-08-23 10:48:21 +08:00
qwqcode ee30ba4fc8 chore(CI): increase dependabot open-pull-requests-limit 2023-08-22 17:52:17 +08:00
qwqcode a02b89ba3e chore(CI): add dependabot updates for docs 2023-08-22 17:48:17 +08:00
dependabot[bot] 2ca3ab8274 chore(deps/ui): bump the prod-deps group in /ui with 1 update (#552)
Bumps the prod-deps group in /ui with 1 update: [katex](https://github.com/KaTeX/KaTeX).

- [Release notes](https://github.com/KaTeX/KaTeX/releases)
- [Changelog](https://github.com/KaTeX/KaTeX/blob/main/CHANGELOG.md)
- [Commits](https://github.com/KaTeX/KaTeX/compare/v0.16.4...v0.16.8)

---
updated-dependencies:
- dependency-name: katex
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-22 17:45:36 +08:00
dependabot[bot] cbf0210131 chore(deps/ui): bump the dev-deps group in /ui with 5 updates (#553)
Bumps the dev-deps group in /ui with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `20.5.1` | `20.5.2` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `6.4.0` | `6.4.1` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `6.4.0` | `6.4.1` |
| [rollup](https://github.com/rollup/rollup) | `3.28.0` | `3.28.1` |
| [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue/tree/HEAD/packages/plugin-vue) | `4.3.1` | `4.3.3` |


Updates `@types/node` from 20.5.1 to 20.5.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@typescript-eslint/eslint-plugin` from 6.4.0 to 6.4.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.4.1/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 6.4.0 to 6.4.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.4.1/packages/parser)

Updates `rollup` from 3.28.0 to 3.28.1
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v3.28.0...v3.28.1)

Updates `@vitejs/plugin-vue` from 4.3.1 to 4.3.3
- [Release notes](https://github.com/vitejs/vite-plugin-vue/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-vue/commits/plugin-vue@4.3.3/packages/plugin-vue)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: rollup
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: "@vitejs/plugin-vue"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-22 17:45:18 +08:00
qwqcode d8d9420616 chore(CI): dependabot use groups 2023-08-22 17:40:39 +08:00
qwqcode 891f792fe4 chore(CI): modify dependabot.yml prefix config 2023-08-22 17:07:46 +08:00
qwqcode d538e47917 chore(CI): fix dependabot.yml 2023-08-22 16:50:14 +08:00
qwqcode 6c7ce98522 refactor(CI): replace renovate with github dependabot (#546) 2023-08-22 16:49:03 +08:00
qwqcode 1e839548a4 refactor(CI): replace using docker/metadata-action for the docker push (#545) 2023-08-22 16:18:20 +08:00
qwqcode 4ea45ae375 chore(ci): upgrade deps in ci 2023-08-22 12:22:50 +08:00
qwqcode 91f89c6b7d chore(deps): update deps in docs 2023-08-22 12:11:20 +08:00
qwqcode 0ac70a5a43 chore(deps): upgrade frontend deps 2023-08-22 12:00:09 +08:00
qwqcode 9ac354cb23 chore(conf): fix default gravatar mirror url for english env in conf 2023-08-21 12:16:13 +08:00
qwqcode 40e6fcd966 feat(go): upgrade golang to v1.21.0 and some deps (#543)
* Upgrade to Golang v1.21.0 and alpine v3.18
2023-08-20 20:11:10 +08:00
WayJam So 7e476ded1c docs(extras): add deploy guide for fly.io (#520) 2023-06-05 19:08:07 +08:00
github-actions[bot] a885c0a179 chore: release v2.5.5 2023-05-11 12:10:33 +00:00
qwqcode 08c0b297e5 feat(gravatar): add gravatar.params config option (#508)
* feat(gravatar): add `gravatar.params` config option

BREAKING CHANGE: The `gravatar.default` config option has been removed. Please use `gravatar.params` instead. The default value for `gravatar.params` is now `"d=mp&s=240"`.

Signed-off-by: qwqcode <qwqcode@gmail.com>

* add docs and fix sidebar

Signed-off-by: qwqcode <qwqcode@gmail.com>

---------

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-05-10 13:42:04 +08:00
qwqcode 01ed04c791 fix(editor): prevent editor reset on comment failure (#507)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-05-10 11:40:09 +08:00
qwqcode 0135a83b49 chore(deps): upgrade frontend deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-05-10 11:22:12 +08:00
qwqcode b9c177bb54 feat(go): upgrade golang to v1.20.4 and some deps (#506) 2023-05-09 11:06:03 +08:00
qwqcode 00ce23bc99 chore(deps): update some deps in docs 2023-05-09 10:56:24 +08:00
qwqcode 4853b6cc5d chore(build): bump pnpm to v8.4.0 2023-05-09 10:45:42 +08:00
qwqcode 79dea425ea feat(build): add embedded fe lite and i18n scripts (#493) (#505) 2023-05-09 10:41:28 +08:00
qwqcode c20faed4e3 fix(api): comment IP data loss after editing (#504)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-05-07 18:55:15 +08:00
qwqcode e9acd28126 chore: update renovate.json
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-04-09 20:51:54 +08:00
github-actions[bot] b71b22f5a7 chore: release v2.5.4 2023-04-09 12:34:32 +00:00
qwqcode bc7d0e09b8 chore(deps): upgrade frontend deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-04-09 20:14:43 +08:00
qwqcode f682ade2c9 docs: update swagger docs and some deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-04-09 20:07:18 +08:00
qwqcode 2b990ff433 feat(go): upgrade golang to v1.20.3 and some deps (#485)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-04-09 20:06:00 +08:00
qwqcode 6d21c2b074 fix(CI): upgrade and pin node.js and pnpm version (#484)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-04-09 19:46:52 +08:00
github-actions[bot] 3840720620 chore: release v2.5.3 2023-04-06 13:08:21 +00:00
qwqcode 7dd8668b6e perf(ip_region): add db file existence check and error message (#482)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-04-06 21:05:37 +08:00
qwqcode ac4b8b0b80 fix(api/comment_add): SIGSEGV crash in comment_add (#478) (#481)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-04-06 20:46:27 +08:00
github-actions[bot] febe890ecb chore: release v2.5.2 2023-03-19 11:49:07 +00:00
qwqcode 1be2ad4d6e perf(style): add !important for white-space css in code block (#467)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-19 19:47:15 +08:00
qwqcode 848969edbc perf(notify): shorten the length of notify key (#466)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-19 19:43:20 +08:00
qwqcode f0d93ad736 fix(ui): destroy instance when calling init func twice
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-17 15:54:08 +08:00
qwqcode 9fb17d0483 chore(typo): fix filename typo
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-17 09:13:53 +08:00
github-actions[bot] 63a637a50e chore: release v2.5.1 2023-03-16 13:52:56 +00:00
qwqcode 54487d999c chore(ci): fix git-chglog config
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-16 21:51:27 +08:00
qwqcode 6916c5a4d5 feat(go): upgrade golang to v1.20.2
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-16 21:14:29 +08:00
qwqcode 00d765b563 chore(deps): upgrade frontend deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-16 21:08:48 +08:00
qwqcode cb4985dc0b chore(deps): upgrade go app deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-16 21:02:40 +08:00
qwqcode 2b7d69e364 chore(ci): fix release.yml git command
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-16 20:58:27 +08:00
qwqcode 5075698f4a fix(ui/count-widget): context api undefined issue (#464)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-16 20:50:42 +08:00
qwqcode 4c6fbeffb7 fix(ui/paginator): showErr func call issue
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-16 20:37:26 +08:00
qwqcode 262dd4123d refactor(ui/user): modify user to standalone module (#463)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-16 19:23:10 +08:00
qwqcode 3ccc25e08b chore(chglog): set title_order config
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-16 11:32:02 +08:00
qwqcode 65ab1bab79 fix(ui/i18n): duplicate packaging built-in language in the external script
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-15 21:52:20 +08:00
qwqcode 4f5f3b9f7c chore(ci/build): checkout latest tag
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-15 21:20:58 +08:00
qwqcode fe4dfb2a1c fix(ui/sort-dropdown): dropdown menu disappears after call reload func (#461)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-15 21:00:39 +08:00
qwqcode b71fe13787 refactor(anti_spam/aliyun): accessing aliyun green text api without sdk (#459)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-14 23:12:12 +08:00
qwqcode 340ab407da chore(docs): update artalk latest version in docs
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 23:15:51 +08:00
qwqcode a00d96e227 chore(ci): add manually repo dispatch
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 22:01:10 +08:00
qwqcode b3d2cc0196 fix(ci): frontend and app build
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 21:53:46 +08:00
github-actions[bot] 710fbcbff5 chore: release v2.5.0 2023-03-10 13:25:05 +00:00
qwqcode 2d04b485ae feat(i18n): add zh-TW i18n translation for sidebar and app
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 21:05:41 +08:00
qwqcode ce81d90e3a docs: init artalk with new frontend api
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 20:58:15 +08:00
qwqcode 18b806eb2a fix: destroy method remove root element
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 20:30:18 +08:00
qwqcode b898a4ca96 chore(docs): fix docs dead link
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 20:27:00 +08:00
qwqcode 069a33773c docs: refine and add frontend api docs
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 20:17:41 +08:00
qwqcode b40c0db7a0 feat(ui): add some static methods
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 20:16:18 +08:00
qwqcode 7efddf713a style: improve some styles
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 18:37:39 +08:00
qwqcode a9982b18ad fix(ui/i18n): subscribe event priority issue
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 15:12:53 +08:00
qwqcode 835f41bc3a feat(captcha): add support for reCAPTCHA and hCaptcha (#456)
* feat(captcha): add support for reCAPTCHA and hCaptcha

Signed-off-by: qwqcode <qwqcode@gmail.com>

* refine docs

Signed-off-by: qwqcode <qwqcode@gmail.com>

---------

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 13:06:23 +08:00
qwqcode 82a57051fe fix(ui/sidebar): setting item save follow type of template
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 12:54:41 +08:00
qwqcode b54ed8115a refactor(captcha): abstract captcha service (#455)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-10 10:39:05 +08:00
qwqcode 481a2ffe2d fix(comment_add): ip region search in comment add api
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 23:29:26 +08:00
qwqcode 4ca7a1622e fix: add X-Forwarded-For proxy header read
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 23:09:54 +08:00
qwqcode 3f90ae73c7 docs: add simplified README for artalk npm package
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 22:46:01 +08:00
qwqcode 45e423dc09 fix: timeAgo appears negative number minutes ago
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 22:20:54 +08:00
qwqcode efe60c23ce perf(docker-build): cache by separating the downloading of deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 22:10:48 +08:00
qwqcode 434a5e41a9 chore: modify comment hash handle
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 21:35:29 +08:00
qwqcode 2dd6933862 fix: timeAgo function does not display the now
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 20:57:50 +08:00
qwqcode cbd3ffd3a5 feat: add graceful shutdown
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 20:57:10 +08:00
qwqcode 1efd35a796 fix(site_origin): issue of same-origin request under the proxy (#454)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 19:35:42 +08:00
qwqcode c8f9a08bfc feat(captcha): support turnstile captcha by cloudflare (#453)
* feat(captcha): support turnstile captcha by cloudflare

Signed-off-by: qwqcode <qwqcode@gmail.com>

* docs: add turnstile captcha

Signed-off-by: qwqcode <qwqcode@gmail.com>

---------

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 17:17:54 +08:00
qwqcode 073e64d7f9 refactor: remove version two-way check (#452)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 14:42:24 +08:00
qwqcode 6c72d31edc fix(ui/editor): disable img upload cannot hide its btn
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 14:13:31 +08:00
qwqcode 8d68717ccc perf(ui/list): remove useless function call
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 14:07:50 +08:00
qwqcode 9f7dd15bf8 perf(ui/sidebar): improve sidebar i18n
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-09 13:41:28 +08:00
qwqcode c561db7997 chore(docs): modify artalk script link
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-08 20:38:44 +08:00
qwqcode 9e72c74a8d chore(docs): upgrade and fix css
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-08 11:45:36 +08:00
qwqcode e8b360efc6 fix(ui/sidebar): array type of preference initial data issue
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-08 11:31:57 +08:00
qwqcode 4679125bb7 chore(ip_region): move config dep out of ip_region pkg
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-08 11:20:46 +08:00
qwqcode 37f68f1604 feat(ui/height_limit): support scrollable height limit area (#451)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-08 11:17:54 +08:00
qwqcode acd76b9d6b chore(deps): upgrade deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-07 11:56:17 +08:00
qwqcode 61b744971a feat(ui/sidebar): add dark mode support (#450)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-07 11:45:43 +08:00
qwqcode 155a7f9305 fix(ui/conf): avoid some conf overrides frontend from the backend (#449)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-07 09:49:06 +08:00
Kindle deepandqwqcode a677443a7c chore(docs): refine import-blog.md hugo case (#413)
* Update import-blog.md

* Update import-blog.md

* Update import-blog.md

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
2023-03-06 22:10:29 +08:00
qwqcode fccebf853e feat: display IP region of comment (#418) (#447)
* ip_region backend api

Signed-off-by: qwqcode <qwqcode@gmail.com>

* frontend ui support

Signed-off-by: qwqcode <qwqcode@gmail.com>

* fix backend

Signed-off-by: qwqcode <qwqcode@gmail.com>

* handle mutiple ip case

Signed-off-by: qwqcode <qwqcode@gmail.com>

* add docs

Signed-off-by: qwqcode <qwqcode@gmail.com>

---------

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-06 21:54:03 +08:00
qwqcode 6ebaf6750b fix(ui/sidebar): boolean type setting option save issue (#431) (#444)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-05 15:00:27 +08:00
qwqcode 00c332e225 fix(ui): hash goto function check condition issue
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-04 22:24:08 +08:00
qwqcode b0ba677938 perf(conf/i18n): detect and change locale when config file contains chinese
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-04 22:01:22 +08:00
qwqcode 1de22bbc0b feat: upgrade go to v1.20.1
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-04 20:33:49 +08:00
qwqcode beee4bd35d refactor(ui/editor): change functions of editor to standalone modules (#443) 2023-03-04 17:55:15 +08:00
qwqcode 74f5e3b1c2 refactor(page/fetch): remove goquery dependency when extracting page data (#442)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-03 19:59:29 +08:00
qwqcode ed70775697 chore(build): fix dts compile issue
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-03 17:55:42 +08:00
qwqcode 711f66e4f5 refactor(ui/editor): modify editor ui to standalone module (#441)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-03 13:11:55 +08:00
qwqcode 70a791cba9 fix(lint): add tsc check before vite compile (#440)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-03 13:09:22 +08:00
qwqcode 65d62fee5e refactor(style): convert to use Sass as a style interpreter (#439)
* chore: rename all less files to scss

Signed-off-by: qwqcode <qwqcode@gmail.com>

* refactor(style): convert to use Sass as a style interpreter

Signed-off-by: qwqcode <qwqcode@gmail.com>

---------

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-02 12:22:56 +08:00
qwqcode 9684278160 chore(deps/go): upgrade deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-02 11:48:23 +08:00
qwqcode 68008d67f7 chore(deps/docs): upgrade deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-02 11:38:28 +08:00
qwqcode aef5bbc142 refactor(anti_spam/qcloud-tms): implement qcloud tms api without sdk (#438)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-03-01 11:33:55 +08:00
qwqcode 77223c9fd7 refactor(ui/list): modify list pagination to standalone module (#437)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-28 19:25:51 +08:00
二丫讲梵 25acedd3ee docs(extras): add deploy guide for vuepress (#436) 2023-02-28 19:09:48 +08:00
qwqcode 8b93feb50e refactor(ui/height-limit): modify height limit function to standalone module (#435)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-28 13:45:26 +08:00
qwqcode d353c9f4ae refactor(ui/i18n): improve i18n function to standalone module (#434)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-28 13:40:29 +08:00
qwqcode f3a0ef6de8 refactor(ui/dark-mode): separate dark mode logic into its own module (#430) 2023-02-24 22:29:18 +08:00
qwqcode e2944f383f refactor(ui): automatic dependency injection (#429)
* refactor(ui): automatic dependency injection

Signed-off-by: qwqcode <qwqcode@gmail.com>

* feat: provide `inject` function allows to inject dep

Signed-off-by: qwqcode <qwqcode@gmail.com>

---------

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-24 22:18:14 +08:00
qwqcode 0103a939d2 refactor(ui/checker): simplify checker lifecycle function param table (#428)
* chore(ui): rename checker file name

Signed-off-by: qwqcode <qwqcode@gmail.com>

* refactor(ui/checker): simplify checker lifecycle function param table

Signed-off-by: qwqcode <qwqcode@gmail.com>

---------

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-24 21:42:21 +08:00
dependabot[bot] 34b82cfa2e chore(deps): bump golang.org/x/image from 0.3.0 to 0.5.0 (#419)
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.3.0 to 0.5.0.
- [Release notes](https://github.com/golang/image/releases)
- [Commits](https://github.com/golang/image/compare/v0.3.0...v0.5.0)

---
updated-dependencies:
- dependency-name: golang.org/x/image
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-24 19:11:59 +08:00
qwqcode 8c7ed30bcd refactor(comment): seperate comment ui renders from single file (#427)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-22 11:51:17 +08:00
dependabot[bot] 4872ea1bb5 chore(deps): bump golang.org/x/net from 0.5.0 to 0.7.0 (#420)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.5.0 to 0.7.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.5.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-22 11:42:19 +08:00
Baoshuo Renandqwqcode d57b747991 docs(deploy): add restart=always for docker to auto restart (#425)
* fix: 为 docker 容器指定 restart=always 使得容器可以自动重启

* Update deploy.md

---------

Co-authored-by: qwqcode <qwqcode@gmail.com>
2023-02-22 11:40:18 +08:00
qwqcode cc1ee6f999 feat: more functions to handle artalk lifecycle (#426)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-22 11:33:33 +08:00
qwqcode 5d85d83ce1 chore(deps): update dependencies
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-17 13:24:05 +08:00
qwqcode 0d2fa86c03 chore(docs): add FUNDING.yml
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-06 00:04:40 +08:00
qwqcode 9e26b22058 chore(docs): revise some docs
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-05 23:25:11 +08:00
qwqcode d411763118 fix(email): failback to email.mail_tpl if admin_notify.email.mail_tpl is empty
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-05 23:24:27 +08:00
qwqcode 3b99a588f7 chore: replace deprecated io/ioutil with new
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 20:55:01 +08:00
qwqcode fa3239e566 chore(deps): upgrade frontend deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 20:46:25 +08:00
qwqcode b52ba30794 fix(sidebar): array type config option cannot be shown
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 20:05:52 +08:00
qwqcode 7cd4dc562a chore(deps): upgrade frontend deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 20:02:31 +08:00
qwqcode 307d935619 chore(i18n): fix comment list counter with i18n
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 19:44:25 +08:00
qwqcode 3060ad8d3a chore(deps): upgrade go deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 19:28:25 +08:00
qwqcode 9d0591c617 chore(docs): add i18n support
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 19:25:05 +08:00
renovate[bot] b7520c88c1 chore(deps): update dependency vitepress to v1.0.0-alpha.45 (#356)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-04 18:23:56 +08:00
qwqcode e447657c94 docs: fix content and update index 2023-02-04 18:13:41 +08:00
qwqcode 1955179da4 fix(email): duplicate sending with multiple admins using same email addrs (#375)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 13:27:33 +08:00
qwqcode 151b52fb37 fix(email): email queue initialization issue (#374)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 13:17:22 +08:00
qwqcode 55ed0a641a chore(conf): update example config file
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-02-04 13:09:21 +08:00
Mr.Hope a67632a48a docs: fix wrong config value (#371)
* Update fe-control.md

* Update fe-control.md
2023-02-03 13:36:21 +08:00
Mr.Hope 0b7b6ca623 docs: fix broken links (#364) 2023-02-02 16:06:59 +08:00
Monst.x d85fc4a71f fix: sidebar navigation sorting (#361) 2023-01-29 19:50:29 +08:00
qwqcode 9a680f0ef8 docs: add open api (#360)
* chore(api): add comment for open api

Signed-off-by: qwqcode <qwqcode@gmail.com>

* docs: add open api generation support

Signed-off-by: qwqcode <qwqcode@gmail.com>

---------

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-29 00:13:19 +08:00
qwqcode ee6bcd8577 chore(docs): improve docs-cn ci workflow
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-27 16:01:19 +08:00
qwqcode e6ac313875 chore(docs): fix vitepress build issue
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-26 21:08:34 +08:00
qwqcode 34e59e653f refactor(CI): improve build and release workflows (#358)
* refactor(CI): build and publish workflows

Signed-off-by: qwqcode <qwqcode@gmail.com>

* fix(docs): version in cdn link output issue

Signed-off-by: qwqcode <qwqcode@gmail.com>

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-26 20:07:55 +08:00
qwqcode 2eaf3e814a chore(deps): upgrade vitepress for docs
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-23 17:20:46 +08:00
pluveto 958d390efb docs: add Project Structure section to CONTRIBUTING.md 2023-01-23 03:30:39 +00:00
qwqcode 7de6c27bd8 feat(i18n): add i18n support for sidebar (#353)
* docs: revise config example template

Signed-off-by: qwqcode <qwqcode@gmail.com>

* feat: add i18n for sidebar

Signed-off-by: qwqcode <qwqcode@gmail.com>

* feat: i18n for backend config in sidebar

Signed-off-by: qwqcode <qwqcode@gmail.com>

* feat(i18n): link FE and BE locale conf

Signed-off-by: qwqcode <qwqcode@gmail.com>

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-21 22:53:34 +08:00
qwqcode 7e01f9d0ed chore: revert the rename of image on dockerhub (#351)
Signed-off-by: qwqcode <qwqcode@gmail.com>

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-20 13:28:14 +08:00
qwqcode cd9b9f48f7 chore: remove github dependabot
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-19 21:38:52 +08:00
qwqcode d52b2f5228 Merge pull request #345 from ArtalkJS/refactor/bump-to-monorepo
fefactor: bump to monorepo
2023-01-19 21:11:01 +08:00
qwqcode 1ca892fc2d feat(i18n): translations for backend (#344)
* i18n: add i18n for server pacakge

Signed-off-by: qwqcode <qwqcode@gmail.com>

* i18n: add i18n for cmd pacakge

Signed-off-by: qwqcode <qwqcode@gmail.com>

* feat: add mustache syntax support for i18n.T in backend

Signed-off-by: qwqcode <qwqcode@gmail.com>

* i18n: improve i18n for backend further

Signed-off-by: qwqcode <qwqcode@gmail.com>

* i18n: `zh-CN` translation for backend

Signed-off-by: qwqcode <qwqcode@gmail.com>

Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-19 20:17:32 +08:00
pluveto 891246a672 docs: add translation section to CONTRIBUTING.md 2023-01-19 02:17:29 +00:00
qwqcode bfceff6446 feat(i18n): add i18n support for backend (#343)
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-18 21:18:05 +08:00
pluveto 0f8d3f935a refactor(scripts): double quote to prevent globbing and word splitting 2023-01-18 12:30:00 +00:00
pluveto e1c1b33232 feat: launch with vscode debugger 2023-01-18 12:05:45 +00:00
pluveto 1419c3231e chore(makefile): add debug-build target 2023-01-18 12:05:16 +00:00
pluveto 5c06c1cd88 docs: update CONTRIBUTING.md make debug-build 2023-01-18 12:04:27 +00:00
qwqcode 90ebd719a0 docs: add CODE_OF_CONDUCT.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 21:25:51 +08:00
qwqcode 6c896b34aa chore: rename dockerhub.yml to docker.yml
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 20:54:10 +08:00
qwqcode 5b73049ac4 feat: docker ci add support for building arm64 wheels
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 20:50:31 +08:00
qwqcode 342f3d3ad8 chore: merge .gitignore and clean up
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 20:25:49 +08:00
qwqcode f89f87d92f fix: docker image build script
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 20:24:45 +08:00
qwqcode e4ffc0bcd1 fix: add .npmignore to fix NPM publish inclusion issue
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 19:58:39 +08:00
qwqcode 664a9e07ad chore: rename artalk.example_zh-CN.yml to artalk.example.zh-CN.yml
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 19:35:13 +08:00
qwqcode 593639f92e chore: move files from docs/docs to docs
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 19:34:59 +08:00
pluveto 61da5eb6ef docs: update setup-example-site.sh script usage 2023-01-17 09:15:09 +00:00
pluveto f210f154c3 feat: one-key site creating with artalk integrated 2023-01-17 09:10:58 +00:00
pluveto 15e472aede fix: missing trusted_domains field 2023-01-17 09:10:58 +00:00
qwqcode 1b7766ca87 fix: config alias and Dockerfile
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 16:37:39 +08:00
pluveto c7e2c8d3fd docs: example in zh-CN 2023-01-17 07:34:54 +00:00
pluveto 9441131f07 chore: example file in English 2023-01-17 07:34:02 +00:00
pluveto 697ed7282a refactor: batch removing artalk -go postfix 2023-01-17 05:37:45 +00:00
pluveto ac26e67436 fix: frontend repository directory issue 2023-01-17 05:34:16 +00:00
pluveto d9cc493b71 docs: migrate ArtalkJS/Docs to monorepo docs 2023-01-17 05:33:59 +00:00
pluveto 8d4219af87 refactor: renamed from artalk-go to artalk 2023-01-17 05:22:09 +00:00
qwqcode d229a628ba refactor: build scripts and CI tests
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-17 00:16:04 +08:00
qwqcode 802749fc94 chore: rename dir frontend to public
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-16 21:55:13 +08:00
pluveto 4f046f8d0e refactor: move from tmp dir to root 2023-01-16 21:34:24 +08:00
pluveto 8da91b3b25 fix: naming conflict of node circleci 2023-01-16 09:41:44 +00:00
pluveto 6a4195098b refactor: merge ci workflows 2023-01-16 09:33:03 +00:00
pluveto 15b15a7fd3 refactor: merge backend to monorepo branch 2023-01-16 09:30:00 +00:00
pluveto 038a1c52a0 chore: move all to tmp dir 2023-01-16 09:28:24 +00:00
qwqcode d0bb5b7824 Merge pull request #55 from ArtalkJS/feat/admin_email_tpl
feat(conf): add conf option for specific email tpl for admins
2023-01-05 17:34:58 +08:00
qwqcode 8f58754a0e feat(conf): add conf option for specific email tpl for admins
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-05 17:15:46 +08:00
qwqcode 91ae48c852 fix(api/get): fix concurrent map writes error
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-05 16:26:53 +08:00
qwqcode f0d792119c Merge pull request #54 from ArtalkJS/fiber
refactor: migrate from echo to go-fiber
2023-01-04 21:02:14 +08:00
qwqcode 389be3c9f2 refactor: migrate from echo to go-fiber
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-04 20:50:49 +08:00
qwqcode 0b37cfd332 chore: create dependabot.yml 2023-01-02 23:13:53 +08:00
qwqcode 2f20159382 feat(go): upgrade to Go 1.19 and update some deps
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-02 22:43:56 +08:00
qwqcode 11cd3276d2 Merge pull request #53 from ArtalkJS/refactor
refactor: 20230101
2023-01-02 13:45:18 +08:00
qwqcode d2d0015cf3 chore: update .gitignore
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-02 13:44:16 +08:00
qwqcode 205572773c refactor: replace pkger with go:embed
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-02 13:33:44 +08:00
qwqcode 938bd18522 refactor: project package structure
Signed-off-by: qwqcode <qwqcode@gmail.com>
2023-01-02 00:01:59 +08:00
qwqcode 0978293cb1 chore(CI): fix circleci cache
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-12-20 16:43:06 +08:00
AHdarkandqwqcode 6b40ee6f87 refactor: abstract email service
* Chore: no stage for the .idea directory

* Chore: abstract email service

* Chore: abstract email service

* Chore: initialize the channel in the function

* CI: Updated the Image version used by Circle CI to 1.18 to match `go.mod`

* Update config.yml

Co-authored-by: qwqcode <qwqcode@gmail.com>
2022-12-20 16:34:21 +08:00
qwqcode 3d1cbae163 fix(api/comment_get): use frontend pageSize config
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-31 12:24:35 +08:00
qwqcode 0cab1ccabe fix: crash when frontend config is not set
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-30 00:15:50 +08:00
qwqcode fcf4849c4b chore: upgrade FeMinVersion to v2.4.3
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-29 17:31:05 +08:00
qwqcode 59a47ba9d5 fix: add whitelist for origin checker
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-29 16:31:40 +08:00
qwqcode 4494e53e9b refactor: http origin checker
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-29 15:51:29 +08:00
qwqcode 1c095c339f perf(conf): only provide conf for frontend when fetching the first page
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-26 20:38:45 +08:00
qwqcode ac87f46b3a feat(cmd): add admin command to create new user
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-23 14:38:23 +08:00
qwqcode 13e2bab3dd feat(conf): auto-gen config file when initializing the app
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-23 13:53:00 +08:00
qwqcode 02bd2a3ac2 chore(api/admin): enhance user management api
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-22 13:33:32 +08:00
qwqcode 8c95417359 fix(artransfer): incorrect IsPinned reference to IsPending (#49)
Signed-off-by: qwqcode <qwqcode@gmail.com>

Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-19 09:38:06 +08:00
qwqcode f85c200cf0 feat(api/comment): add search for comment list api
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-18 15:23:36 +08:00
qwqcode 97898c584d feat(api/admin): add user management api for admin
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-18 14:10:08 +08:00
qwqcode cd14cac17c chore(deps): upgrade echo to v4.9.1
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-18 11:26:39 +08:00
dependabot[bot] 7897407ec9 chore(deps): bump github.com/labstack/echo/v4 from 4.5.0 to 4.9.0 (#48)
Bumps [github.com/labstack/echo/v4](https://github.com/labstack/echo) from 4.5.0 to 4.9.0.
- [Release notes](https://github.com/labstack/echo/releases)
- [Changelog](https://github.com/labstack/echo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/labstack/echo/compare/v4.5.0...v4.9.0)

---
updated-dependencies:
- dependency-name: github.com/labstack/echo/v4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-18 11:22:08 +08:00
qwqcode 05394876d5 feat(email-tpl): add ip variable to email template
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-18 11:21:14 +08:00
qwqcode ddec9d2adf chore(ci): set up CodeQL CI 2022-10-14 21:19:26 +08:00
qwqcode 0fe312143a fix(config): replace viper with koanf to make map case sensitivity (#47)
Signed-off-by: qwqcode <qwqcode@gmail.com>

Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-14 20:19:59 +08:00
qwqcode 6fe8375446 feat: root path redict to sidebar login page
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-14 16:35:09 +08:00
qwqcode 9e01dc2067 feat(api/login): support choose user when multi usernames use the same email
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-13 19:24:40 +08:00
qwqcode eb58cac600 fix: replace gravatar default mirror
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-10-09 16:24:49 +08:00
qwqcode 326d9b3d8f chore(version): upgrade FeMinVersion to 2.4.1
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-09-26 22:07:41 +08:00
qwqcode 171c17e255 fix(importer): UrlResolver disabled by default
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-09-26 14:17:37 +08:00
qwqcode a694ee8e45 feat(api): settings get & save
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-09-26 14:02:41 +08:00
qwqcode ff96cd9702 fix(api): Modify to only api subpath enable SiteOrigin checker
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-18 23:14:46 +08:00
qwqcode dfba394a88 chore: Upgrade FeMinVersion to v2.3.4
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-17 18:53:05 +08:00
qwqcode 1f5494e524 refactor(api): Modify admin_comment_edit user merge logic
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-17 12:14:53 +08:00
KevinZønda de7c2c213d chore(docs): Fix link (#39) 2022-06-16 10:21:18 +08:00
qwqcode 8329bee93c feat: Global site & origin checker & support cookie
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-15 18:28:26 +08:00
qwqcode 0b9f364448 chore(pkg-manager): Upgrade pnpm to 7.2.1
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-15 13:47:37 +08:00
qwqcode af132d0e98 chore: Remove some unused GET method API
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-08 21:27:27 +08:00
qwqcode 4e2f78e37d perf(trusted_domains): Improve origin checker
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-08 21:23:11 +08:00
qwqcode 60ed699672 fix(docker): Entrypoint script gen command
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-07 17:36:33 +08:00
qwqcode a244286d65 fix(trusted_domains): Disable CORS restrictions
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-07 16:45:46 +08:00
qwqcode 7d9f15ab76 fix(dockerfile): Expose host for external device
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-07 11:30:38 +08:00
qwqcode 346595f0cf refactor(docker): Use a folder to place config instead of mounting a single file
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-07 02:13:20 +08:00
qwqcode 7dee18c5c7 feat(gen): Gen cmd support overwrite file
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-06 23:55:10 +08:00
qwqcode 546ebee48e fix(docker): Docker-compose file add build option
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-06 23:16:49 +08:00
qwqcode bac1271a96 fix(trusted_domains): Extract from full URL with slash suffix & improve referer interceptor
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-06 21:48:20 +08:00
qwqcode 1666681872 feat(comment): Add field content_marked to render the markdown content
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-06 17:13:09 +08:00
qwqcode 0f87730f2e fix(api/stat): Different RAND expressions for SQLite
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-06 16:53:03 +08:00
qwqcode fc69bf7180 fix(time): Embed IANA timezone database in Windows build
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-06-06 16:43:59 +08:00
qwqcode ed547206e6 feat(notify): Support WebHook notify
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-23 17:01:51 +08:00
qwqcode 27b6fcde97 fix(notify): Remove atk-emoticon img tags
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-23 16:11:06 +08:00
qwqcode d5b67a26d5 feat(notify): Support template & fix some bugs
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-23 15:27:49 +08:00
qwqcode 2af6e3e213 feat(conf): Support for admin_notify.noise_mode option
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-23 10:34:35 +08:00
qwqcode dbc8e268bc chore(conf): Prevent deprecated options from unmarshall in JSON
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-23 00:50:59 +08:00
qwqcode 5334763d76 feat(conf): Support for admin_notify.email.enabled option
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-23 00:46:43 +08:00
qwqcode 924a080d94 refactor(conf): Rename notify to admin_notify & admin_notify.email option
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-22 23:38:27 +08:00
qwqcode 37112f90b7 chore(conf): Update FrontendConf
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-22 22:29:56 +08:00
qwqcode e04f2eb420 fix(utils): func SplitAndTrimSpace remove blank items by default
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-22 22:19:36 +08:00
qwqcode 067730cef0 feat(api/stat): Support 'rand_comments' and 'rand_pages' types & fix some bugs
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-22 22:13:14 +08:00
qwqcode d9c4cf9e5f fix(api/stat): Add limit for comment_most_pages sql
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-22 21:29:28 +08:00
qwqcode 9659460836 Merge pull request #31 from ArtalkJS/pending-email-send
Resend email when comment is_pending status is modified
2022-05-22 19:50:09 +08:00
qwqcode 94c789b867 fix(comment_edit): Resend email when comment is_pending status is modified
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-22 19:47:25 +08:00
qwqcode 99b7dc80d3 fix(comment_add): PendingDefault ignore Admin user
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-22 19:29:10 +08:00
qwqcode d32f42feb7 chore: Remove achieved TODO
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-22 19:21:32 +08:00
qwqcode c478608b1b fix(cache): Duplicate display reply comments when pid cache is deleted
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-21 18:12:43 +08:00
qwqcode 8924afdadd fix(api/stat): Query when using default site
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-21 13:47:45 +08:00
qwqcode f39e85744c chore(version): Update FeMinVersion to 2.3.0
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-21 01:18:25 +08:00
qwqcode 89d39ebf54 chore(api/stat): Modify type names
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-20 21:42:32 +08:00
qwqcode 3bba26399a feat(api): New statistic api
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-20 21:23:27 +08:00
qwqcode 8a17ab5025 chore(pkg-manager): Update pnpm to 7.1.2
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-19 21:26:06 +08:00
qwqcode 225f93f0f0 chore(docs): Add CircleCI shield
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-05 21:52:56 +08:00
qwqcode 1f81be4c94 chore(test): Add CircleCI config
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-05 20:26:36 +08:00
qwqcode 2f012d9b0b feat(go): Update golang to v1.18.1
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-05 00:45:28 +08:00
qwqcode f5a5117a71 chore(dockerfile): Update pnpm to 7.0.0
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-04 23:45:49 +08:00
qwqcode f15c84c584 chore(version): Update FeMinVersion to 2.2.12
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-04 23:33:33 +08:00
qwqcode e60c4a6ee9 fix(importer): UrlResolver disabled by default when a TargetSiteUrl is given
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-04 23:22:52 +08:00
qwqcode a16977d49b fix(frontend-conf): Use pointer with omitempty to ignore frontend config output
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-04 22:46:12 +08:00
qwqcode 2cb8e4044c fix(transfer): Importer boot param parse.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-03 21:51:59 +08:00
qwqcode 12bd0b5d91 fix: Prevent unsafe svg image uploads
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-01 20:30:33 +08:00
qwqcode 5d2c0904f6 test(page): GetAccessibleURL method
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-05-01 17:45:48 +08:00
qwqcode 566595e7a7 test(model): Add query_find_create test
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-30 23:23:11 +08:00
qwqcode 9e873fe809 test(model): Add query_del test
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-30 23:06:01 +08:00
qwqcode c55e772fba test(model): Add query_find test
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-30 22:46:28 +08:00
qwqcode 8db752f425 fix(cache): Use SingleFlight to avoid Cache breakdown.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-30 21:37:36 +08:00
qwqcode 19cba53ba5 chore: Move some methods
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-30 13:42:21 +08:00
qwqcode 2e6b99fc21 chore(model): Organize some methods
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-30 13:32:14 +08:00
qwqcode a36f4fb27b test: Add fixtures & set up testing.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-30 00:58:31 +08:00
qwqcode 4de9b00974 chore(makefile): Modify PHONY
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-29 21:49:16 +08:00
qwqcode 8d60195cd8 chore: Rename Makefile file.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-29 20:59:23 +08:00
qwqcode f224a55978 Merge pull request #28 from ArtalkJS/multi-site
Enhance Support for Multiple Sites
2022-04-29 18:03:03 +08:00
qwqcode 9ccf4d48e9 chore(cache): Replace all cache_marshaler global variable to cache.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-29 17:59:10 +08:00
qwqcode a03e98551d refactor(api_get): Comments get api.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-29 17:25:00 +08:00
qwqcode 02b3173084 feat(multi-site): Isolate admin users among sites
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-29 14:11:48 +08:00
qwqcode fcd44bcced refactor(api): Remove unnecessary parameter of ParamsDecode method
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-29 12:07:29 +08:00
qwqcode bb2e68374b chore(rename): Rename code files in http folder
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-29 11:31:13 +08:00
qwqcode 886bbd8e30 chore(multi-site): Preliminary Site Manager Access control
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-28 23:40:17 +08:00
qwqcode 8d7e5ca2e3 fix(cors): Import cors domains from db site urls.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-28 21:15:11 +08:00
qwqcode 03070989ac chore(admin_check): Remove useless AdminOnly method calls in each admin_api.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-28 21:00:57 +08:00
qwqcode 0c64ca0a4f chore(admin_check): Query user from db before check.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-28 20:49:22 +08:00
qwqcode 8f3a1ce92c chore(admin_check): Remove useless jwt middleware
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-28 20:39:34 +08:00
qwqcode 9a8b979dd1 feat(user): Admin email sending isolation between sites.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-28 19:48:23 +08:00
qwqcode 3120b813b9 fix(cache): Type conversion issue in Captcha part when using redis.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-27 13:15:02 +08:00
qwqcode 2ad686433a fix(validator): ValidateURL modify to IsRequestURL
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-26 16:39:14 +08:00
qwqcode d03534f9a6 fix(importer): Fix too many sql variables Err while too much items.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-26 16:00:19 +08:00
qwqcode 3c76f52e69 chore(version): Update FeMinVersion to v2.2.8
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-25 19:05:19 +08:00
qwqcode 231a6b3ef2 feat(upgrade): Upgrade command allow ignore version check.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-25 19:02:31 +08:00
qwqcode 05ad1c4f9c feat(conf): Support control Frontend Conf by Backend.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-25 14:30:58 +08:00
qwqcode fd1be636ab fix(db): Time type field use pointer to solve 0000-00-00 issue.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-24 00:20:21 +08:00
qwqcode 9ca2a80abf feat(db): Allow set table_prefix
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-24 00:09:14 +08:00
qwqcode 11d107e2c4 feat(api_admin_cache): Add api handle cache
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 23:54:34 +08:00
qwqcode 446213b7df fix(conf_admins): Preserve admin user which not in config file.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 23:24:34 +08:00
qwqcode a27b015792 fix(db): Fix query syntax error & importer vote recover.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 23:21:05 +08:00
qwqcode ff03509861 fix(admin_edit): Remove cache before admin_edit.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 22:37:13 +08:00
qwqcode 052974639a feat(conf): Config database options not just dsn.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 22:27:42 +08:00
qwqcode 5a1b36129d fix(db): Support postgres database.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 21:59:36 +08:00
qwqcode 177ca04e02 feat(importer): Speed up importer & fix some bugs.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 21:23:04 +08:00
qwqcode 5cd0129b6c feat(cache): Replace built-in json lib with vmihailenco/msgpack to speed up
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 18:36:27 +08:00
qwqcode 3f1313ae3b fix(cache): ChildCommentCacheSave repeatedly cache while exist
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 17:49:19 +08:00
qwqcode 12ee6ab936 chore(docs): Update README.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 16:38:00 +08:00
qwqcode 72d205f3e9 feat(cache): Support redis & memcache
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 16:28:48 +08:00
qwqcode dcde2b43f1 feat: FindCommentChildren query db while cache miss
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 14:44:05 +08:00
qwqcode 9ab36c65d7 fix: Add lock in ChildCommentCacheSave
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 14:30:32 +08:00
qwqcode 323455c924 fix: Add lock prevent query db repeatedly while cache miss.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 14:03:46 +08:00
qwqcode 0ab5d1f290 fix: Cache add mutex lock
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 13:40:46 +08:00
qwqcode d1986c4f6f feat(cache): Almost full cache coverage.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-23 01:15:42 +08:00
qwqcode 1eff8309ea chore(conf): Update artalk-go.example.yml file.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-22 15:15:36 +08:00
qwqcode 95e387f40f feat(upgit): Config del_local to remove local file after uploaded.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-22 15:13:22 +08:00
qwqcode 264b4649ea Merge pull request #23 from ArtalkJS/refactor
test(model): Find & Create actions.
2022-04-22 15:00:27 +08:00
qwqcode af5e721a18 test(model): Find & Create actions.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-22 14:57:47 +08:00
qwqcode 9fea95e3dd Merge pull request #21 from ArtalkJS/refactor
Some Refactor
2022-04-22 00:31:20 +08:00
qwqcode bc14540ccc chore: First testing.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-22 00:30:29 +08:00
qwqcode 09d4dfb6ae chore: Add some comments.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-21 21:46:39 +08:00
qwqcode 3f4f0cb6c5 refactor: Replace global variable lib.DB with injected db.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-21 21:34:25 +08:00
qwqcode 796cf2ce53 refactor: Bind API actions under a struct.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-21 21:18:14 +08:00
qwqcode 6e58a80bc1 chore: Update frontend to 2.2.6
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-20 19:45:39 +08:00
qwqcode 024c5fc50c fix(geetest): Static page prevent cache
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-19 20:31:21 +08:00
qwqcode b30b98c447 feat(api_add): Allow patch user-agent parameter
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-19 13:44:11 +08:00
qwqcode 3c58913df1 fix(upgrade): Upgrade cmd load config
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-19 00:48:56 +08:00
qwqcode fba2210e24 feat(api_admin_page_fetch): Add GetStatus parameter.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-19 00:06:33 +08:00
qwqcode 873a2f98dc chore: Remove pvs table & merge pv field to page table.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-18 22:28:08 +08:00
qwqcode b2710b1f1c feat(api): Site cannot find err mark
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-18 22:17:20 +08:00
qwqcode 3348b628ec feat: Page title fetch support meta tag redirect link
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-18 20:36:55 +08:00
qwqcode 59732696c1 feat(api_login_status): Add is_admin field
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-18 19:04:03 +08:00
qwqcode dd55b7f4c3 feat(api): Add Accessible URL fields
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-18 18:24:55 +08:00
qwqcode f861fa282a refactor: Improve GetLinkToReply logic
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-18 17:43:02 +08:00
qwqcode 34f5005843 feat: Admin update all title of pages.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-18 17:23:16 +08:00
qwqcode 1e98599dc1 fix(importer): UrlResolver avoid end of slash being removed
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-18 15:42:53 +08:00
qwqcode c94eaba7a5 feat(db): Remove formal foreign key constraints
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-18 14:24:45 +08:00
qwqcode da746c4134 fix: Geetest js resource url
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 21:57:32 +08:00
qwqcode c691c495fa chore: Update docker-compose.yml
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 21:16:35 +08:00
qwqcode 8e8e428300 chore: Update FeMinVersion to v2.2.2
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 19:57:23 +08:00
qwqcode 0c69206bd0 feat(api-import-upload): Frontend importer upload before.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 17:17:15 +08:00
qwqcode eb2bf34227 chore: Modify build-frontend.sh to use the latest commit
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 14:35:59 +08:00
qwqcode 25f0e26fe7 fix(import/export): Fix some bugs & simplify code
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 14:33:42 +08:00
qwqcode 19885c86d9 docs: Update README.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 02:18:53 +08:00
qwqcode eb529ac941 feat(version): Update Frontend min version to 2.2.1
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 02:07:54 +08:00
qwqcode c216e5a239 feat(api): Modify some APIs method to post
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 02:01:41 +08:00
qwqcode 67358cad18 docs: Update README.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 01:35:58 +08:00
qwqcode b2a780ebb5 fix(api_version): Trim version prefix v char
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 01:23:52 +08:00
qwqcode 19e188b7f7 feat(cmd): Add config cmd
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 01:18:09 +08:00
qwqcode 2a5e54f8cb fix(limit-middleware): Precise match & fix disable captcha config.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 00:57:13 +08:00
qwqcode ab9b9ec818 feat(api): Get login status API
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 00:38:01 +08:00
qwqcode a8faad7b17 fix(api_main_get): Msg center disable comment-pin.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-17 00:19:04 +08:00
qwqcode c1279b3089 fix(captcha): Fix lots of bugs.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-16 23:30:29 +08:00
qwqcode 14661ed00b feat(geetest): Provide geetest check API for frontend.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-16 19:10:26 +08:00
qwqcode b9cbe4e955 feat(geetest): Access geetest API
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-16 16:37:16 +08:00
qwqcode 53c4a64aa1 refactor(notify_launcher): notify_launcher refactor and fix some bugs.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-16 15:08:56 +08:00
qwqcode b85a5a4673 fix: Truncate Chinese character issue.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-16 01:30:37 +08:00
qwqcode 93a4f6fe5a feat(anti-spam): Support KeyWords for Spam detection.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-16 01:21:16 +08:00
qwqcode a7bb22fa81 feat(anti-spam): Support Aliyun for Spam detection.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-16 00:34:41 +08:00
qwqcode 9c463c1705 feat(tencent_tms): Support tencent tms for Spam detection.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-15 22:01:32 +08:00
qwqcode 651ac9d973 chore(license): Relicense project to LGPL-v3
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-15 14:00:47 +08:00
qwqcode 73b97a8c89 fix(docker): Run artalk-go anywhere with a right config
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-15 13:17:46 +08:00
qwqcode 996b762d5b feat(cmd): Add workdir parameter & gen cmd.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-15 12:58:36 +08:00
qwqcode 5d5bc6dd24 chore: Modify FeMinVersion to 2.1.9
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-15 00:19:59 +08:00
qwqcode f70a509213 feat(notify): Various ways to send notify message for admin.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-14 23:04:20 +08:00
qwqcode 2027f26053 fix(admin_site_edit): Split urls and TrimSpace to allow Space around sep char.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-14 20:43:59 +08:00
qwqcode b86250889d chore(pkm): Replace yarn to pnpm.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-14 15:29:23 +08:00
qwqcode ba7c366b97 feat(self-upgrade): Add cmd Self-upgrade function
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-14 14:05:50 +08:00
qwqcode f6674c149d Merge pull request #18 from ArtalkJS/img-upload
图片上传功能 (后端 API)
2022-04-14 00:30:58 +08:00
qwqcode 3b3947c1c1 chore: Modify img_upload.max_size example value.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-14 00:23:40 +08:00
qwqcode 523fab8036 fix(img-upload): Set img_upload.path defualt value
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-14 00:13:48 +08:00
qwqcode d17987d64b feat(img-upload): Admin always enable img_upload function.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-13 22:50:51 +08:00
qwqcode 30e8ade45a docs: Update README.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-13 22:30:39 +08:00
qwqcode ef3cbf5993 feat(img-upload): Upload using upgit
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-13 22:27:57 +08:00
qwqcode c943c8fa08 feat(img-upload): Upload rate limitation.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-13 21:13:13 +08:00
qwqcode 7b2db0faf8 feat(img-upload): Image Upload Api
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-13 21:06:37 +08:00
qwqcode 5a6f926085 feat(img-upload): Add img-upload option to config file.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-13 18:43:48 +08:00
qwqcode 1016adf0ca docs: Update README.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-13 00:52:10 +08:00
qwqcode 3538d6a7c8 feat(pin): Pin comments keep most top & Child-comments recursive query use Cooked.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-13 00:14:34 +08:00
qwqcode a26e8f4360 feat(pin): Update admin_comment_edit api to edit IsPinned
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 22:41:54 +08:00
qwqcode e5aac45f1c feat(model): Add IsPinned field into commnent model.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 22:38:41 +08:00
qwqcode fcfba0c6b5 feat(api/get): SortBy & ViewOnlyAdmin param support.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 22:23:01 +08:00
qwqcode c1dfcab0a6 fix(typo): CaptchaCheck typo
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 16:44:23 +08:00
qwqcode eda9ae4fd9 fix(captcha): Always-mode fail on the first req & modify font size
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 16:19:15 +08:00
qwqcode 931902fd8b docs: Update README.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 14:05:49 +08:00
qwqcode f5e2432eec feat(pv): Make route rule & create pvs table
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 14:01:45 +08:00
qwqcode e95a9448fe feat: Page PV counter
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 12:59:36 +08:00
qwqcode 79abdaed28 feat: Remove example config allow_origins field
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 09:15:14 +08:00
qwqcode 597d4dbbd1 feat: trusted_domains disable referer check
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 09:05:00 +08:00
qwqcode 94859f8f54 feat: Global trusted_domain config
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 09:01:40 +08:00
qwqcode 0df40c4fea chore: Update script use volta install node
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 00:53:25 +08:00
qwqcode aa902601fb feat: Use bluemonday sanitizer
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 00:26:10 +08:00
qwqcode 60e91a5ae7 chore: Script check and install yarn
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-12 00:16:39 +08:00
qwqcode 17f6897d47 fix: Dockerfile install bash
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-11 23:46:05 +08:00
qwqcode 72383a0e08 docs: Update README.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-11 23:40:22 +08:00
qwqcode afd88967ab chore: Remove deprecated artransfer cdoe
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-11 23:37:39 +08:00
qwqcode bece167fea feat: Add script to build artalk-sidebar
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-11 23:32:44 +08:00
qwqcode 3960a8356e fix(UA): Cooperate with client-side to correct Win11 UA.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-04-11 21:45:08 +08:00
qwqcode f518f438ab chore: Update artalk-go.example.yml.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-02-26 22:34:53 +08:00
qwqcode f420fb5cfd fix: Reduce the use of native raw SQL to process boolean judgments and transfer them to ORM for processing.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-02-26 22:25:56 +08:00
qwqcode 6bee451636 fix: Wrong logic of captcha 'always' config.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-02-26 21:28:28 +08:00
qwqcode 109805894c feat: Update config example file.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-02-26 21:10:34 +08:00
qwqcode dbce93b40d feat: password support to be encrypted by md5.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-02-26 21:06:10 +08:00
qwqcode 211585016d feat: admin_users password support to be encrypted by using bcrypt.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-02-26 20:55:47 +08:00
qwqcode 6b7ba78395 fix: Fix wrong SQL syntax to support mysql database.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2022-02-26 20:09:22 +08:00
qwqcode f48d7c891b fix: Rename field total_parents to total_roots.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-21 00:13:30 +08:00
qwqcode 6206d7dded chore: Modify default email-tpl reply btn text.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-18 18:42:09 +08:00
qwqcode 6371933252 fix(artransfer): typecho date recovery.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-16 17:49:57 +08:00
qwqcode 94754cf29c fix(artransfer): CreatedAt field recovery & json unmarshal number to float64 issue.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-15 23:53:48 +08:00
qwqcode 6c3415b6f3 fix(artransfer): trim json string before checking array type.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-15 15:56:00 +08:00
qwqcode 008a98fcfa fix(artransfer): improve logger & twikoo importer bug.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-14 22:01:50 +08:00
qwqcode 2e5e04332b Update FeMinVersion to 2.1
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-11 00:08:30 +08:00
qwqcode 83f9576de6 fix(vote): Vote up and down at the same time.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-09 23:45:23 +08:00
qwqcode 16ba3bfd84 fix: admin_site_edit URL Validator bug.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-09 22:13:07 +08:00
qwqcode 24764a67bf fix: admin_page_get default Sort by create_at DESC.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-08 18:20:38 +08:00
qwqcode 2f638aabe3 feat: Pagination of admin_page_get.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-08 15:37:24 +08:00
qwqcode db134ec18a feat: FeMinVersion update to 2.0.5
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-02 23:56:20 +08:00
qwqcode 6d6a0504d8 feat: ApiVersion & FeMinVersion.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-02 23:55:20 +08:00
qwqcode 9bcd9921d5 feat: Specific comments get flat mode.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-02 22:47:04 +08:00
qwqcode 47e16fd386 chore: Remove useless type conversion.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-02 20:59:03 +08:00
qwqcode 2d29536fbc docs: Update README.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-11-02 14:35:57 +08:00
qwqcode 861abc2edd docs: Update README.md
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-30 22:22:42 +08:00
qwqcode 3d9ece48fa fix: PageEdit not work when Page is not created. 2021-10-30 21:29:00 +08:00
qwqcode 7db57dcd0b fix(artrans): Frontend import Payload modify to JSON object.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-29 08:21:13 +08:00
qwqcode 977e8af7e0 chore: Modify export param.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-28 22:37:32 +08:00
qwqcode 2a8683a2d5 fix(artrans): Modify Typecho boot param keys.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-28 20:52:54 +08:00
qwqcode fbce496de4 feat(artrans): Run on frontend client.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-28 19:49:13 +08:00
qwqcode 364a251041 feat(artrans): Import from Artalk v1 (PHP).
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-27 17:05:02 +08:00
qwqcode cabc3a96d8 feat(artrans): Export and Import Artrans type data.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-27 15:33:44 +08:00
qwqcode 229ade32c3 fix(importer): json decode by universal type.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-27 08:49:57 +08:00
qwqcode c1ed9fdd92 feat(importer): import from Twikoo.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-26 23:52:20 +08:00
qwqcode 7dc0ea9d19 chore: Merge some code.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-26 23:18:37 +08:00
qwqcode bce0598ebe feat(importer): import from valine.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-26 22:56:21 +08:00
qwqcode fa2c7605e2 fix: Typecho Importer some bugs.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-26 20:37:21 +08:00
qwqcode 6a372bacdc feat: Typecho Impoter add some hint.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-26 19:10:56 +08:00
qwqcode d9e4245bee feat: Typecho Impoter PageKey builder.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-26 17:27:46 +08:00
qwqcode 9a34bcb023 feat: Typecho Impoter. 2021-10-25 23:48:07 +08:00
qwqcode 93d07d9b69 feat: Add robots.txt.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-23 07:54:32 +08:00
qwqcode c10316cbc6 fix: github actions image cache
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-22 19:59:48 +08:00
qwqcode 3155e28fe3 feat: Add goreleaser with golang-cross.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-22 18:33:18 +08:00
qwqcode 3b2c34d6fe Fix empty version issue. 2021-10-21 23:47:07 +08:00
qwqcode edce679f88 Modify config allow_origin to allow_origins
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-10-21 23:35:29 +08:00
qwqcode dce93b3679 Update GitHub actions & add some badges. 2021-10-21 23:06:11 +08:00
qwqcode 1288863264 Github action to dockerhub. 2021-10-21 21:44:45 +08:00
qwqcode 63f7a734ea Improve Email Sender & Fix important security issues. 2021-10-21 20:44:55 +08:00
QWQAQ ba86df566d Merge pull request #5 from syfxlin/main
Fix check email template.
2021-10-21 12:38:01 +08:00
Otstar Lin 308f7cef39 Merge branch 'main' of https://github.com/syfxlin/ArtalkGo 2021-10-21 03:09:24 +00:00
Otstar Lin 53f37fa68a Fix check email template. 2021-10-21 03:08:42 +00:00
QWQAQ 3479584f71 Merge pull request #4 from syfxlin/main
Fix a typo.
2021-10-21 01:01:20 +08:00
Otstar Lin 312b387581 Fix a typo. 2021-10-20 16:11:39 +00:00
qwqcode ec51c719c3 Format yml config file. 2021-10-20 22:50:09 +08:00
QWQAQ 10c09a92fa Update README.md 2021-10-20 22:49:18 +08:00
qwqcode 7cebb701ad Add SSL config & docker build script. 2021-10-20 21:11:45 +08:00
qwqcode 972355a45a Update dockerfile. 2021-10-20 12:58:06 +08:00
QWQAQ 5716a7bef5 Merge pull request #2 from fossabot/add-license-scan-badge
Add license scan report and status
2021-10-20 11:29:51 +08:00
QWQAQ 9486a04572 Merge pull request #3 from syfxlin/main
添加 Dockerfile 和 docker-compose.yml
2021-10-20 11:28:45 +08:00
Otstar Lin 00fe255223 Add Dockerfile and docker-componse.yml example 2021-10-20 03:07:19 +00:00
fossabot d89e7088b7 Add license scan report and status
Signed off by: fossabot <badges@fossa.com>
2021-10-19 19:45:20 -07:00
QWQAQ 75ff7631bd Update README.md 2021-10-20 00:51:40 +08:00
qwqcode 7da6b44aab Fix wrong delete using. 2021-10-19 11:22:25 +08:00
qwqcode 727dcfcf28 Add site model field . 2021-10-18 21:05:04 +08:00
qwqcode 0e3b1efb53 Vote for comment or page. 2021-10-15 15:53:17 +08:00
qwqcode bb05d683ed Fix msg center empty user bug. 2021-10-14 13:47:20 +08:00
qwqcode 48c60b84d3 User name and email not case sensitive. 2021-10-14 13:24:39 +08:00
qwqcode 7a83824e0d Fix mail notification logic. 2021-10-13 23:13:23 +08:00
qwqcode 47726d614f Comments get with sites. 2021-10-13 21:50:34 +08:00
qwqcode 4ae5a3fd02 Reduce query to improve performance. 2021-10-13 19:49:37 +08:00
qwqcode 12a624555b Mark all as read. 2021-10-13 18:40:14 +08:00
qwqcode 4a9484a544 Unread message mark. 2021-10-12 14:38:44 +08:00
qwqcode 714d5122fb Fix email notify mark and render bug. 2021-10-12 00:01:53 +08:00
qwqcode 33c8bbe9b1 Add model Notify & msg read / unread. 2021-10-11 23:28:40 +08:00
qwqcode 5995bc1c5b Allow any request method at path '/'. 2021-10-11 16:58:43 +08:00
qwqcode dd3dab4294 Fix open assets not found bug. 2021-10-11 13:58:05 +08:00
qwqcode 6c6ca70bd0 Add more todos. 2021-10-10 20:28:01 +08:00
qwqcode 2512a22073 Update README todos. 2021-10-10 20:20:11 +08:00
qwqcode 92f3d7e22e Anti spam: support akismet. 2021-10-10 19:26:54 +08:00
qwqcode 91d965f61c Request param Parser support convert string to bool. 2021-10-10 15:47:49 +08:00
qwqcode 772288dbaf Add timezone config item. 2021-10-10 15:07:24 +08:00
qwqcode 37d4084013 Remove Page model field & fix lots of bugs. 2021-10-10 14:55:36 +08:00
qwqcode 0e53f8b50d New logic to get default site isoluted content. 2021-10-10 00:04:33 +08:00
qwqcode c99861fc30 Improve some details, Soft Delete is not used in some places to prevent content duplication. 2021-10-09 23:07:35 +08:00
qwqcode 4cb361fd51 Admin importer api. 2021-10-09 18:23:51 +08:00
qwqcode 45fec00545 Fix a wrong of type. 2021-10-09 15:03:19 +08:00
qwqcode ad5bf0e5e6 Api for Sidebar Admin panel. 2021-10-08 20:22:02 +08:00
qwqcode 59439d81b5 Replace struct query by string query: bcz when querying with struct, GORM will only query with non-zero fields. 2021-09-28 19:31:55 +08:00
qwqcode 7af6628d38 Cross origin action control & rename some apis. 2021-09-28 19:15:10 +08:00
qwqcode bc2b672b9b Rename param site to site_name & rename manager to admin. 2021-09-27 18:49:09 +08:00
qwqcode 38e98915b7 Remove site isolation of user model. 2021-09-27 17:10:05 +08:00
qwqcode 0a25166bbd Complete Site Isolation & Sync config AdminUsers with database. 2021-09-27 15:32:04 +08:00
qwqcode c124b0abc1 Fix emailsend & Add page details & site isolation. 2021-09-27 13:54:38 +08:00
qwqcode 230b501e23 Modify output date format. 2021-09-18 15:18:59 +08:00
qwqcode 05bc345523 Comment pending type support. 2021-09-18 14:57:34 +08:00
qwqcode f7d1a41717 Comment List FlatMode & Message center. 2021-09-17 22:35:46 +08:00
qwqcode 4514764aba Notification Center. 2021-09-16 22:26:10 +08:00
qwqcode 90fd84722b Remove comment field & collapsed comment. 2021-09-16 14:45:18 +08:00
qwqcode ca08478389 Add manager comment del action. 2021-09-15 21:59:26 +08:00
qwqcode 8a21a4cad5 Fix some bugs. 2021-09-15 21:55:08 +08:00
qwqcode 5374e2f621 Add manager edit-page & edit-comment actions. 2021-09-15 21:12:52 +08:00
qwqcode 0f0e9846c2 Add user-get api. 2021-09-15 16:26:41 +08:00
qwqcode 737beefad2 Modify http routes. 2021-09-14 14:06:56 +08:00
qwqcode c506bf566a Modify the admin user check logic. 2021-09-12 15:29:10 +08:00
qwqcode 10ba5c7623 Update login method.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-09-08 20:04:08 +08:00
qwqcode 9fab4c1aaa Modify ActionGet method from GET to POST. 2021-08-27 11:20:26 +08:00
qwqcode 2daf3d8180 Complete email tpl render. 2021-08-27 10:35:39 +08:00
qwqcode f9412bf098 Add more sql database supports. 2021-08-27 01:14:07 +08:00
qwqcode d8eac4825b CommentAdd action check the admin user. 2021-08-27 00:48:06 +08:00
qwqcode 225d6029fc Update README.md 2021-08-27 00:36:58 +08:00
qwqcode e55d31656b Complete 3 ways to send email: smtp, ali_dm, sendmail. 2021-08-27 00:16:49 +08:00
qwqcode 7ffeb2ff0b Complete permission checker (ActionLimit) and captcha. 2021-08-26 23:02:03 +08:00
qwqcode 3e9869c190 Complete comment basic add & get function. 2021-08-26 17:04:45 +08:00
qwqcode 4389dba285 Rename Artalk-API-Go to ArtalkGo 2021-08-26 00:26:51 +08:00
qwqcode 77d418fa99 Basic route, captcha, jwt, makefile.
Signed-off-by: qwqcode <qwqcode@gmail.com>
2021-08-25 23:52:10 +08:00
qwqcode 170ea5a524 Complete the basic model & config. 2021-08-24 20:38:31 +08:00
qwqcode 6960d5a4fa 🚧 Start the project. 2021-08-24 13:27:00 +08:00
QWQAQ 6409aa91ff Initial commit 2021-08-24 11:16:07 +08:00
938 changed files with 80591 additions and 11887 deletions

No files matched your search

+79
View File
@@ -0,0 +1,79 @@
version: 2.1
orbs:
node: circleci/node@5.2.0
codecov: codecov/codecov@3.3.0
executors:
base:
docker:
- image: cimg/base:stable
node:
docker:
- image: "cimg/node:20.17.0"
go:
docker:
- image: cimg/go:1.22.6
parameters:
trigger-app:
type: boolean
default: false
run-them-all:
type: boolean
default: false
jobs:
## Backend
test_app:
executor: go
working_directory: ~/go/src/github.com/ArtalkJS/Artalk
environment:
GO111MODULE: "on"
steps:
- checkout
- run:
name: "Print the Go version"
command: >
go version
- restore_cache:
keys:
- go-mod-1.22.6-{{ checksum "go.sum" }}
- run:
name: Install Dependencies
command: go mod download
- save_cache:
key: go-mod-1.22.6-{{ checksum "go.sum" }}
paths:
- "~/go/pkg/mod"
- run:
name: Run tests
command: |
mkdir -p /tmp/test-reports
gotestsum --junitfile /tmp/test-reports/unit-tests.xml -- -coverprofile=/tmp/test-reports/coverage.out ./...
- store_test_results:
path: /tmp/test-reports
- codecov/upload:
flags: go
file: /tmp/test-reports/coverage.out
all_projects:
executor: base
steps:
- run:
command: |
echo "all"
workflows:
build-app:
when:
or:
- << pipeline.parameters.trigger-app >>
- << pipeline.parameters.run-them-all >>
jobs:
- test_app
build-shared-other:
when: << pipeline.parameters.run-them-all >>
jobs:
- all_projects
+18 -22
View File
@@ -1,31 +1,27 @@
# https://circleci.com/docs/2.0/configuration-reference
version: 2.1
# this allows you to use CircleCI's dynamic configuration
# https://circleci.com/docs/2.0/dynamic-config/
setup: true
# the path-filtering orb is required to continue a pipeline based on
# https://circleci.com/developer/orbs/orb/circleci/path-filtering
orbs:
node: circleci/node@5.0.3
jobs:
build:
docker:
- image: 'cimg/node:16.15.1'
steps:
- node/install
- checkout
- run:
name: Print the node version
command: node -v
- run:
name: Install pnpm
command: npm i -g pnpm@7.11.0
- run:
name: Install Dependencies
command: pnpm install --frozen-lockfile
- run:
name: Build Artalk
command: pnpm build:all
path-filtering: circleci/path-filtering@1.0.0
workflows:
tests:
setup:
jobs:
- build:
- path-filtering/filter:
mapping: |
(cmd|internal|server|pkg|test|conf)/.* trigger-app true
main.go|go.mod|go.sum trigger-app true
base-revision: master # git branch name
config-path: .circleci/conditional_config.yml
filters:
branches:
ignore:
- gh-pages
- /release\/.+/
- nightly
+1
View File
@@ -0,0 +1 @@
node_modules
+11
View File
@@ -13,8 +13,19 @@ indent_style = space
indent_size = 2
[*.md]
indent_size = 2
trim_trailing_whitespace = false
[*.yml]
indent_style = space
indent_size = 2
[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
indent_style = tab
indent_size = 4
[*.sh]
indent_size = 4
[Dockerfile]
indent_size = 4
-11
View File
@@ -1,11 +0,0 @@
# don't ever lint node_modules
node_modules
# don't lint build output (make sure it's set to your correct build folder name)
dist
# don't lint nyc coverage output
coverage
vite*.config*
# 不检测 js
**/*.js
-45
View File
@@ -1,45 +0,0 @@
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
env: { "browser": true },
parserOptions: {
project: ['./packages/*/tsconfig.json'],
tsconfigRootDir: __dirname,
},
extends: [
'airbnb-base',
'airbnb-typescript/base',
'prettier',
'plugin:import/recommended',
'plugin:import/typescript',
"plugin:compat/recommended",
],
plugins: ['@typescript-eslint', 'import'],
rules: {
'no-alert': 'off',
'no-unused-vars': 'off',
'no-plusplus': 0,
'no-param-reassign': 0,
'no-console': 0,
'no-underscore-dangle': 0,
'no-constructor-return': 0,
'class-methods-use-this': 0,
'spaced-comment': 0,
'no-lonely-if': 0,
'prefer-destructuring': 0,
'import/no-cycle': 0,
'@typescript-eslint/lines-between-class-members': 0,
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-use-before-define': 0,
},
settings: {
'import/resolver': {
typescript: {
"project": [__dirname + "/packages/*/tsconfig.json"]
},
},
'polyfills': [
'AbortController'
]
},
}
+15
View File
@@ -0,0 +1,15 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
buy_me_a_coffee: artalk
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
- https://afdian.com/a/artalk
+25
View File
@@ -0,0 +1,25 @@
name: Comment issue
description: Create comment on a issue
inputs:
issue_number:
required: true
description: The issue number you want to comment
content:
required: true
description: The content of comment
runs:
using: "composite"
steps:
- uses: actions/github-script@v7
env:
STDOUT: ${{ inputs.content }}
with:
script: |
github.rest.issues.createComment({
issue_number: ${{ inputs.issue_number }},
owner: context.repo.owner,
repo: context.repo.repo,
body: process.env.STDOUT
})
+21
View File
@@ -0,0 +1,21 @@
{{ range .Versions }}
## {{ if .Tag.Previous }}[{{ .Tag.Name }}]({{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}){{ else }}{{ .Tag.Name }}{{ end }} ({{ datetime "2006-01-02" .Tag.Date }})
{{ range .CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
* {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }}
{{ end }}
{{ end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}
{{ range .Notes }}
{{ .Body }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}}
+39
View File
@@ -0,0 +1,39 @@
style: github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/ArtalkJS/Artalk
options:
tag_filter_pattern: "^v"
sort: date
commits:
filters:
Type:
- feat
- fix
- perf
- refactor
- docs
commit_groups:
sort_by: Custom
title_order:
- feat
- fix
- perf
- refactor
- docs
title_maps:
feat: Features
fix: Bug Fixes
perf: Performance Improvements
refactor: Code Refactoring
docs: Documentation
header:
pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s\\/]*)\\))?\\:\\s(.*)$"
pattern_maps:
- Type
- Scope
- Subject
notes:
keywords:
- BREAKING CHANGE
+67
View File
@@ -0,0 +1,67 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: gomod
directory: /
schedule:
interval: monthly
commit-message:
prefix: "chore(deps/go): "
groups:
deps:
patterns:
- "*"
open-pull-requests-limit: 15
- package-ecosystem: npm
directory: /ui
schedule:
interval: monthly
commit-message:
prefix: "chore(deps/ui): "
groups:
prod-deps:
dependency-type: production
dev-deps:
dependency-type: development
open-pull-requests-limit: 15
- package-ecosystem: npm
directory: /docs
schedule:
interval: monthly
commit-message:
prefix: "chore(deps/docs): "
groups:
deps:
patterns:
- "*"
open-pull-requests-limit: 15
- package-ecosystem: docker
directory: /
schedule:
interval: monthly
commit-message:
prefix: "chore(deps/docker): "
groups:
deps:
patterns:
- "*"
open-pull-requests-limit: 15
- package-ecosystem: github-actions
directory: /.github/workflows
schedule:
interval: monthly
commit-message:
prefix: "chore(deps/ci): "
groups:
deps:
patterns:
- "*"
open-pull-requests-limit: 15
-10
View File
@@ -1,10 +0,0 @@
{
"extends": ["config:base", "schedule:weekly"],
"branchPrefix": "chore/",
"labels": ["dependencies"],
"rangeStrategy": "bump",
"reviewers": [
"qwqcode",
"kecrily"
]
}
+86
View File
@@ -0,0 +1,86 @@
name: Build App
on:
workflow_call:
inputs:
version:
required: true
type: string
dry_run:
required: true
type: boolean
env:
GO_VERSION: 1.22.6
PKG_NAME: github.com/ArtalkJS/Artalk
DOCKER_IMG: ghcr.io/goreleaser/goreleaser-cross
CACHE_DIR: /tmp/cache/docker-image
jobs:
build_publish:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
ref: ${{ inputs.version }}
# `go-releaser` will read the semver version from git tag name
# `git-chglog` will diff the tag and generate changelog
fetch-depth: 0
# disable cache because the err `no space left on device`
# - name: Docker Image Cache
# id: docker-cache
# uses: actions/cache@v3
# with:
# path: ${{ env.CACHE_DIR }}
# key: docker-image-go-cross-${{ env.GO_VERSION }}
- name: Pull Docker Image
# if: steps.docker-cache.outputs.cache-hit != 'true'
run: |
docker pull "${DOCKER_IMG}:v${GO_VERSION}"
# mkdir -p "${CACHE_DIR}"
# docker save -o "${CACHE_DIR}/go-cross.tar" "${DOCKER_IMG}:v${GO_VERSION}"
# - name: Restore Docker Image from Cache
# if: steps.docker-cache.outputs.cache-hit == 'true'
# run: docker load -i ${CACHE_DIR}/go-cross.tar
- name: Setup git-chglog
run: |
curl -sL $(curl -s https://api.github.com/repos/git-chglog/git-chglog/releases/latest \
| grep -oP '"https://.+linux_amd64.tar.gz"' | tr -d \") | tar -C /usr/local/bin -xz git-chglog
git-chglog --version
- name: Pre Build
run: |-
mkdir -p local
# github token
echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" > local/.release-env
# changelog
git-chglog --config .github/chglog/config.yml ${{ inputs.version }} > local/release-notes.md
# copy config file
cp conf/artalk.example.yml artalk.yml
- name: Print Relase Notes
run: cat local/release-notes.md
- name: Build and Release
run: |
docker run \
--rm \
--privileged \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(pwd)/sysroot:/sysroot \
-v $(pwd):/go/src/${PKG_NAME} \
-w /go/src/${PKG_NAME} \
-e CGO_ENABLED=1 \
--env-file local/.release-env \
ghcr.io/goreleaser/goreleaser-cross:v${GO_VERSION} \
release --release-notes local/release-notes.md ${{ inputs.dry_run && '--skip=publish' || '' }}
+82
View File
@@ -0,0 +1,82 @@
name: Build Docker
on:
workflow_call:
inputs:
version:
required: true
type: string
dry_run:
required: true
type: boolean
target:
required: true
type: string
env:
DOCKER_IMG: artalk/artalk-go
jobs:
build_publish:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
ref: ${{ inputs.version }}
# https://github.com/docker/metadata-action
- name: Gen docker meta
id: meta
uses: docker/metadata-action@v5
with:
context: git
images: |
${{ env.DOCKER_IMG }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
# https://github.com/docker/login-action
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# https://github.com/docker/setup-qemu-action
- name: Setup QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: ${{ inputs.target }}
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
# Build UI outside of Docker to speed up cross-platform builds
- name: Build UI
run: |
make build-frontend
# https://github.com/docker/build-push-action
- name: Build and Push
id: build
uses: docker/build-push-action@v6
with:
push: ${{ !inputs.dry_run }}
context: .
file: ./Dockerfile
build-args: |
APP_VERSION=${{ inputs.version }}
SKIP_UI_BUILD=true
platforms: ${{ inputs.target }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Print image digest
run: echo ${{ steps.build.outputs.digest }}
+31
View File
@@ -0,0 +1,31 @@
name: Build Done
on:
workflow_call:
inputs:
version:
required: true
type: string
dry_run:
required: true
type: boolean
issue_number:
required: true
type: number
jobs:
done:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
ref: ${{ inputs.version }}
- name: Comment done info
uses: ./.github/actions/comment
if: ${{ inputs.issue_number != 0 }}
with:
issue_number: ${{ inputs.issue_number }}
content: |-
🎉 Finished build and publish ${{ inputs.version }} ([NPM Package](https://www.npmjs.com/package/artalk?activeTab=versions) / [Docker Image](https://hub.docker.com/r/artalk/artalk-go/tags) / [Github Release](https://github.com/ArtalkJS/Artalk/releases/tag/${{ inputs.version }})).
+361
View File
@@ -0,0 +1,361 @@
name: Build Nightly
run-name: Build Nightly
on:
schedule:
- cron: "0 10 * * *"
workflow_dispatch:
inputs:
dry_run:
description: "Dry run"
type: boolean
default: true
env:
DIST_DIR: /tmp/builds
DIGEST_DIR: /tmp/digests
DOCKER_IMG: artalk/artalk-go
DOCKER_BUILD_ARGS: |-
SKIP_UI_BUILD=true
jobs:
# Prepare check should run
prepare:
runs-on: ubuntu-latest
outputs:
skip: ${{ steps.check.outputs.skip }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Check should run
id: check
if: github.event_name == 'schedule'
run: |
if [[ "$(git log --since='24 hours ago' | wc -l)" -eq 0 ]] || \
[[ "$GITHUB_REPOSITORY" != "ArtalkJS/Artalk" ]]; then
echo "skip=true" >> $GITHUB_OUTPUT
fi
# Bulid UI first
# (build ui outside of docker to speed up cross-platform builds)
ui:
if: ${{ needs.prepare.outputs.skip != 'true' }}
needs: prepare
runs-on: macos-14
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9.9.0
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20.x
registry-url: https://registry.npmjs.org/
cache: "pnpm"
- name: Get pnpm store directory
shell: bash
run: |
echo "PNPM_STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ env.PNPM_STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build UI
run: |
make build-frontend
- name: Pack UI
id: pack
run: |
SRC_FILE=$(pnpm pack -C ui/artalk --pack-destination ../.. | tail -n 1)
mkdir -p bin
PKG_FILE="bin/artalk_frontend_nigthly_$(date +'%Y%m%d').tar.gz"
mv $SRC_FILE $PKG_FILE
echo "pkg_file=$PKG_FILE" >> $GITHUB_OUTPUT
- name: Upload UI
uses: actions/upload-artifact@v4
with:
name: ui-src
path: |
public
ui/artalk/dist
if-no-files-found: error
retention-days: 1
- name: Upload UI package
uses: actions/upload-artifact@v4
with:
name: build-ui-pkg
path: ${{ steps.pack.outputs.pkg_file }}
retention-days: 1
#
# Build app on different platforms
#
build:
needs: ui
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
# - macos-14
# :(
# native Apple m1 arm64 is not supported nested virtualization yet, so docker qemu is not working.
# https://github.com/actions/runner-images/issues/9460
# https://docs.veertu.com/anka/anka-virtualization-cli/nested-virtualization/
#
# wait for arm64 linux runner support on github actions.
platform:
- linux/amd64
- linux/arm64
# exclude:
# # exclude build x86 on arm, and vice versa.
# - { os: macos-14, platform: linux/amd64 }
# - { os: ubuntu-latest, platform: linux/arm64 }
steps:
- name: Prepare
run: |
PF="${{ matrix.platform }}"
echo "PLATFORM_PAIR=${PF//\//_}" >> $GITHUB_ENV
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup docker on macos
if: startsWith(matrix.os, 'macos')
uses: crazy-max/ghaction-setup-docker@v3
- name: Gen docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_IMG }}
tags: type=raw,value=nightly
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Download UI before build
uses: actions/download-artifact@v4
with:
name: ui-src
- name: Build and push by digest
uses: docker/build-push-action@v6
id: build
with:
context: .
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
build-args: ${{ env.DOCKER_BUILD_ARGS }}
# The `type=image,push=true` must the last one,
# because the `build.outputs.digest` will output the last image's digest.
# The digests will be used in the merge step.
outputs: |
type=docker,name=${{ env.DOCKER_IMG }}
type=image,push=true,name=${{ env.DOCKER_IMG }},push-by-digest=true,name-canonical=true
- name: Export digest
run: |
mkdir -p $DIGEST_DIR
digest="${{ steps.build.outputs.digest }}"
touch "$DIGEST_DIR/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ env.DIGEST_DIR }}/*
if-no-files-found: error
retention-days: 1
# Export docker image
- name: Export Docker Image
id: docker
run: |
IMG_FILE="artalk_docker_nigthly_$(date +'%Y%m%d')_${PLATFORM_PAIR}.tar.gz"
docker save ${{ env.DOCKER_IMG }} | gzip > $IMG_FILE
echo "img_file=$IMG_FILE" >> $GITHUB_OUTPUT
# App
- name: Pack app
id: app
run: |
BASE_DIR="/tmp/app_pkg"
NAME="artalk_nigthly_$(date +'%Y%m%d')_${PLATFORM_PAIR}"
SUB_DIR="$BASE_DIR/$NAME"
PKG_FILE="$BASE_DIR/$NAME.tar.gz"
# bin file
mkdir -p $SUB_DIR
docker run --rm --entrypoint cat ${{ env.DOCKER_IMG }} /artalk > "$SUB_DIR/artalk"
chmod +x "$SUB_DIR/artalk"
# doc file
cp conf/artalk.example.yml "$SUB_DIR/artalk.yml"
cp README.md LICENSE CHANGELOG.md "$SUB_DIR"
# create package file
tar -czf $PKG_FILE -C $BASE_DIR $NAME
echo "app_pkg_file=$PKG_FILE" >> $GITHUB_OUTPUT
# Move build artifacts
- name: Move build artifacts
run: |
mkdir -p $DIST_DIR
mv ${{ steps.app.outputs.app_pkg_file }} $DIST_DIR
mv ${{ steps.docker.outputs.img_file }} $DIST_DIR
# Upload build artifacts
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-${{ env.PLATFORM_PAIR }}
path: ${{ env.DIST_DIR }}/*
if-no-files-found: error
retention-days: 1
# Merge docker digests from different platforms
# Reference: https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
docker_merge:
runs-on: ubuntu-latest
needs: build
steps:
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ env.DIGEST_DIR }}
pattern: digests-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.DOCKER_IMG }}
tags: type=raw,value=nightly
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Create manifest list and push
working-directory: ${{ env.DIGEST_DIR }}
run: |
TAGS_ARG=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")
MINIFEST_SRCS=$(printf '${{ env.DOCKER_IMG }}@sha256:%s ' *)
docker buildx imagetools create ${TAGS_ARG} ${MINIFEST_SRCS}
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.DOCKER_IMG }}:${{ steps.meta.outputs.version }}
# Release
release:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download builds
uses: actions/download-artifact@v4
with:
path: ${{ env.DIST_DIR }}
pattern: build-*
merge-multiple: true
# Generate CHANGELOG
- name: Generate Changelog
run: |
# install git-chglog
curl -sL $(curl -s https://api.github.com/repos/git-chglog/git-chglog/releases/latest \
| grep -oP '"https://.+linux_amd64.tar.gz"' | tr -d \") | tar -C /usr/local/bin -xz git-chglog
CHANGELOG=$(git-chglog --config .github/chglog/config.yml --next-tag nightly nightly)
MD_FILE="/tmp/changelog.md"
echo -e "$CHANGELOG" > $MD_FILE
echo -e "\n> [!NOTE]\n" \
"> The Nightly version, automatically built based on the latest code, " \
"is not yet released and may be unstable. Please use it with caution. " \
"Docker user can run \`docker pull artalk/artalk-go:nightly\` to get " \
"the nightly build." >> $MD_FILE
# checksums.txt
- name: Calculate checksums.txt
run: |
cd $DIST_DIR
sha256sum * > checksums.txt
# print checksums.txt
cat checksums.txt
FILES=$(find ${DIST_DIR} -type f -exec readlink -f {} \;)
echo -e "RELEASE_FILES<<EOF" >> $GITHUB_ENV
echo -e "$FILES" >> $GITHUB_ENV
echo -e "EOF" >> $GITHUB_ENV
- name: Create tag and push
env:
GH_TOKEN: ${{ github.token }}
run: |
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
gh release delete nightly --yes || true
git push origin :refs/tags/nightly || true
git tag -f nightly
git push -f origin nightly
- name: Release
uses: softprops/action-gh-release@v2
with:
prerelease: true
tag_name: nightly
name: 🧪 Nightly Version
body_path: /tmp/changelog.md
files: ${{ env.RELEASE_FILES }}
draft: false
+61
View File
@@ -0,0 +1,61 @@
name: Build Pre Tagging
on:
workflow_call:
inputs:
dry_run:
required: true
type: boolean
issue_number:
required: true
type: number
outputs:
version:
description: "Version"
value: ${{ jobs.tagging.outputs.version }}
jobs:
tagging:
runs-on: ubuntu-latest
steps:
- name: Get release version
run: |
# `github.head_ref` only exists for pull_request events
REF="${{ github.head_ref || github.ref }}"
VERSION="${REF#refs/tags/}"
VERSION="${VERSION#refs/heads/}"
VERSION="${VERSION#release/}"
echo "Version: $VERSION"
echo "VERSION=$VERSION" >> $GITHUB_ENV
if [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Invalid version format: $VERSION, please check git ref or tag."
exit 1
fi
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create Tag
run: |
if [ ! $(git tag -l "${VERSION}") ]; then
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git tag -a $VERSION -m "Release $VERSION"
git push origin $VERSION
else
echo "Skip creating tag $VERSION, already exists."
fi
- name: Comment tag info to PR
uses: ./.github/actions/comment
if: ${{ inputs.issue_number != 0 }}
with:
issue_number: ${{ inputs.issue_number }}
content: |-
🔖 Tagged version [${{ env.VERSION }}](https://github.com/ArtalkJS/Artalk/tree/${{ env.VERSION }}) and updated the [CHANGELOG.md](https://github.com/ArtalkJS/Artalk/blob/master/CHANGELOG.md).
outputs:
version: ${{ env.VERSION }}
+55
View File
@@ -0,0 +1,55 @@
name: Build UI
on:
workflow_call:
inputs:
version:
required: true
type: string
dry_run:
required: true
type: boolean
jobs:
build_publish:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
ref: ${{ inputs.version }}
- name: Use pnpm
uses: pnpm/action-setup@v4
with:
version: 9.9.0
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20.x
registry-url: https://registry.npmjs.org/
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
- name: Publish
run: pnpm publish -F artalk --no-git-checks ${{ inputs.dry_run && '--dry-run' || '' }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# GitHub Packages
#
# Setup .npmrc file to publish to GitHub Packages
# - uses: actions/setup-node@v4
# with:
# registry-url: 'https://npm.pkg.github.com'
# # Publish to GitHub Packages
# - run: npm publish
# env:
# NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+82
View File
@@ -0,0 +1,82 @@
name: Build and Publish
run-name: Build and Publish (${{ github.head_ref || github.ref }}) ${{ inputs.dry_run && '(🧪 Dry-Run)' || '' }}
on:
pull_request:
branches: [master]
types: [closed]
workflow_dispatch:
inputs:
dry_run:
description: "Dry run"
type: boolean
default: true
build_items:
description: "Build items"
type: string
default: "ui,app,docker"
jobs:
# Tag the release version code before building
# Getting the version code from the branch name or git ref.
tagging:
# Only run on manual trigger
# or when a PR is merged into master.
# (which the branch name start with `relase/`)
if: |
github.event_name == 'workflow_dispatch' ||
(github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/'))
uses: ./.github/workflows/build-tagging.yml
with:
issue_number: ${{ github.event.pull_request.number || 0 }}
dry_run: ${{ inputs.dry_run || false }}
secrets: inherit
# Build the UI
ui:
if: inputs.build_items == '' || contains(inputs.build_items, 'ui')
needs: tagging
uses: ./.github/workflows/build-ui.yml
with:
version: ${{ needs.tagging.outputs.version }}
dry_run: ${{ inputs.dry_run || false }}
secrets: inherit
# Build the Docker image
docker:
if: inputs.build_items == '' || contains(inputs.build_items, 'docker')
needs: tagging
uses: ./.github/workflows/build-docker.yml
# Parallel build the multi-arch docker image
strategy:
matrix:
# since docker push actions will override the previous images,
# so need to build `linux/amd64` and push first,
# then build `linux/amd64` twice with other archs (build very slow so keep it last).
target: ["linux/amd64", "linux/amd64,linux/arm64"]
with:
version: ${{ needs.tagging.outputs.version }}
dry_run: ${{ inputs.dry_run || false }}
target: ${{ matrix.target }}
secrets: inherit
# Build the binary app
app:
if: inputs.build_items == '' || contains(inputs.build_items, 'app')
needs: tagging
uses: ./.github/workflows/build-app.yml
with:
version: ${{ needs.tagging.outputs.version }}
dry_run: ${{ inputs.dry_run || false }}
secrets: inherit
# All builds are complete
done:
needs: [tagging, ui, docker, app]
uses: ./.github/workflows/build-done.yml
with:
version: ${{ needs.tagging.outputs.version }}
issue_number: ${{ github.event.pull_request.number || 0 }}
dry_run: ${{ inputs.dry_run || false }}
secrets: inherit
+37 -34
View File
@@ -9,16 +9,18 @@
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
name: CodeQL
on:
push:
branches: [ "master" ]
branches:
- master
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
branches:
- master
schedule:
- cron: '40 17 * * 4'
- cron: "40 17 * * 4"
jobs:
analyze:
@@ -32,43 +34,44 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
language:
- go
- javascript
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
+42
View File
@@ -0,0 +1,42 @@
name: Docs CN Mirror Deploy
on:
push:
branches: ["master"]
paths: ["docs/**"]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Use pnpm
uses: pnpm/action-setup@v4
with:
version: 9.9.0
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Build Docs
run: pnpm build:docs
- name: Deploy
uses: TencentCloud/cos-action@v1
with:
secret_id: ${{ secrets.TENCENT_CLOUD_SECRET_ID }}
secret_key: ${{ secrets.TENCENT_CLOUD_SECRET_KEY }}
cos_bucket: ${{ secrets.DOCS_CN_COS_BUCKET }}
cos_region: ${{ secrets.DOCS_CN_COS_REGION }}
local_path: docs/docs/.vitepress/dist/
remote_path: /
clean: true
-74
View File
@@ -1,74 +0,0 @@
# https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
name: NPM Publish
on:
push:
tags:
- v*
jobs:
publish:
# prevents this action from running on forks
if: github.repository == 'ArtalkJS/Artalk'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Use pnpm
uses: pnpm/action-setup@v2.2.4
with:
version: 7.11.0
- name: Set node version to 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
registry-url: https://registry.npmjs.org/
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
- name: Publish
run: cd packages/artalk && pnpm publish --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# GitHub Packages
#
# Setup .npmrc file to publish to GitHub Packages
# - uses: actions/setup-node@v2
# with:
# registry-url: 'https://npm.pkg.github.com'
# # Publish to GitHub Packages
# - run: npm publish
# env:
# NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Docs Update
docs-update:
runs-on: ubuntu-latest
steps:
- name: Get the version
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/v/}
- name: Checkout ArtalkDocs
uses: actions/checkout@v3
with:
repository: ArtalkJS/Docs
token: ${{ secrets.PAT }}
- name: Update CDN links
run: |
sed -i 's#artalk@.[^/]*#artalk@${{ steps.get_version.outputs.VERSION }}#g' docs/code/ArtalkCDN.json
perl -pi -e 's#"Artalk"(\W+)?:(\W+)?".*?"#"Artalk": "${{ steps.get_version.outputs.VERSION }}"#g' docs/code/ArtalkVersion.json
sed -i 's#artalk@.[^/]*#artalk@${{ steps.get_version.outputs.VERSION }}#g' docs/code/quick-start/cdn.html
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Update Artalk CDN link to v${{ steps.get_version.outputs.VERSION }}
-41
View File
@@ -1,41 +0,0 @@
name: GitHub Pages
on:
push:
branches:
- master
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Use pnpm
uses: pnpm/action-setup@v2.2.4
with:
version: 7.11.0
- name: Set node version to 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
registry-url: https://registry.npmjs.org/
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Build
run: cd packages/artalk && pnpm predeploy
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: gh-pages
publish_dir: ./packages/artalk/deploy
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
+96
View File
@@ -0,0 +1,96 @@
name: 0x📦 Release New Version
run-name: 📦 Release ${{ inputs.semver }} by @${{ github.actor }} ${{ inputs.dry_run && '(🧪 Dry-Run)' || '' }}
on:
workflow_dispatch:
inputs:
semver:
type: choice
description: Which version you want to increment?
options:
- patch
- minor
- major
required: true
custom_version:
description: Manual Custom Version (Special Purpose, v*)
type: string
required: false
dry_run:
description: "Dry run?"
type: boolean
default: false
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
ref: master
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20.x
registry-url: https://registry.npmjs.org/
- name: Setup semver
run: npm install -g semver
- name: Handle Version Number
run: |
PREV_VERSION="$(git describe --tags --abbrev=0 --match 'v*')"
if [ -n "${{ inputs.custom_version }}" ]; then
NEXT_VERSION="${{ inputs.custom_version }}"
else
NEXT_VERSION="v$(semver --increment ${{ inputs.semver }} ${PREV_VERSION})"
fi
echo "PREV_VERSION=${PREV_VERSION}" >> $GITHUB_ENV
echo "VERSION=${NEXT_VERSION}" >> $GITHUB_ENV
- name: Print Next Version
run: echo "${VERSION}"
- name: Setup git-chglog
run: |
curl -sL $(curl -s https://api.github.com/repos/git-chglog/git-chglog/releases/latest \
| grep -oP '"https://.+linux_amd64.tar.gz"' | tr -d \") | tar -C /usr/local/bin -xz git-chglog
git-chglog --version
- name: Version Changelog
run: |
# prepend changelog
changelog=$(git-chglog --config .github/chglog/config.yml --next-tag "${VERSION}" "${VERSION}")
echo -e "${changelog}\n" | cat - CHANGELOG.md > temp && mv temp CHANGELOG.md
# modify the version of `package.json`
perl -i -pe 's/"version": ".*?"/"version": "'${VERSION#v}'"/g' ui/artalk/package.json
# modify the version in docs
perl -pi -e 's#"latest"(\W+)?:(\W+)?".*?"#"latest": "'${VERSION#v}'"#g' docs/docs/code/ArtalkVersion.json
- name: Print Git Diff
run: git diff
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
if: ${{ !inputs.dry_run }}
with:
branch: "release/${{ env.VERSION }}"
commit-message: "chore: release ${{ env.VERSION }}"
title: "chore: release ${{ env.VERSION }}"
labels: release
body: |
## Release ${{ env.VERSION }} 📦🚀
This PR is auto-generated, please check the changelog and confirm the release. 😀
The build workflow will be triggered after the PR is merged.
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
assignees: ${{ github.actor }}
+20
View File
@@ -0,0 +1,20 @@
name: Repo Dispatch
run-name: Dispatch event `${{ inputs.event_type }}` manually by @${{ github.actor }}
on:
workflow_dispatch:
inputs:
event_type:
type: string
description: Event Type
required: true
default: ""
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v3
with:
event-type: ${{ inputs.event_type }}
+38
View File
@@ -0,0 +1,38 @@
name: Test Docs
on:
push:
branches: ["*", "!release/*", "!nightly"]
paths: ["docs/**"]
tags-ignore: ["v*"]
pull_request:
paths: ["docs/**"]
branches: ["*", "!release/*", "!nightly"]
jobs:
test_docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Use pnpm
uses: pnpm/action-setup@v4
with:
version: 9.9.0
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Build Docs
run: pnpm build:docs
- name: Lint Docs
run: pnpm eslint docs && pnpm prettier --check docs
+56
View File
@@ -0,0 +1,56 @@
name: Test Frontend
on:
push:
branches: ["*", "!release/*", "!nightly"]
paths: ["ui/**"]
tags-ignore: ["v*"]
pull_request:
paths: ["ui/**"]
branches: ["*", "!release/*", "!nightly"]
jobs:
test_ui:
strategy:
matrix:
node: [18, 20]
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- if: matrix.os == 'windows-latest'
name: Set git to use LF (for Windows environment)
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout Code
uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9.9.0
- name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: pnpm
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- name: Package Build Test
run: pnpm build:all
- name: Unit test
run: pnpm test
- name: Lint
run: pnpm eslint ui && pnpm prettier --check ui
# https://github.com/arethetypeswrong/arethetypeswrong.github.io
- name: "arethetypeswrong test"
if: runner.os == 'ubuntu-latest'
run: pnpm -F artalk test:attw || true
+59 -12
View File
@@ -1,5 +1,45 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Generated files
.DS_Store
node_modules/
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
.heartbeat
.idea
*~
.goutputstream*
.c9revisions
.settings
.swp
.tmp
.env
.vscode/*.log
.release-env
*.suo
*.ntvs*
*.njsproj
*.sln
.pnpm-store
/sysroot
.history
# Logs
logs
@@ -8,16 +48,23 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
__debug*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
.history
# frontend
node_modules
/ui/**/dist
dist
deploy
local
# backend
/artalk.yml
/config.yml
/bin
/data
/local
# always compile latest version
/public/sidebar
/public/dist
playwright-report
test-results
+179
View File
@@ -0,0 +1,179 @@
# Goreleaser Config
#
# https://goreleaser.com/quick-start/
# https://goreleaser.com/customization/
# https://goreleaser.com/customization/templates/
# https://goreleaser.com/customization/fury/
# https://goreleaser.com/customization/announce/telegram/
project_name: artalk
env:
- GO111MODULE=on
- CGO_ENABLED=1
before:
hooks:
# install dependencies
- make install
- make build-frontend
# build multi-platform
builds:
## ----------------------
## Linux
## ----------------------
# Linux (amd_64)
- id: linux-amd64
goos:
- linux
goarch:
- amd64
env:
- CC=x86_64-linux-gnu-gcc
- CXX=x86_64-linux-gnu-g++
binary: "{{.ProjectName}}"
main: ./main.go
ldflags: &common_ldflags |
-X github.com/ArtalkJS/Artalk/internal/config.Version={{.Version}}
-X github.com/ArtalkJS/Artalk/internal/config.CommitHash={{ .ShortCommit }}
-s -w
# Linux (arm_64)
- id: linux-arm64
goos:
- linux
goarch:
- arm64
env:
- CC=aarch64-linux-gnu-gcc
- CXX=aarch64-linux-gnu-g++
binary: "{{.ProjectName}}"
main: ./main.go
ldflags: *common_ldflags
# Linux (arm_v7)
- id: linux-arm7
goos:
- linux
goarch:
- arm
goarm:
- "7"
env:
- CC=arm-linux-gnueabihf-gcc
- CXX=arm-linux-gnueabihf-g++
binary: "{{.ProjectName}}"
main: ./main.go
ldflags: *common_ldflags
## ----------------------
## macOS
## ----------------------
# Darwin (amd_64)
- id: darwin-amd64
goos:
- darwin
goarch:
- amd64
env:
- CC=o64-clang
- CXX=o64-clang++
binary: "{{.ProjectName}}"
main: ./main.go
ldflags: *common_ldflags
# Darwin (arm_64)
- id: darwin-arm64
goos:
- darwin
goarch:
- arm64
env:
- CC=oa64-clang
- CXX=oa64-clang++
binary: "{{.ProjectName}}"
main: ./main.go
ldflags: *common_ldflags
## ----------------------
## Win
## ----------------------
# Win (amd_64)
- id: windows-amd64
goos:
- windows
goarch:
- amd64
env:
- CC=x86_64-w64-mingw32-gcc
- CXX=x86_64-w64-mingw32-g++
binary: "{{.ProjectName}}"
main: ./main.go
ldflags: *common_ldflags
flags:
# https://go-review.googlesource.com/c/go/+/224588/
# https://github.com/ArtalkJS/Artalk/issues/35
&win_common_flags |
-tags=timetzdata
# Win (arm_64)
- id: windows-arm64
goos:
- windows
goarch:
- arm64
env:
- CC=/llvm-mingw/bin/aarch64-w64-mingw32-gcc
- CXX=/llvm-mingw/bin/aarch64-w64-mingw32-g++
binary: "{{.ProjectName}}"
main: ./main.go
ldflags: *common_ldflags
flags: *win_common_flags
archives:
- id: artalk
builds:
- linux-amd64
- darwin-amd64
- windows-amd64
- windows-arm64
- linux-arm7
- linux-arm64
- darwin-arm64
name_template: "{{.ProjectName}}_v{{.Version}}_{{.Os}}_{{.Arch}}{{.Arm}}"
format: tar.gz
format_overrides:
- goos: windows
format: zip
wrap_in_directory: true
files:
- README*
- LICENSE*
- artalk.yml
checksum:
name_template: "checksums.txt"
snapshot:
name_template: "{{.Version}}-SNAPSHOT-{{.ShortCommit}}"
# changelog:
# sort: asc
# filters:
# exclude:
# - '^docs:'
# - '^test:'
# - '^chore:'
release:
github:
owner: ArtalkJS
name: Artalk
prerelease: auto
draft: false
extra_files:
- glob: ./local/release_includes/*
+18
View File
@@ -0,0 +1,18 @@
CHANGELOG.md
CHANGELOG.tpl.md
CDN.html
internal/template/notify_tpl/default.html
# generated files
# @link https://github.com/prettier/prettier/issues/3634
pnpm-lock.yaml
**/auto-imports.d.ts
**/components.d.ts
**/typed-router.d.ts
ui/artalk/src/api/v2.ts
docs/swagger/swagger.json
docs/swagger/swagger.yaml
docs/**
ui/artalk-sidebar/src/lib/md5.js
ui/artalk/src/lib/detect.ts
**/dist/**
+23 -3
View File
@@ -1,6 +1,26 @@
{
"semi": false,
"arrowParens": "always",
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"bracketSameLine": false,
"jsxSingleQuote": false,
"printWidth": 100,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"semi": false,
"singleQuote": true,
"htmlWhitespaceSensitivity": "ignore"
}
"tabWidth": 2,
"trailingComma": "all",
"useTabs": false,
"vueIndentScriptAndStyle": false,
"overrides": [
{
"files": ["*.yaml", "*.yml"],
"options": {
"singleQuote": false
}
}
]
}
-18
View File
@@ -1,18 +0,0 @@
language: node_js
node_js:
- lts/*
script:
- pnpm run lint
- pnpm run build
cache:
npm: false
directories:
- "~/.pnpm-store"
before_install:
- curl -fsSL https://get.pnpm.io/install.sh | sh -
- pnpm config set store-dir ~/.pnpm-store
install:
- pnpm install
+18
View File
@@ -0,0 +1,18 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Artalk for Debugging",
"type": "go",
"request": "launch",
"mode": "exec",
"program": "${workspaceFolder}/bin/artalk",
"preLaunchTask": "Build for debugging",
"env": {
"ATK_SITE_DEFAULT": "ArtalkDocs",
"ATK_TRUSTED_DOMAINS": "http://localhost:5173 http://localhost:23367"
},
"args": ["server", "-c", "${workspaceFolder}/artalk.yml"]
}
]
}
+63
View File
@@ -0,0 +1,63 @@
{
// Enable the ESlint flat config support
"eslint.experimental.useFlatConfig": true,
// Disable the default formatter, use eslint instead
// "prettier.enable": false,
"editor.formatOnSave": false,
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
"eslint.runtime": "node",
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "style/*", "severity": "off" },
{ "rule": "*-indent", "severity": "off" },
{ "rule": "*-spacing", "severity": "off" },
{ "rule": "*-spaces", "severity": "off" },
{ "rule": "*-order", "severity": "off" },
{ "rule": "*-dangle", "severity": "off" },
{ "rule": "*-newline", "severity": "off" },
{ "rule": "*quotes", "severity": "off" },
{ "rule": "*semi", "severity": "off" }
],
// Enable eslint for all supported languages
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml",
"toml",
"xml"
],
"cSpell.words": [
"akismet",
"artalk",
"artran",
"artrans",
"artransfer",
"gomail",
"Goreleaser",
"gorm",
"ldflags",
"lfshook",
"Metas",
"pgsql",
"sendmail",
"sqlite",
"pkged"
]
}
+14
View File
@@ -0,0 +1,14 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build for debugging",
"type": "shell",
"command": "make build-debug",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
+735
View File
@@ -0,0 +1,735 @@
## [v2.9.0](https://github.com/ArtalkJS/Artalk/compare/v2.8.7...v2.9.0) (2024-09-03)
### Features
* **auth:** add user profile and password changing ([#966](https://github.com/ArtalkJS/Artalk/issues/966))
* **config:** add `site_url` config option ([#967](https://github.com/ArtalkJS/Artalk/issues/967))
* **go:** upgrade golang to v1.22.6 and some deps
* **ui/dashboard:** new dashboard ui refresh for desktop devices ([#957](https://github.com/ArtalkJS/Artalk/issues/957))
* **ui/date:** add `dateFormatter` config option ([#940](https://github.com/ArtalkJS/Artalk/issues/940))
* **ui/plugin:** make ui plugin configurable
* **ui/sidebar:** add dark mode toggle for dashboard ([#790](https://github.com/ArtalkJS/Artalk/issues/790))
* **ui/sidebar:** add page search by keywords in sidebar ([#603](https://github.com/ArtalkJS/Artalk/issues/603))
* **ui/sidebar:** add user search by keywords in sidebar ([#710](https://github.com/ArtalkJS/Artalk/issues/710))
### Bug Fixes
* **anti_spam:** handle empty `referer` variable in anti-spam check ([#853](https://github.com/ArtalkJS/Artalk/issues/853))
* **api/auth:** fix missing Microsoft oauth provider configuration ([#929](https://github.com/ArtalkJS/Artalk/issues/929))
* **api/auth:** migrate auth_identities when account merging ([#920](https://github.com/ArtalkJS/Artalk/issues/920))
* **api/auth:** register issue due to unremoved auth records after user deletion ([#919](https://github.com/ArtalkJS/Artalk/issues/919))
* **api/comment_add:** improve the security of comment add api ([#964](https://github.com/ArtalkJS/Artalk/issues/964))
* **auth:** correct email verification code send button
* **plugin/lightbox:** fix import for non-browser env ([#931](https://github.com/ArtalkJS/Artalk/issues/931))
* **plugin_kit:** fix typescript lib path retrieval on win
* **plugin_kit:** import source path case error on linux
* **sidebar:** correct total item count for pagination in sidebar
* **ui/dark_mode:** apply dark mode config option before mounting ui ([#890](https://github.com/ArtalkJS/Artalk/issues/890))
* **ui/plugin-kit:** fix typescript lib folder for api-extractor in monorepo
* **ui/sidebar:** disable admin password check dialog in sidebar
* **ui/sidebar:** show env variables in sidebar settings ui ([#946](https://github.com/ArtalkJS/Artalk/issues/946)) ([#956](https://github.com/ArtalkJS/Artalk/issues/956))
* **ui/stat:** fix invalid backward compatible strategy ([#880](https://github.com/ArtalkJS/Artalk/issues/880))
* **validator:** restrict to allow only HTTP protocol
### Performance Improvements
* **api/auth:** add more specific error messages for login failures
* **app/init:** generate translated config file by env variable `ATK_LOCALE`
* **auth:** add loading skeleton for login methods list
* **auth:** enhance visibility of skip button ([#863](https://github.com/ArtalkJS/Artalk/issues/863))
* **auth:** perform optical adjustment for consistent icon sizing
* **auth:** correct verify button position in register form
* **i18n:** auto-load frontend i18n locale js sources
* **notify:** improve error messages for notify ([#943](https://github.com/ArtalkJS/Artalk/issues/943))
* **plugin_kit:** improve typescript diagnostics output
* **style/sidebar:** modify font-family for sidebar
* **ui/sidebar:** enhance i18n translations for sidebar
* **ui/sidebar:** mask sensitive input values in sidebar settings ([#494](https://github.com/ArtalkJS/Artalk/issues/494))
* **ui/sidebar:** optimize setup process and i18n lazy load ([#962](https://github.com/ArtalkJS/Artalk/issues/962))
### Code Refactoring
* **plugin_katex:** use tokenizer extension of marked ([#955](https://github.com/ArtalkJS/Artalk/issues/955))
* **ui/deps:** remove `abortcontroller-polyfill` ([#923](https://github.com/ArtalkJS/Artalk/issues/923))
* **ui/marked:** replace pkg-level marked with new class instance ([#954](https://github.com/ArtalkJS/Artalk/issues/954))
* **ui/types:** add `Layer` interface
* **ui/user:** rename `nick` to `name` in `LocalUser` data structure ([#961](https://github.com/ArtalkJS/Artalk/issues/961))
### Documentation
* **auth:** set `auth.anonymous` to false as default
* **ui/i18n:** add more locale support for sidebar
* **ui/i18n:** add translations for French, Korean, and Russian
## [v2.8.7](https://github.com/ArtalkJS/Artalk/compare/v2.8.6...v2.8.7) (2024-06-09)
### Features
* **go:** upgrade golang to v1.22.3 and some deps
* **plugin_kit:** add vite plugin for developing artalk plugins ([#904](https://github.com/ArtalkJS/Artalk/issues/904))
* **sync:** add keyed rw-mutex
### Bug Fixes
* **api/auth:** include render mustache params for verification email subject ([#910](https://github.com/ArtalkJS/Artalk/issues/910))
* **api/stats:** fix `site_pv` response body and add unit tests ([#896](https://github.com/ArtalkJS/Artalk/issues/896))
* **api/transfer_upload:** close temp file in transfer upload endpoint ([#877](https://github.com/ArtalkJS/Artalk/issues/877))
* **auth:** failed to register by social account on mysql database ([#902](https://github.com/ArtalkJS/Artalk/issues/902))
* **conf_env:** enhance environment variable loading for config ([#892](https://github.com/ArtalkJS/Artalk/issues/892))
* **plugin_katex:** fix event issue causing katex integration failure ([#897](https://github.com/ArtalkJS/Artalk/issues/897))
* **ui/height_limit:** height limit issue for collapsed comments ([#865](https://github.com/ArtalkJS/Artalk/issues/865))
* **ui/sidebar:** unable to logout if user is not admin in control center
* **ui/types:** remove marked dependency in dts ([#868](https://github.com/ArtalkJS/Artalk/issues/868))
### Performance Improvements
* **conf:** add cache for config metadata to boost startup speed ([#892](https://github.com/ArtalkJS/Artalk/issues/892))
* **dao:** add singleflight for no-cache db find func
* **gravatar:** support both sha256 and md5 hash for gravatar ([#912](https://github.com/ArtalkJS/Artalk/issues/912))
* **gravatar:** convert email to lowercase before hashing for gravatar
* **gravatar:** use sha256 hashing algorithm for gravatar ([#874](https://github.com/ArtalkJS/Artalk/issues/874))
* **ui/conf:** exclude conf `pvEl`, `countEl` and `statPageKeyAttr` from remove server ([#905](https://github.com/ArtalkJS/Artalk/issues/905))
* **ui/dev:** bump eslint to v9 ([#915](https://github.com/ArtalkJS/Artalk/issues/915))
### Code Refactoring
* **dao:** add `date` field to the page json entity
* **dao:** improve `QueryDBWithCache` func and concurrent unit tests ([#884](https://github.com/ArtalkJS/Artalk/issues/884))
* **transfer:** improve the reliability of the transfer ([#883](https://github.com/ArtalkJS/Artalk/issues/883))
* **transfer:** strip domain from page key by default ([#873](https://github.com/ArtalkJS/Artalk/issues/873))
* **ui:** fix linter issues for ui and docs ([#917](https://github.com/ArtalkJS/Artalk/issues/917))
* **ui/stat:** use class selector for pageview elements by default ([#880](https://github.com/ArtalkJS/Artalk/issues/880))
### Documentation
* refine documentation
* **dev:** refine contributing.md and translate to chinese
* **i18n:** revise French translation ([#913](https://github.com/ArtalkJS/Artalk/issues/913))
* **ip_region:** add instructions for obtaining accurate IP under proxy
## [v2.8.6](https://github.com/ArtalkJS/Artalk/compare/v2.8.5...v2.8.6) (2024-05-09)
### Features
* **auth:** user accounts merge tool ([#854](https://github.com/ArtalkJS/Artalk/issues/854))
* **auth:** social login api endpoints ([#854](https://github.com/ArtalkJS/Artalk/issues/854))
* **ci:** include frontend dist files in release ([#860](https://github.com/ArtalkJS/Artalk/issues/860))
* **i18n:** add incremental updates feature for i18n code scan tool
* **multi_push/lark:** add card mode for lark push ([#839](https://github.com/ArtalkJS/Artalk/issues/839))
* **sync:** add keyed mutex
* **ui/auth:** plugin-auth for integrating social login ([#854](https://github.com/ArtalkJS/Artalk/issues/854))
* **ui/img_lazyload:** add support for lazy loading images ([#850](https://github.com/ArtalkJS/Artalk/issues/850))
### Bug Fixes
* **api/pv:** add mutex for page pv record endpoint
* **cache/user:** user id cache from email lookup not cleared
* **comments_get:** include `site_name` for isolation in associated query for comment's page
* **dao:** ensure find and create functions thread safe ([#845](https://github.com/ArtalkJS/Artalk/issues/845))
* **db/migrate:** fix root_id migrate for database lacking recursive CTE support ([#848](https://github.com/ArtalkJS/Artalk/issues/848)) ([#846](https://github.com/ArtalkJS/Artalk/issues/846))
* **db_migrate:** drop `fk_comments_user` foreign key constraint of the users table
* **sidebar/site:** unable to edit the new site urls
* **ui/dark_mode:** add support for configuring dark mode in backend ([#790](https://github.com/ArtalkJS/Artalk/issues/790))
* **ui/dark_mode:** unable to toggle dark mode for sidebar in auto mode
* **ui/height_limit:** height limit not working while loading images ([#849](https://github.com/ArtalkJS/Artalk/issues/849))
* **ui/marked:** optimize same origin link judgment logic
### Documentation
* update introduction document
* **auth:** add social login feature ([#854](https://github.com/ArtalkJS/Artalk/issues/854))
* **i18n:** add translation for Korean and Russian
## [v2.8.5](https://github.com/ArtalkJS/Artalk/compare/v2.8.3...v2.8.5) (2024-04-21)
### Features
* **ci/build:** add nightly build workflow
* **conf/http:** add `http.proxy_header` config option
* **go:** upgrade golang to v1.22.2 and some deps
### Bug Fixes
* **cmd/gen:** ensure directory before saving in `gen` cmd ([#612](https://github.com/ArtalkJS/Artalk/issues/612))
* **dao:** prevent potential infinite loop in `FindCommentRootID`
* **db/migrate:** issue with root id generation
* **db/migrator:** remove foreign key constraints and better `root_id` generation ([#835](https://github.com/ArtalkJS/Artalk/issues/835))
* **log:** improve log system and fix memory leaks ([#843](https://github.com/ArtalkJS/Artalk/issues/843))
* **transfer:** retrieve root_id for imported comment data
* **ui/comment:** missing reply comment data when inserting ([#838](https://github.com/ArtalkJS/Artalk/issues/838))
* **ui/comment:** incorrect reply comment data in nested mode ([#771](https://github.com/ArtalkJS/Artalk/issues/771)) ([#837](https://github.com/ArtalkJS/Artalk/issues/837))
* **ui/lifecycle:** keep root element during destroy ([#810](https://github.com/ArtalkJS/Artalk/issues/810))
* **ui/sidebar:** user list not refresh when data is modified
* **ui/upload:** unable to upload image when file extension is uppercase
* **upload:** add config option to solve request entity too large issue ([#834](https://github.com/ArtalkJS/Artalk/issues/834))
### Performance Improvements
* **conf/upgit:** disallow custom executable path of `upgit` for security ([#817](https://github.com/ArtalkJS/Artalk/issues/817))
* **db:** optimize N+1 query in comment list ([#799](https://github.com/ArtalkJS/Artalk/issues/799))
* **i18n:** add translation for 'parameter is required'
* **ui/pkg:** add shorter export names ([#821](https://github.com/ArtalkJS/Artalk/issues/821))
* **ui/version_check:** beautify version upgrade notice
### Code Refactoring
* **comments_get:** reduce api complexity by introducing `LiteDB` ([#800](https://github.com/ArtalkJS/Artalk/issues/800))
* **ui/prettier:** add prettier code formatter
### Documentation
* **extras:** add deploy guide for Valaxy ([#836](https://github.com/ArtalkJS/Artalk/issues/836))
* **i18n:** add French translation ([#797](https://github.com/ArtalkJS/Artalk/issues/797))
### BREAKING CHANGE
For UpGit users: Due to security reasons, Artalk no longer allows configuring the executable file path (img_upload.upgit.exec) for upgit. Please add it to system environment variables instead.
## [v2.8.3](https://github.com/ArtalkJS/Artalk/compare/v2.8.2...v2.8.3) (2024-03-04)
### Features
* **api/auth:** invalidate old auth tokens after changing password
* **api/domain:** add GET `/conf/domain` endpoint
* **app:** add `onConfUpdated` hook
* **comment:** add `is_verified` field for comment entity
* **ui/api:** add `ctx.getApiHandlers()` to handle error responses and expose hooks
* **ui/editor:** add `beforeSubmit` hook for editor submitting
* **ui/plugins:** support dynamic loading of ui plug-in scripts ([#774](https://github.com/ArtalkJS/Artalk/issues/774))
### Bug Fixes
* **captcha/image:** unable to display image captcha on initial load
* **conf:** skip patching IP region conf if disabled
* **exception:** missing `message` field after refactoring exception data structure
* **sidebar/login:** cannot select a name with the same email upon login ([#781](https://github.com/ArtalkJS/Artalk/issues/781))
* **ui/layer:** ensure immediate operation when calling `show()` after `hide()`
### Performance Improvements
* **ui/editor:** improve the icon details for editor
### Code Refactoring
* **dao:** validate the args of the `FindCreateUser` function
* **entity/user:** extract `CheckPassword` function
* **origin:** extract `CheckURLTrusted` function
## [v2.8.2](https://github.com/ArtalkJS/Artalk/compare/v2.8.1...v2.8.2) (2024-02-05)
### Bug Fixes
* **api/comments:** `ua` field is optional and not required ([#767](https://github.com/ArtalkJS/Artalk/issues/767))
* **style:** replace style `break-all` with `break-word` in content el ([#644](https://github.com/ArtalkJS/Artalk/issues/644))
### Performance Improvements
* **ui/editor:** optimize editor styles for narrow-width screens
* **ui/editor:** modify editor plug-in text buttons to icons for brevity
* **ui/editor:** place `Cancel Reply` at the bottom of editor area ([#644](https://github.com/ArtalkJS/Artalk/issues/644))
* **ui/lite:** disable ArtalkLite `preview` config option by default
## [v2.8.1](https://github.com/ArtalkJS/Artalk/compare/v2.8.0...v2.8.1) (2024-02-04)
### Features
* **api:** add GET `/comments/:id` endpoint ([#764](https://github.com/ArtalkJS/Artalk/issues/764))
* **config:** add `db.prepare_stmt` config option ([#760](https://github.com/ArtalkJS/Artalk/issues/760)) ([#762](https://github.com/ArtalkJS/Artalk/issues/762))
* **ui/goto:** improved solution of navigating to comment via link hash ([#693](https://github.com/ArtalkJS/Artalk/issues/693)) ([#765](https://github.com/ArtalkJS/Artalk/issues/765))
### Bug Fixes
* **api/comments:** counting comments issue in PostgreSQL db ([#760](https://github.com/ArtalkJS/Artalk/issues/760)) ([#761](https://github.com/ArtalkJS/Artalk/issues/761))
* **cmd/admin:** update user role to admin if already exists
* **ip_region:** unable to output the IP region correctly ([#760](https://github.com/ArtalkJS/Artalk/issues/760))
* **ui/list:** unable to reply or delete comments after switching pagination
* **ui/no_comment:** always appears when creating comment
* **ui/pv:** missing `pageTitle` field in the PV request
* **ui/scroll:** scroll into view issue when `relativeTo` parameter is provided
### Performance Improvements
* **style/sidebar:** improve some detail in sidebar
### Code Refactoring
* **ui/comment:** loose coupling between `Comment` and `Context`
* **ui/list:** refactor the list layout manager
### Documentation
* supplement and refine `fe-api.md`
## [v2.8.0](https://github.com/ArtalkJS/Artalk/compare/v2.7.3...v2.8.0) (2024-01-31)
### Features
* **go:** upgrade golang to v1.21.5 and some deps
* **notify:** add `notify_pending` config option ([#728](https://github.com/ArtalkJS/Artalk/issues/728)) ([#754](https://github.com/ArtalkJS/Artalk/issues/754))
* **ui/admin:** add logout button in admin panel ([#488](https://github.com/ArtalkJS/Artalk/issues/488)) ([#753](https://github.com/ArtalkJS/Artalk/issues/753))
### Bug Fixes
* **cache:** unable to change admin list after caching ([#748](https://github.com/ArtalkJS/Artalk/issues/748)) ([#750](https://github.com/ArtalkJS/Artalk/issues/750))
* **i18n:** sidebar language cannot be changed
* **ui/editor:** prevent propagation of click event in editor ([#734](https://github.com/ArtalkJS/Artalk/issues/734))
* **ui/layer:** unexpected behavior with multiple items when closing
* **ui/lite:** correct the instance name for compiling ArtalkLite ([#740](https://github.com/ArtalkJS/Artalk/issues/740))
* **ui/no_comment:** flickering when clearing list before fetch
* **ui/pagination:** auto load list when scroll reaches bottom
* **ui/sidebar:** incorrectly increasing pv count in sidebar ([#724](https://github.com/ArtalkJS/Artalk/issues/724))
* **ui/sidebar_layer:** sidebar still displays when login is required
### Performance Improvements
* **ui/conf:** support for watching partial changes in config with `watchConf()` ([#755](https://github.com/ArtalkJS/Artalk/issues/755))
* **ui/i18n:** refine some translation ([#743](https://github.com/ArtalkJS/Artalk/issues/743))
* **ui/pagination:** replace the prev/next text on pagination buttons with icons ([#743](https://github.com/ArtalkJS/Artalk/issues/743))
* **ui/sidebar:** prevent potential token leakage by clearing query in iframe url
### Code Refactoring
* **api:** update swagger file of API v2
* **api:** refactor HTTP API to version 2 ([#735](https://github.com/ArtalkJS/Artalk/issues/735))
* **transfer:** normalize transfer payload parameter name
* **ui:** optimize init and update lifecycle events
* **ui/comment:** rename class `Comment` to `CommentNode`
* **ui/ctx:** add `getComments` and `getCommentNodes` in context ([#752](https://github.com/ArtalkJS/Artalk/issues/752))
### Documentation
* update multi-sites manual ([#747](https://github.com/ArtalkJS/Artalk/issues/747))
### BREAKING CHANGE
For Developers: The HTTP API has now been updated to version v2, with a lot of adjustments made, such as changing to Restful API style, request type, request body, response body, etc. data structure, adding error response codes. You can refer to [#735](https://github.com/ArtalkJS/Artalk/issues/735) or https://artalk.js.org/http-api Please update all your existing clients to adapt to the new v2 server. The new base path is `/api/v2/`. The UI package's HTTP client has been implemented to auto-generate based on `Swagger.json`, and there have been a lot of adjustments to the `artalk.ctx.getApi()` related code. In addition, the HTTP API no longer enforces checks on the header's `Origin` and `Referer` (to implement strict isolation of different sites) but still maintains the original CORS origin check.
For General Users: Now all administrators have the same level of authority (there is no longer super admin authority), the function of assigning sub-administrators with independent scope authority to individual sites has been removed, which can simplify the HTTP server maintenance and implementation. Upgrading only requires updating the client and server application at the same time, and there are no additional operations.
## [v2.7.3](https://github.com/ArtalkJS/Artalk/compare/v2.7.2...v2.7.3) (2023-12-28)
### Features
* **ci:** add dry-run mode for build workflow
* **cmd:** support cli flag for creating admin account
### Bug Fixes
* **ui/init:** stack overflow when merging with config defaults ([#717](https://github.com/ArtalkJS/Artalk/issues/717))
### Performance Improvements
* **ui/build:** better dts generation ([#689](https://github.com/ArtalkJS/Artalk/issues/689))
### Code Refactoring
* **ci:** better release workflow
* **docker:** add `--build-arg` argument to skip ui build
* **test/ui:** add more ui api tests
* **ui:** refactor directory structure ([#712](https://github.com/ArtalkJS/Artalk/issues/712))
* **ui/conf:** better handling of mutable config ([#722](https://github.com/ArtalkJS/Artalk/issues/722))
* **ui/test:** add vitest for unit testing
### Documentation
* update ui api documentation
### BREAKING CHANGE
Directly referencing `artalk.conf` and `artalk.$root` is deprecated. Please use functions instead: `artalk.getConf()` and `artalk.getEl()`.
## [v2.7.2](https://github.com/ArtalkJS/Artalk/compare/v2.7.1...v2.7.2) (2023-12-20)
### Features
* patch `locale` config from `zh-cn` to `zh-CN` ([#678](https://github.com/ArtalkJS/Artalk/issues/678))
### Bug Fixes
* **sidebar:** sidebar language switch and config save issue ([#708](https://github.com/ArtalkJS/Artalk/issues/708))
* **ui:** add `referrerpolicy` attribute for iframe ([#687](https://github.com/ArtalkJS/Artalk/issues/687)) ([#707](https://github.com/ArtalkJS/Artalk/issues/707))
* **ui/dark-mode:** potential memory leak issue in auto mode ([#688](https://github.com/ArtalkJS/Artalk/issues/688))
* **ui/pagination:** auto switch page by url hashtag issue ([#693](https://github.com/ArtalkJS/Artalk/issues/693))
* **ui/sidebar:** refactor settings and fix save issue ([#677](https://github.com/ArtalkJS/Artalk/issues/677)) ([#706](https://github.com/ArtalkJS/Artalk/issues/706))
### Code Refactoring
* **ui:** move window references into function scope ([#675](https://github.com/ArtalkJS/Artalk/issues/675))
* **ui/api:** losing coupling between `Api` and `User`
* **ui/user:** user class no longer globally singleton
### Documentation
* **i18n:** add translation for `open` button
* **refactor:** organize the pkgs and fix some issues ([#702](https://github.com/ArtalkJS/Artalk/issues/702))
## [v2.7.1](https://github.com/ArtalkJS/Artalk/compare/v2.7.0...v2.7.1) (2023-12-17)
### Bug Fixes
* **build:** generate source maps to ease debugging
* **cout-widget:** `loadCountWidget` issue
* **ui:** static method export issue in JS module ([#669](https://github.com/ArtalkJS/Artalk/issues/669))
### Documentation
* **i18n:** add translation of update notice
## [v2.7.0](https://github.com/ArtalkJS/Artalk/compare/v2.6.4...v2.7.0) (2023-12-17)
### Features
* **ui:** support `scrollRelativeTo` config option
* **ui/test:** add end-to-end (e2e) testing using Playwright
### Bug Fixes
* **api/img-upload:** `public_path` config enables the use of full url ([#659](https://github.com/ArtalkJS/Artalk/issues/659)) ([#664](https://github.com/ArtalkJS/Artalk/issues/664))
* **lifecycle:** create multi-instances at the same time ([#660](https://github.com/ArtalkJS/Artalk/issues/660)) ([#663](https://github.com/ArtalkJS/Artalk/issues/663))
* **notify_pusher:** panic when admin ids array is empty ([#634](https://github.com/ArtalkJS/Artalk/issues/634))
* **style/list:** replace `float` to `text-align` in footer part ([#619](https://github.com/ArtalkJS/Artalk/issues/619))
* **ui:** scroll to the center of the viewport issue
* **ui/conf:** sanitize `noComment` conf option for security ([#624](https://github.com/ArtalkJS/Artalk/issues/624))
* **ui/dark-mode:** `setDarkMode` cannot save to instance config ([#661](https://github.com/ArtalkJS/Artalk/issues/661))
* **ui/editor:** fix position of the comment box when replying ([#643](https://github.com/ArtalkJS/Artalk/issues/643)) ([#648](https://github.com/ArtalkJS/Artalk/issues/648))
### Performance Improvements
* **cache:** implement GC feature for simple_cache pkg ([#656](https://github.com/ArtalkJS/Artalk/issues/656))
### Code Refactoring
* **editor:** refactor editor plugin manager ([#609](https://github.com/ArtalkJS/Artalk/issues/609))
* **editor:** refactor plug kit and events ([#613](https://github.com/ArtalkJS/Artalk/issues/613))
* **ui:** reduce coupling with `ContextApi`
* **ui:** separate standalone admin-only-elem checker
* **ui/api:** loose coupling between `Api` and `Context`
* **ui/conf:** loose coupling between config and list fetch
* **ui/event:** refactor core event manager ([#611](https://github.com/ArtalkJS/Artalk/issues/611))
* **ui/layer:** better layer implements and independence ([#662](https://github.com/ArtalkJS/Artalk/issues/662))
* **ui/list:** separate list into standalone components ([#618](https://github.com/ArtalkJS/Artalk/issues/618))
* **ui/marked:** separate markdown related codes
* **ui/marked:** loose coupling with `marked` func
* **ui/plugin:** further divide functionality into plugins ([#615](https://github.com/ArtalkJS/Artalk/issues/615))
* **ui/stat:** losing coupling of `CountWidget`
* **ui/types:** better `ArtalkType` import and export ([#620](https://github.com/ArtalkJS/Artalk/issues/620))
### Documentation
* revise and add more examples
* provide clearer and more detailed instructions in CONTRIBUTING.md
* **conf:** disable `frontend.uaBadge` config option by default
* **deploy:** add deployment guide for render.com ([#649](https://github.com/ArtalkJS/Artalk/issues/649))
* **import:** update the examples in import-framework.md ([#665](https://github.com/ArtalkJS/Artalk/issues/665))
### BREAKING CHANGE
The following top-level functions exported by the 'artalk' npm package have been deprecated: `Artalk.update`, `Artalk.reload`, and `Artalk.destroy`. These methods now require invocation on an instance created by either `Artalk.init` or `new Artalk`. Please utilize instance-level methods instead, such as `artalkInstance.update`. For more information, refer to [the documentation](https://artalk.js.org/guide/frontend/import-framework.html). The update was implemented to enable the concurrent creation of multiple instances, adapting to situations where Vue components are simultaneously referenced across various pages. Initially, only a singular instance was permitted to mitigate memory leak concerns. However, this proved limiting for scenarios involving the caching of multiple component instances through 'keep-alive.' To better suit intricate SPA application needs, the choice was made to permit the creation of multiple independent instances. It's crucial to remember to manually invoke the `artalk.destroy` method when releasing components to avoid memory leaks (Issue [#660](https://github.com/ArtalkJS/Artalk/issues/660)).
## [v2.6.4](https://github.com/ArtalkJS/Artalk/compare/v2.6.3...v2.6.4) (2023-10-12)
### Features
* **go:** upgrade golang to v1.21.3 and some deps
### Bug Fixes
* **editor:** fix duplicate event binding when update conf ([#605](https://github.com/ArtalkJS/Artalk/issues/605))
* **email:** sender not initialized correctly
* **style:** fix copyright text overlay on send button ([#607](https://github.com/ArtalkJS/Artalk/issues/607))
### Code Refactoring
* **anti_spam:** refactor anti_spam pkg and add unit test ([#589](https://github.com/ArtalkJS/Artalk/issues/589))
## [v2.6.3](https://github.com/ArtalkJS/Artalk/compare/v2.6.2...v2.6.3) (2023-09-20)
### Features
* **config:** add `db.ssl` to enable db ssl mode ([#587](https://github.com/ArtalkJS/Artalk/issues/587))
### Bug Fixes
* **notify_tpl:** fix template render result in notify case
### Performance Improvements
* **config:** add error message for timezone setting ([#586](https://github.com/ArtalkJS/Artalk/issues/586))
### Code Refactoring
* **renderer:** abstract func of template renderer for multi-cases ([#585](https://github.com/ArtalkJS/Artalk/issues/585))
### Documentation
* new landing page
## [v2.6.2](https://github.com/ArtalkJS/Artalk/compare/v2.6.1...v2.6.2) (2023-09-12)
### Bug Fixes
* **cmd:** remove app instance creation when mini boot ([#577](https://github.com/ArtalkJS/Artalk/issues/577))
### Performance Improvements
* **style:** modify `z-index` less than 5 ([#578](https://github.com/ArtalkJS/Artalk/issues/578))
## [v2.6.1](https://github.com/ArtalkJS/Artalk/compare/v2.6.0...v2.6.1) (2023-09-11)
### Bug Fixes
* **captcha:** image captcha base64 response issue ([#575](https://github.com/ArtalkJS/Artalk/issues/575))
### Documentation
* **config:** add info about env variables ([#566](https://github.com/ArtalkJS/Artalk/issues/566))
* **extras:** add deploy guide for railway.app ([#567](https://github.com/ArtalkJS/Artalk/issues/567))
## [v2.6.0](https://github.com/ArtalkJS/Artalk/compare/v2.5.5...v2.6.0) (2023-09-01)
### Features
* **config:** support load env variables as config ([#564](https://github.com/ArtalkJS/Artalk/issues/564))
* **go:** upgrade golang to v1.21.0 and some deps ([#543](https://github.com/ArtalkJS/Artalk/issues/543))
* **hook:** add hook pkg
* **simple_cache:** a simple thread-safe cache with sync.Map
* **utils:** add common random utils
### Bug Fixes
* **cache:** child comment ids store after comment updated
* **cmd:** fix parse root cmd global flags
* **config:** fix ip region patch
* **db:** fix dsn strings for mysql connections ([#541](https://github.com/ArtalkJS/Artalk/issues/541))
* **limiter:** limiter log ignore options method req
* **limiter:** fix limiter always mode
* **log:** add missing log for web server listen func ([#556](https://github.com/ArtalkJS/Artalk/issues/556))
* **ui:** fix plug cannot disable issue ([#563](https://github.com/ArtalkJS/Artalk/issues/563))
### Performance Improvements
* **cmd:** support command mini boot mode
### Code Refactoring
* **CI:** replace using `docker/metadata-action` for the docker push ([#545](https://github.com/ArtalkJS/Artalk/issues/545))
* **CI:** replace renovate with github dependabot ([#546](https://github.com/ArtalkJS/Artalk/issues/546))
* **anti_spam:** refactor anti_spam pkg
* **artransfer:** refactor artransfer pkg
* **cache:** remove cached fields in struct to save memory ([#555](https://github.com/ArtalkJS/Artalk/issues/555))
* **cache:** cache code tidy-up
* **cache:** refactor cache pkg
* **cache:** refactor cache pkg
* **cache:** refactor cache pkg
* **captcha:** refactor captcha pkg
* **cloud:** refactor cloud pkg
* **cmd:** refactor cmd pkg
* **conf:** better config.NewFromFile with error handle
* **config:** refactor config pkg
* **core:** refactor core pkg
* **core:** better AppService func with error handle
* **cors:** refactor cors middleware
* **dao:** refactor dao pkg
* **dao_cache:** add dao_cache pkg
* **db:** refactor db pkg
* **email:** refactor email pkg
* **i18n:** refactor i18n pkg
* **ip_region:** refactor ip_region pkg
* **limiter:** add limiter pkg
* **log:** create common log pkg
* **main:** refactor main.go
* **notify:** add notify_pusher pkg
* **server/common:** refactor server/common pkg
* **server/handler:** refactor server/handler pkg
* **server/middleware:** refactor server/middleware pkg
* **test:** create common test pkg
### Documentation
* **extras:** add deploy guide for fly.io ([#520](https://github.com/ArtalkJS/Artalk/issues/520))
## [v2.5.5](https://github.com/ArtalkJS/Artalk/compare/v2.5.4...v2.5.5) (2023-05-10)
### Features
* **build:** add embedded fe lite and i18n scripts ([#493](https://github.com/ArtalkJS/Artalk/issues/493)) ([#505](https://github.com/ArtalkJS/Artalk/issues/505))
* **go:** upgrade golang to v1.20.4 and some deps ([#506](https://github.com/ArtalkJS/Artalk/issues/506))
* **gravatar:** add `gravatar.params` config option ([#508](https://github.com/ArtalkJS/Artalk/issues/508))
### Bug Fixes
* **api:** comment IP data loss after editing ([#504](https://github.com/ArtalkJS/Artalk/issues/504))
* **editor:** prevent editor reset on comment failure ([#507](https://github.com/ArtalkJS/Artalk/issues/507))
### BREAKING CHANGE
The `gravatar.default` config option has been removed. Please use `gravatar.params` instead. The default value for `gravatar.params` is now `"d=mp&s=240"`.
## [v2.5.4](https://github.com/ArtalkJS/Artalk/compare/v2.5.3...v2.5.4) (2023-04-09)
### Features
* **go:** upgrade golang to v1.20.3 and some deps ([#485](https://github.com/ArtalkJS/Artalk/issues/485))
### Bug Fixes
* **CI:** upgrade and pin node.js and pnpm version ([#484](https://github.com/ArtalkJS/Artalk/issues/484))
### Documentation
* update swagger docs and some deps
## [v2.5.3](https://github.com/ArtalkJS/Artalk/compare/v2.5.2...v2.5.3) (2023-04-06)
### Bug Fixes
* **api/comment_add:** SIGSEGV crash in comment_add ([#478](https://github.com/ArtalkJS/Artalk/issues/478)) ([#481](https://github.com/ArtalkJS/Artalk/issues/481))
### Performance Improvements
* **ip_region:** add db file existence check and error message ([#482](https://github.com/ArtalkJS/Artalk/issues/482))
## [v2.5.2](https://github.com/ArtalkJS/Artalk/compare/v2.5.1...v2.5.2) (2023-03-19)
### Bug Fixes
* **ui:** destroy instance when calling init func twice
### Performance Improvements
* **notify:** shorten the length of notify key ([#466](https://github.com/ArtalkJS/Artalk/issues/466))
* **style:** add `!important` for white-space css in code block ([#467](https://github.com/ArtalkJS/Artalk/issues/467))
## [v2.5.1](https://github.com/ArtalkJS/Artalk/compare/v2.5.0...v2.5.1) (2023-03-16)
### Features
* **go:** upgrade golang to v1.20.2
### Bug Fixes
* **ui/count-widget:** context api undefined issue ([#464](https://github.com/ArtalkJS/Artalk/issues/464))
* **ui/i18n:** duplicate packaging built-in language in the external script
* **ui/paginator:** showErr func call issue
* **ui/sort-dropdown:** dropdown menu disappears after call reload func ([#461](https://github.com/ArtalkJS/Artalk/issues/461))
### Code Refactoring
* **anti_spam/aliyun:** accessing aliyun green text api without sdk ([#459](https://github.com/ArtalkJS/Artalk/issues/459))
* **ui/user:** modify user to standalone module ([#463](https://github.com/ArtalkJS/Artalk/issues/463))
## [v2.5.0](https://github.com/ArtalkJS/Artalk/compare/v2.4.4...v2.5.0) (2023-03-10)
### Features
* migrate from `echo` to `go-fiber`
* upgrade go to v1.20.1
* display IP region of comment ([#418](https://github.com/ArtalkJS/Artalk/issues/418)) ([#447](https://github.com/ArtalkJS/Artalk/issues/447))
* docker ci add support for building arm64 wheels
* more functions to handle artalk lifecycle ([#426](https://github.com/ArtalkJS/Artalk/issues/426))
* **ui:** add some static methods
* **ui/height_limit:** support scrollable height limit area ([#451](https://github.com/ArtalkJS/Artalk/issues/451))
* **ui/sidebar:** add dark mode support ([#450](https://github.com/ArtalkJS/Artalk/issues/450))
* **captcha:** add support for reCAPTCHA and hCaptcha ([#456](https://github.com/ArtalkJS/Artalk/issues/456))
* **captcha:** support turnstile captcha by cloudflare ([#453](https://github.com/ArtalkJS/Artalk/issues/453))
* **i18n:** add i18n support for backend ([#343](https://github.com/ArtalkJS/Artalk/issues/343))
* **i18n:** translations for backend ([#344](https://github.com/ArtalkJS/Artalk/issues/344))
* **i18n:** add i18n support for sidebar ([#353](https://github.com/ArtalkJS/Artalk/issues/353))
* **i18n:** add zh-TW i18n translation for sidebar and app
### Bug Fixes
* **ui:** hash goto function check condition issue
* **ui/conf:** avoid some conf overrides frontend from the backend ([#449](https://github.com/ArtalkJS/Artalk/issues/449))
* **ui/editor:** disable img upload cannot hide its btn
* **ui/i18n:** subscribe event priority issue
* **ui/sidebar:** array type of preference initial data issue
* **ui/sidebar:** array type config option cannot be shown
* **ui/sidebar:** boolean type setting option save issue ([#431](https://github.com/ArtalkJS/Artalk/issues/431)) ([#444](https://github.com/ArtalkJS/Artalk/issues/444))
* **ui/sidebar:** setting item save follow type of template
* **lint:** add tsc check before vite compile ([#440](https://github.com/ArtalkJS/Artalk/issues/440))
* **email:** duplicate sending with multiple admins using same email addrs ([#375](https://github.com/ArtalkJS/Artalk/issues/375))
* **email:** email queue initialization issue ([#374](https://github.com/ArtalkJS/Artalk/issues/374))
* **email:** failback to `email.mail_tpl` if `admin_notify.email.mail_tpl` is empty
* `timeAgo` function does not display the now
* add `.npmignore` to fix NPM publish inclusion issue
* sidebar navigation sorting ([#361](https://github.com/ArtalkJS/Artalk/issues/361))
### Performance Improvements
* improve some css styles
* add graceful shutdown
* **conf/i18n:** detect and change locale when config file contains chinese
* **ui/list:** remove useless function call
* **ui/sidebar:** improve sidebar i18n
### Code Refactoring
* bump to monorepo
* renamed from artalk-go to artalk
* http origin checker
* abstract email service
* project package structure
* remove version two-way check ([#452](https://github.com/ArtalkJS/Artalk/issues/452))
* build scripts and CI tests
* replace pkger with go:embed
* launch with vscode debugger
* **CI:** one-key site creating with artalk integrated
* **CI:** improve build and release workflows ([#358](https://github.com/ArtalkJS/Artalk/issues/358))
* **captcha:** abstract captcha service ([#455](https://github.com/ArtalkJS/Artalk/issues/455))
* **comment:** separate comment ui renders from single file ([#427](https://github.com/ArtalkJS/Artalk/issues/427))
* **style:** convert to use Sass as a style interpreter ([#439](https://github.com/ArtalkJS/Artalk/issues/439))
* **ui:** automatic dependency injection ([#429](https://github.com/ArtalkJS/Artalk/issues/429))
* **ui/checker:** simplify checker lifecycle function param table ([#428](https://github.com/ArtalkJS/Artalk/issues/428))
* **ui/dark-mode:** separate dark mode logic into its own module ([#430](https://github.com/ArtalkJS/Artalk/issues/430))
* **ui/editor:** modify editor ui to standalone module ([#441](https://github.com/ArtalkJS/Artalk/issues/441))
* **ui/editor:** change functions of editor to standalone modules ([#443](https://github.com/ArtalkJS/Artalk/issues/443))
* **ui/height-limit:** modify height limit function to standalone module ([#435](https://github.com/ArtalkJS/Artalk/issues/435))
* **ui/i18n:** improve i18n function to standalone module ([#434](https://github.com/ArtalkJS/Artalk/issues/434))
* **ui/list:** modify list pagination to standalone module ([#437](https://github.com/ArtalkJS/Artalk/issues/437))
* **page/fetch:** remove goquery dependency when extracting page data ([#442](https://github.com/ArtalkJS/Artalk/issues/442))
* **anti_spam/qcloud-tms:** implement qcloud tms api without sdk ([#438](https://github.com/ArtalkJS/Artalk/issues/438))
### Documentation
* migrate ArtalkJS/Docs to monorepo docs
* add `CODE_OF_CONDUCT.md`
* add simplified README for artalk npm package
* add translation section to `CONTRIBUTING.md`
* fix wrong config value ([#371](https://github.com/ArtalkJS/Artalk/issues/371))
* fix broken links ([#364](https://github.com/ArtalkJS/Artalk/issues/364))
* add open api ([#360](https://github.com/ArtalkJS/Artalk/issues/360))
* add `Project Structure` section to `CONTRIBUTING.md`
* refine and add frontend api docs
* update setup-example-site.sh script usage
* init artalk with new frontend api
* **deploy:** add `restart=always` for docker to auto restart ([#425](https://github.com/ArtalkJS/Artalk/issues/425))
* **extras:** add deploy guide for vuepress ([#436](https://github.com/ArtalkJS/Artalk/issues/436))
+131
View File
@@ -0,0 +1,131 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or advances of
any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address,
without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at <artalkjs@gmail.com>.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
+298
View File
@@ -0,0 +1,298 @@
# Developer Contributing Guide
This guide helps developers understand how to contribute code, documentation, tests, and feedback to the Artalk project. We welcome all forms of contributions, whether it's large feature development, small fixes, documentation improvements, or testing. We believe that every contribution is an important part of moving the project forward.
This guide is available in multiple languages: [English](https://github.com/ArtalkJS/Artalk/blob/master/CONTRIBUTING.md) • [简体中文](https://artalk.js.org/develop/contributing.html)
## Setup
Clone the repository:
```sh
git clone https://github.com/ArtalkJS/Artalk.git
```
It's recommended to fork the repository first, and then clone the forked repository.
Navigate to the directory:
```sh
cd Artalk
```
## Development Environment
To develop Artalk, both frontend and backend, install the following tools:
- [Node.js](https://nodejs.org/en/) (>= 20.17.0)
- [PNPM](https://pnpm.io/) (>= 9.9.0)
- [Go](https://golang.org/) (>= 1.22)
- [Docker](https://www.docker.com/) (>= 20.10.0) (optional)
- [Docker Compose](https://docs.docker.com/compose/) (>= 1.29.0) (optional)
## Development Workflow Overview
The development workflow consists of the following steps:
1. **Set Up Complete Development Instance**:
- Navigate to the Artalk Repo directory.
- Execute `make dev` to run the backend on port `23366`.
- Execute `pnpm dev` to run the frontend on port `5173`.
- Optionally, execute `pnpm dev:sidebar` to run the sidebar frontend on port `23367`.
2. **Access Frontend for Development**:
- Open your browser and go to `http://localhost:5173` to perform your development and testing.
3. **Testing**:
- Run the backend unit tests using `make test`.
- Run the ui unit tests using `pnpm test`.
- Run the ui E2E tests using `make test-frontend-e2e`.
4. **Building Frontend Code**:
- When you make changes to the frontend code, build the complete frontend program using `pnpm build:all`.
- The JavaScript and CSS code will be found in `ui/artalk/dist`.
- The frontend code is automatically deployed to NPM by GitHub Actions.
5. **Building Backend Code**:
- When you make changes to the backend code, note that the backend program embeds the frontend code.
- Before building the backend, run `make build-frontend` (which runs `scripts/build-frontend.sh`). This will place the embedded frontend main program and sidebar frontend program in `/public`.
- Then, build the backend program using `make build`.
More exploration:
- **Developing Artalk Plugins or Themes**:
Refer to the [Artalk Plugin Development Guide](https://artalk.js.org/develop/plugin.html).
- **Makefile**:
You can explore the process and commands in the `Makefile`.
- **Automated CI on GitHub**:
The automated CI pipeline on GitHub, located in the `.github/workflows` directory, builds the frontend, backend, and Docker images. It publishes Docker images to Docker Hub, handles npm package publishing, and creates GitHub Releases. And also testing the frontend and backend.
The following sections provide more detailed information on the development workflow.
## Project Structure
Artalk is a monorepo project, meaning all the source code resides in a single repository. Despite this, the frontend and backend are kept separate. The frontend part is located in the `./ui` directory.
### Directory Overview
- `bin/`: The compiled binary files. (This directory is ignored by git).
- `cmd/`: The source code for the command line tools.
- `conf/`: The sample configuration files.
- `data/`: The local data. (This directory is ignored by git).
- `docs/`: The documentation site source code.
- `i18n/`: The translation files.
- `local/`: The local files. (This directory is ignored by git).
- `internal/`: The Go source code for the internal packages.
- `public/`: The static files. Built frontend files will be copied here.
- `scripts/`: The scripts for development and building.
- `server/`: The Go source code for the backend.
- `ui/`: The UI source code for the frontend.
- `.github/`: The GitHub Actions workflows.
- `.vscode/`: The VSCode settings.
## Backend Development
### Run Backend
1. **Create Configuration File**:
- Copy `./conf/artalk.example.yml` to the root directory.
- Rename it to `artalk.yml`.
- Modify the file as needed.
2. **Start Backend Program**:
- Run `make dev` to start the backend on port `23366`.
- Access it via `http://localhost:23366`.
- It's recommended to keep the default port for testing.
- (Alternative) Use `ARGS="version" make dev` to pass startup parameters (default is `ARGS="server"`).
The `make dev` builds the backend with debugging symbols, which is convenient for debugging with GDB.
If you are using the VSCode, you can use the `F5` key (or RUN button) to start debugging the backend program directly.
### Build Backend
1. **Fetch Latest Git Tag**:
Execute `git fetch --tags` to get the latest git tag information. This tag will be used as the version number of the backend app. Alternatively, specify it using environment variables: `VERSION="v1.0.0"` and `COMMIT_HASH="66128e"`.
2. **Build Frontend**:
Run `make build-fronted` to build the frontend, as the backend app embeds the frontend code.
3. **Build Backend**:
Execute `make build` to build the backend program.
The built binary file will be located in the `./bin` directory.
## Frontend Development (UI)
### Run Frontend
1. **Install Dependencies**:
Run `pnpm install` to install all necessary dependencies.
2. **Start Development Server**:
Execute `pnpm dev --port 5173` to start the frontend development server.
3. **Access the Frontend**:
The frontend application will run on port `5173` by default. Access it in your browser at `http://localhost:5173`.
4. **Sidebar Development**:
To run the sidebar part of the frontend, use `pnpm dev:sidebar`.
The ports `5173` and `23367` are used for frontend development and testing. These ports are included in the `ATK_TRUSTED_DOMAINS` configuration of the backend program.
### Build Frontend
To build the frontend, run the following command:
```sh
make build-frontend
```
The compiled JavaScript and CSS files will be located in the `/public` directory, embedded into the backend program.
For more details, refer to the `scripts/build-frontend.sh` script.
## Docker Development
### Build Docker Image
To build the Docker image, run the following command:
```sh
docker build -t artalk:TAG .
```
Replace `TAG` with the desired tag name (e.g., `latest`).
### Skip Frontend Build
If you have already built the frontend outside the Docker container, you can skip the frontend build process inside the container to speed up the build. Use the following command:
```sh
docker build --build-arg SKIP_FRONTEND_BUILD=true -t artalk:latest .
```
For more details, refer to the `Dockerfile`.
## Testing
### Testing the Backend
To test the backend Go program, you can use the following commands:
- **Unit Testing**:
Run `make test` to execute unit tests. The results will be outputted in the terminal.
- **Test Coverage**:
Run `make test-coverage` to check the code test coverage.
- **HTML Coverage Report**:
Run `make test-coverage-html` to generate and browse the test coverage report in HTML format.
- **Run Specific Tests**:
To run specific tests, use the command with an environment variable:
```sh
TEST_PATHS="./server/..." make test
```
### Testing the Frontend
Frontend testing includes unit tests and end-to-end (E2E) tests.
- **Unit Testing**:
The unit tests for the frontend are conducted using Vitest. Run `pnpm test` to start the unit testing.
- **End-to-End Testing**:
E2E testing is conducted using Playwright. To start the E2E testing, run:
```sh
make test-frontend-e2e
```
### Continuous Integration for Testing
Both frontend and backend testing are automated and will be performed during Git pull requests and as part of the build process using CircleCI or GitHub Actions.
## Configurations
The template configuration files are located in the `/conf` directory, with templates annotated in multiple languages named in the format `artalk.example.[lang].yml` (e.g., `artalk.example.zh-CN.yml`). Artalk will parse these template configuration files to generate the settings interface, environment variable names, and documentation. To improve performance, some data will be cached during the program's runtime to eliminate parsing time.
In the `internal/config/config.go` file, there is a definition of the `Config` struct, which is used to parse the yml files into Go structs. This struct contains more precise type definitions. If you need to add, modify, or delete a configuration item, you must make changes to both the configuration file templates in `/conf` and the `Config` struct.
When you modify the configuration files, please run the following command to update the configuration data cache:
```sh
make update-conf
```
To update the environment variable documentation, you can run the command:
```sh
make update-conf-docs
```
## Documentations
The documentation consists of three parts, each associated with a specific package: **Guide documentation**, **Landing page**, and **Swagger API documentation**. Below is an organized summary of the relevant commands and their outputs for each package.
### Guide Documentation (`docs`)
- **Directory**: `docs/docs/guide`
- **Dev Command**: `pnpm -F docs dev:docs`
- **Build Command**: `pnpm -F docs build:docs`
- **Output Directory**: `docs/docs/.vitepress/dist`
### Landing Page (`docs-landing`)
- **Directory**: `docs/landing`
- **Dev Command**: `pnpm -F docs-landing dev:landing`
- **Build Command**: `pnpm -F docs-landing build:landing`
- **Output Directory**: `docs/landing/dist`
### Swagger API Documentation (`docs-swagger`)
- **Directory**: `docs/swagger`
- **Build Command**: `make update-swagger`
- **Output Directory**: `docs/swagger`
Swagger definitions are located in the backend code at `/server`. After modifying the Swagger definitions, running the build command will update the Swagger docs and generate HTTP client code at `/ui/artalk/src/api/v2.ts`.
### Combined Build
- **Command to Build All Packages**: `pnpm build:docs`
- **Combined Output Directory**: `docs/docs/.vitepress/dist`
This command builds and combines all three packages into a single directory, ready for publishing.
### Environment Variable Documentation
- **File**: `docs/docs/guide/env.md`
- **Command to Update**: `make update-conf-docs`
This command reads the configuration template file located in `/conf` to update the environment variable documentation. Run this command after modifying the configuration template file.
## Translation (i18n)
If you write new features or make fixes/refactoring, use the following command to incrementally generate the translation files by parsing the source code for `i18n.T` function calls:
```sh
make update-i18n
```
If you're not a programmer and would like to help improve the translation, you can edit the translation files directly in the `/i18n` directory and then submit a pull request.
## The End
Thank you for your patience in reading this and for your interest and support in Artalk. We understand that the success of an open-source project relies on the contributions of every developer. Whether through code, documentation, testing, or feedback, your participation is the driving force behind the project's continuous progress. We sincerely invite you to join us in improving and enhancing Artalk.
By collaborating, we can create a more robust and versatile platform that benefits the entire community. Your unique insights and expertise are invaluable, and together, we can achieve remarkable advancements. Whether you are a seasoned developer or just starting, there is always a place for your contributions in our project.
If you have any questions or need assistance, please feel free to ask in the issue section on our GitHub page: https://github.com/ArtalkJS/Artalk/issues. Thank you once again for your support, and we look forward to working with you.
+72
View File
@@ -0,0 +1,72 @@
### build Artalk
FROM golang:1.22.6-alpine3.20 AS builder
WORKDIR /source
# install tools
RUN set -ex \
&& apk add --no-cache make git gcc musl-dev bash
# download go deps
# (cache by separating the downloading of deps)
COPY go.mod go.sum ./
RUN go mod download
# copy source code
COPY . .
## build UI
ARG SKIP_UI_BUILD=false
# install ui build toolchain
RUN set -ex \
&& if [ "$SKIP_UI_BUILD" = "false" ]; then \
apk add --no-cache nodejs npm \
&& npm install -g pnpm@9.9.0 \
;fi
RUN set -ex \
&& if [ "$SKIP_UI_BUILD" = "false" ]; then \
make build-frontend \
;fi
## build App
ARG APP_VERSION=""
ARG APP_COMMIT_HASH=""
RUN set -ex \
&& if [[ ! -z "$APP_VERSION" ]]; then export VERSION=$APP_VERSION ;fi \
&& if [[ ! -z "$APP_COMMIT_HASH" ]]; then export COMMIT_HASH=$APP_COMMIT_HASH ;fi \
&& make build
### build final image
FROM alpine:3.20
# we set the timezone `Asia/Shanghai` by default, you can be modified
# by `docker build --build-arg="TZ=Other_Timezone ..."`
ARG TZ="Asia/Shanghai"
ENV TZ=${TZ}
COPY --from=builder /source/bin/artalk /artalk
RUN apk add --no-cache bash tzdata \
&& ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
&& echo ${TZ} > /etc/timezone
# move runner script to `/usr/bin/` and create alias
COPY scripts/docker-artalk-runner.sh /usr/bin/artalk
RUN chmod +x /usr/bin/artalk \
&& ln -s /usr/bin/artalk /usr/bin/artalk-go
VOLUME ["/data"]
COPY docker-entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# expose Artalk default port
EXPOSE 23366
CMD ["server", "--host", "0.0.0.0", "--port", "23366"]
+17 -161
View File
@@ -1,165 +1,21 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
The MIT License (MIT)
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Copyright (c) 2018-present, qwqcode and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+78
View File
@@ -0,0 +1,78 @@
PKG_NAME := github.com/ArtalkJS/Artalk
BIN_NAME := ./bin/artalk
VERSION ?= $(shell git describe --tags --abbrev=0 --match 'v*')
COMMIT_HASH ?= $(shell git rev-parse --short HEAD)
HAS_RICHGO := $(shell which richgo)
GOTEST ?= $(if $(HAS_RICHGO), richgo test, go test)
ARGS ?= server
all: install build
install:
go mod tidy
run: all
$(BIN_NAME) $(ARGS)
build:
go build \
-ldflags "-s -w -X $(PKG_NAME)/internal/config.Version=$(VERSION) \
-X $(PKG_NAME)/internal/config.CommitHash=$(COMMIT_HASH)" \
-o $(BIN_NAME) \
$(PKG_NAME)
build-frontend:
./scripts/build-frontend.sh
build-debug:
@echo "Building Artalk $(VERSION) for debugging..."
@go build \
-ldflags "-X $(PKG_NAME)/internal/config.Version=$(VERSION) \
-X $(PKG_NAME)/internal/config.CommitHash=$(COMMIT_HASH)" \
-gcflags "all=-N -l" \
-o $(BIN_NAME) \
$(PKG_NAME)
dev: build-debug
ATK_SITE_DEFAULT="ArtalkDocs" \
ATK_TRUSTED_DOMAINS="http://localhost:5173 http://localhost:23367" \
$(BIN_NAME) $(ARGS)
test:
$(GOTEST) -timeout 20m $(or $(TEST_PATHS), ./...)
test-coverage:
$(GOTEST) -cover $(or $(TEST_PATHS), ./...)
test-coverage-html:
$(GOTEST) -v -coverprofile=coverage.out $(or $(TEST_PATHS), ./...)
go tool cover -html=coverage.out
test-frontend-e2e:
./scripts/frontend-e2e-test.sh $(if $(REPORT), --show-report)
update-i18n:
go generate ./internal/i18n
update-conf:
go generate ./internal/config
update-conf-docs:
go run ./internal/config/meta/gen --format markdown --locale zh-CN -o ./docs/docs/guide/env.md
update-swagger:
go install github.com/swaggo/swag/cmd/swag@latest
swag init -g server/server.go --output ./docs/swagger --requiredByDefault
pnpm -r swagger:build-http-client
docker-build:
./scripts/docker-build.sh
docker-push:
./scripts/docker-build.sh --push
.PHONY: all install run build build-frontend build-debug dev \
test test-coverage test-coverage-html test-frontend-e2e \
update-i18n update-conf update-conf-docs update-swagger \
docker-build docker-push;
+84 -98
View File
@@ -1,134 +1,120 @@
<p align="center">
<img src="https://user-images.githubusercontent.com/22412567/137740516-d9e97af0-fb3b-4dab-b331-671a9a2a3a63.png" alt="Artalk" width="100%">
<img src="https://user-images.githubusercontent.com/22412567/171680920-6e74b77c-c565-487b-bff1-4f94976ecbe7.png" alt="Artalk" width="100%">
</p>
# Artalk
[![](https://img.shields.io/npm/v/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![](https://img.shields.io/npm/dt/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![](https://badgen.net/bundlephobia/minzip/artalk?style=flat-square)](https://bundlephobia.com/package/artalk)
[![CircleCI](https://circleci.com/gh/ArtalkJS/Artalk/tree/master.svg?style=svg)](https://circleci.com/gh/ArtalkJS/Artalk/tree/master)
[![npm version](https://img.shields.io/npm/v/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![npm downloads](https://img.shields.io/npm/dt/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![Docker Pulls](https://img.shields.io/docker/pulls/artalk/artalk-go?style=flat-square)](https://hub.docker.com/r/artalk/artalk-go)
[![Go Report Card](https://goreportcard.com/badge/github.com/ArtalkJS/Artalk?style=flat-square)](https://goreportcard.com/report/github.com/ArtalkJS/Artalk)
[![CircleCI](https://img.shields.io/circleci/build/gh/ArtalkJS/Artalk?style=flat-square)](https://circleci.com/gh/ArtalkJS/Artalk/tree/master)
[![Codecov](https://img.shields.io/codecov/c/gh/ArtalkJS/Artalk?style=flat-square)](https://codecov.io/gh/ArtalkJS/Artalk)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/artalk?style=flat-square)](https://bundlephobia.com/package/artalk)
> 🌌 A Self-hosted comment system
[中文](./README.md) • [Official Website](https://artalk.js.org) • [Latest Release](https://github.com/ArtalkJS/Artalk/releases) • [Changelog](https://github.com/ArtalkJS/Artalk/blob/master/CHANGELOG.md)
[简体中文](./README.md) / [Documentation](https://artalk.js.org) / [Releases](https://github.com/ArtalkJS/ArtalkGo/releases) / [ArtalkGo](https://github.com/ArtalkJS/ArtalkGo)
🌌 Artalk is a simple yet feature-rich commenting system that you can deploy out of the box and integrate into any blog, website, or web application.
---
- 🍃 Lightweight (~30kB)
- 👨‍👧‍👦 Secure (Self-hosted)
- 🐳 Easy to use (Very Easy)
- 🍱 Golang backend (Fast and Cross Platform)
- 🌊 TypeScript × Vanilla × Vite (No Dependencies)
- 🍃 Frontend ~40KB, pure Vanilla JS
- 🍱 Backend Golang, efficient lightweight cross-platform
- 🐳 One-click deployment via Docker, convenient and fast
- 🌈 Open-source program, self-hosted, privacy-first
## Features
- Sidebar: Multi-site centralized management
- Notification Center: Red badge alert / Mark as read
- Verification: User Verification Badge / Password access
- Moderation: Anti-spam detection / Captcha frequency limit
- Emoticons: Insert emoji / Quickly import presets
- Email Notify: Template customization / Send to multi-admin
- Site Isolation: Multi-site management / Admin assignment
- Page Management: Provide page title / Easy to look up
- Image Upload: Upload to localhost / various remote image host
- Private Space Mode: Only visible to yourself / Message board
- Multiple Msg Pushers: Support Telegram / Slack / LINE
- Nested Comments: Switchable to Flat Mode
- Comment Vote: For or against comments
- Comment Sort: Sort by popularity or time
- Comment PIN: Pin important comments
- Track only author: Show only author's comments
- Asynchronous: Send comments without waiting
- Infinite Scrolling: Provide various comment content pagination custom
- AutoSave: A anti-lost editor
- AutoFill: Autofill user profile
- Preview: Real-time preview of markdown
- Dark Mode: Prevents eye disease damage
- Collapse Comment: I do not want you to see this comment
- Data Backup: Prevent comment data loss
- Data Migration: Switch back and forth between different commenting systems
- Multiple comments on one page: Multiple comment areas on one page (seems useless
- Markdown: Markdown syntax was supported by default
- LaTex support: Import KaTex plugin to integrate LaTex parser for artalk
- Using [Vite](https://github.com/vitejs/vite): The ultimate developer experience
<!-- prettier-ignore-start -->
## Getting Started
<!-- features -->
* [Sidebar](https://artalk.js.org/guide/frontend/sidebar.html): Quick management, intuitive browsing
* [Social Login](https://artalk.js.org/guide/frontend/auth.html): Quick login via social accounts
* [Email Notification](https://artalk.js.org/guide/backend/email.html): Multiple sending methods, email templates
* [Multi-channel Push](https://artalk.js.org/guide/backend/admin_notify.html): Multiple push methods, notification templates
* [In-site Notifications](https://artalk.js.org/guide/frontend/sidebar.html): Red dot marking, mention list
* [CAPTCHA](https://artalk.js.org/guide/backend/captcha.html): Multiple verification types, frequency limitation
* [Comment Moderation](https://artalk.js.org/guide/backend/moderator.html): Content detection, spam interception
* [Image Upload](https://artalk.js.org/guide/backend/img-upload.html): Custom upload, support for image hosting
* [Markdown](https://artalk.js.org/guide/intro.html): Support Markdown syntax
* [Emoticons](https://artalk.js.org/guide/frontend/emoticons.html): Compatible with OwO, quick integration
* [Multi-site](https://artalk.js.org/guide/backend/multi-site.html): Site isolation, centralized management
* [Admin](https://artalk.js.org/guide/backend/multi-site.html): Password verification, badge identification
* [Page Management](https://artalk.js.org/guide/frontend/sidebar.html): Quick view, one-click title jump
* [Page Views Statistics](https://artalk.js.org/guide/frontend/pv.html): Easily track page views
* [Hierarchy](https://artalk.js.org/guide/frontend/config.html#nestmax): Nested paginated lists, scroll loading
* [Comment Voting](https://artalk.js.org/guide/frontend/config.html#vote): Upvote or downvote comments
* [Comment Sorting](https://artalk.js.org/guide/frontend/config.html#listsort): Multiple sorting options, freedom to choose
* [Comment Search](https://artalk.js.org/guide/frontend/sidebar.html): Quickly search comment content
* [Comment Pinning](https://artalk.js.org/guide/frontend/sidebar.html): Pin important messages
* [Author-only View](https://artalk.js.org/guide/frontend/config.html): Show only comments from the author
* [Comment Jumping](https://artalk.js.org/guide/intro.html): Quickly jump to referenced comments
* [Auto Save](https://artalk.js.org/guide/frontend/config.html): Content input auto-saving
* [IP Geolocation](https://artalk.js.org/guide/frontend/ip-region.html): User IP location display
* [Data Migration](https://artalk.js.org/guide/transfer.html): Free migration, quick backup
* [Image Lightbox](https://artalk.js.org/guide/frontend/lightbox.html): Quickly integrate image lightbox
* [Image Lazy Loading](https://artalk.js.org/guide/frontend/img-lazy-load.html): Delay loading images, optimize experience
* [Latex](https://artalk.js.org/guide/frontend/latex.html): Latex formula parsing integration
* [Dark Mode](https://artalk.js.org/guide/frontend/config.html#darkmode): Dark mode switching
* [Extension Plugins](https://artalk.js.org/develop/): Create more possibilities
* [Multi-language](https://artalk.js.org/guide/frontend/i18n.html): Multi-language switching
* [Command Line](https://artalk.js.org/guide/backend/config.html): Command line operation management capability
* [API Documentation](https://artalk.js.org/develop/): Provides OpenAPI format documentation
* [Program Upgrade](https://artalk.js.org/guide/backend/update.html): Version detection, one-click upgrade
<!-- /features -->
Reference to:[**Documentation**](https://artalk.js.org/guide/deploy.html)
<!-- prettier-ignore-end -->
```sh
$ pnpm add artalk
## Installation
Deploy via Docker with one click:
```bash
docker run -d \
--name artalk \
-p 8080:23366 \
-v $(pwd)/data:/data \
-e "TZ=America/New_York" \
-e "ATK_LOCALE=en" \
-e "ATK_SITE_DEFAULT=Artalk Blog" \
-e "ATK_SITE_URL=https://example.com" \
artalk/artalk-go
```
```ts
import Artalk from 'artalk'
Integrate Artalk into your webpage:
new Artalk({
el: '#Comments',
pageKey: 'http://your_domain/post/1', // Page Link
pageTitle: 'The title of your page', // Page Title
server: 'http://localhost:8080/api', // Server URL
site: 'Site Name',
i18n: 'en-US'
<!-- prettier-ignore-start -->
```ts
Artalk.init({
el: '#Comments',
site: 'Artalk Blog',
server: 'https://artalk.example.com',
pageKey: '/2018/10/02/hello-world.html'
})
```
### Docker
<!-- prettier-ignore-end -->
```sh
# Create a directory for Artalk
mkdir Artalk
cd Artalk
[**Learn More →**](https://artalk.js.org/guide/deploy.html)
# Download config template
curl -L https://raw.githubusercontent.com/ArtalkJS/ArtalkGo/master/artalk-go.example.yml > conf.yml
## For Developers
docker run -d \
--name artalk \
-p 0.0.0.0:8080:23366 \
-v $(pwd)/conf.yml:/conf.yml \
-v $(pwd)/data:/data \
artalk/artalk-go
```
Pull requests are welcome!
### Docker Compose
```sh
mkdir Artalk
cd Artalk
vim docker-compose.yaml
```
```yaml
version: "3.5"
services:
artalk:
container_name: artalk
image: artalk/artalk-go
ports:
- 8080:23366
volumes:
- ./conf.yml:/conf.yml
- ./data:/data
```
```sh
docker-compose up -d
```
See [Development](https://artalk.js.org/develop/) and [Contributing](./CONTRIBUTING.md) for information on working with the codebase, getting a local development setup, and contributing changes.
## Contributors
Your contributions enrich the open-source community, fostering learning, inspiration, and innovation. We deeply value your involvement. Thank you for being a vital part of our community! 🥰
[![](https://contrib.rocks/image?repo=ArtalkJS/Artalk)](https://github.com/ArtalkJS/Artalk/graphs/contributors)
## Supporters
[![Stargazers repo roster for @ArtalkJS/Artalk](https://reporoster.com/stars/ArtalkJS/Artalk)](https://github.com/ArtalkJS/Artalk/stargazers)
## Feedback
## Repobeats Analytics
Thanks for the help and feedback provided by the community, if you have good suggestions or comments, please go to [issues](https://github.com/ArtalkJS/Artalk/issues) to let us know at any time.
![Alt](https://repobeats.axiom.co/api/embed/a9fc9191ac561bc5a8ee2cddc81e635ecaebafb6.svg 'Repobeats analytics image')
## Stargazers over time
@@ -136,7 +122,7 @@ Thanks for the help and feedback provided by the community, if you have good sug
## License
[LGPL-3.0](./LICENSE)
[MIT](./LICENSE)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalk.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalk?ref=badge_shield)
+82 -169
View File
@@ -4,100 +4,108 @@
# Artalk
[![](https://img.shields.io/npm/v/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![](https://img.shields.io/npm/dt/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![](https://badgen.net/bundlephobia/minzip/artalk?style=flat-square)](https://bundlephobia.com/package/artalk)
[![CircleCI](https://circleci.com/gh/ArtalkJS/Artalk/tree/master.svg?style=svg)](https://circleci.com/gh/ArtalkJS/Artalk/tree/master)
[![npm version](https://img.shields.io/npm/v/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![npm downloads](https://img.shields.io/npm/dt/artalk.svg?style=flat-square)](https://www.npmjs.com/package/artalk)
[![Docker Pulls](https://img.shields.io/docker/pulls/artalk/artalk-go?style=flat-square)](https://hub.docker.com/r/artalk/artalk-go)
[![Go Report Card](https://goreportcard.com/badge/github.com/ArtalkJS/Artalk?style=flat-square)](https://goreportcard.com/report/github.com/ArtalkJS/Artalk)
[![CircleCI](https://img.shields.io/circleci/build/gh/ArtalkJS/Artalk?style=flat-square)](https://circleci.com/gh/ArtalkJS/Artalk/tree/master)
[![Codecov](https://img.shields.io/codecov/c/gh/ArtalkJS/Artalk?style=flat-square)](https://codecov.io/gh/ArtalkJS/Artalk)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/artalk?style=flat-square)](https://bundlephobia.com/package/artalk)
> 🌌 Golang 自托管评论系统
[English](./README.en.md) • [官方网站](https://artalk.js.org) • [最新版本](https://github.com/ArtalkJS/Artalk/releases) • [更新日志](https://github.com/ArtalkJS/Artalk/blob/master/CHANGELOG.md)
[English](./README.en.md) / [官方文档](https://artalk.js.org) / [最新后端](https://github.com/ArtalkJS/ArtalkGo/releases) / [ArtalkGo](https://github.com/ArtalkJS/ArtalkGo)
Artalk 是一款简单易用但功能丰富的评论系统,你可以开箱即用地部署并置入任何博客、网站、Web 应用。
---
- 🍃 轻量 (~30kB)
- 👨‍👧‍👦 安全 (自托管)
- 🐳 易上手 (防脱发)
- 🍱 Golang 后端 (快速 / 跨平台)
- 🌊 Vanilla x TypeScript × Vite (纯天然 / 无依赖)
- 🍃 前端 ~40KB,纯天然 Vanilla JS
- 🍱 后端 Golang,高效轻量跨平台
- 🐳 通过 Docker 一键部署,方便快捷
- 🌈 开源程序,自托管,隐私至上
## 特性
- 侧 边 栏 :支持多站点集中化管理
- 通知中心:红点的标记 / 提及列表
- 身份验证:徽标自定义 / 密码验证
- 评论审核:反垃圾检测 / 频率限制
- 表情符号:插入表情包 / 快速导入
- 邮件提醒:模版自定义 / 多管理员
- 站点隔离:管理员分配 / 多个站点
- 页面管理:标题可显示 / 快速跳转
- 图片上传:上传到本地 / 多种图床
- 多元推送:支持 钉钉 飞书 TG
- 无限层级:可切换为平铺模式
- 评论投票:赞同还是反对评论
- 评论排序:按热度或时间排序
- 评论置顶:重要消息置顶显示
- 只看作者:仅显示作者的评论
- 说说模式:仅自己可发布评论
- 异步处理:发送评论无需等待
- 滚动加载:评论内容分页处置
- 自动保存:用户输入防丢功能
- 自动填充:用户链接自动填充
- 实时预览:评论内容实时预览
- 暗黑模式:防止眼部疾病伤害
- 评论折叠:这个不打算给你康
- 数据备份:防止评论数据丢失
- 数据迁移:快速切换评论系统
- Markdown:默认支持 MD 语法
- 支持 Latex:提供集成 Katex 插件
- 使用 [Vite](https://github.com/vitejs/vite):属于开发者的极致体验
<!-- prettier-ignore-start -->
## 食用方针
<!-- features -->
* [侧边栏](https://artalk.js.org/guide/frontend/sidebar.html): 快速管理、直观浏览
* [社交登录](https://artalk.js.org/guide/frontend/auth.html): 通过社交账号快速登录
* [邮件通知](https://artalk.js.org/guide/backend/email.html): 多种发送方式、邮件模板
* [多元推送](https://artalk.js.org/guide/backend/admin_notify.html): 多种推送方式、通知模版
* [站内通知](https://artalk.js.org/guide/frontend/sidebar.html): 红点标记、提及列表
* [验证码](https://artalk.js.org/guide/backend/captcha.html): 多种验证类型、频率限制
* [评论审核](https://artalk.js.org/guide/backend/moderator.html): 内容检测、垃圾拦截
* [图片上传](https://artalk.js.org/guide/backend/img-upload.html): 自定义上传、支持图床
* [Markdown](https://artalk.js.org/guide/intro.html): 支持 Markdown 语法
* [表情包](https://artalk.js.org/guide/frontend/emoticons.html): 兼容 OwO,快速集成
* [多站点](https://artalk.js.org/guide/backend/multi-site.html): 站点隔离、集中管理
* [管理员](https://artalk.js.org/guide/backend/multi-site.html): 密码验证、徽章标识
* [页面管理](https://artalk.js.org/guide/frontend/sidebar.html): 快速查看、标题一键跳转
* [浏览量统计](https://artalk.js.org/guide/frontend/pv.html): 轻松统计网页浏览量
* [层级结构](https://artalk.js.org/guide/frontend/config.html#nestmax): 嵌套分页列表、滚动加载
* [评论投票](https://artalk.js.org/guide/frontend/config.html#vote): 赞同或反对评论
* [评论排序](https://artalk.js.org/guide/frontend/config.html#listsort): 多种排序方式,自由选择
* [评论搜索](https://artalk.js.org/guide/frontend/sidebar.html): 快速搜索评论内容
* [评论置顶](https://artalk.js.org/guide/frontend/sidebar.html): 重要消息置顶显示
* [仅看作者](https://artalk.js.org/guide/frontend/config.html): 仅显示作者的评论
* [评论跳转](https://artalk.js.org/guide/intro.html): 快速跳转到引用的评论
* [自动保存](https://artalk.js.org/guide/frontend/config.html): 输入内容防丢功能
* [IP 属地](https://artalk.js.org/guide/frontend/ip-region.html): 用户 IP 属地展示
* [数据迁移](https://artalk.js.org/guide/transfer.html): 自由迁移、快速备份
* [图片灯箱](https://artalk.js.org/guide/frontend/lightbox.html): 图片灯箱快速集成
* [图片懒加载](https://artalk.js.org/guide/frontend/img-lazy-load.html): 延迟加载图片,优化体验
* [Latex](https://artalk.js.org/guide/frontend/latex.html): Latex 公式解析集成
* [夜间模式](https://artalk.js.org/guide/frontend/config.html#darkmode): 夜间模式切换
* [扩展插件](https://artalk.js.org/develop/): 创造更多可能性
* [多语言](https://artalk.js.org/guide/frontend/i18n.html): 多国语言切换
* [命令行](https://artalk.js.org/guide/backend/config.html): 命令行操作管理能力
* [API 文档](https://artalk.js.org/develop/): 提供 OpenAPI 格式文档
* [程序升级](https://artalk.js.org/guide/backend/update.html): 版本检测,一键升级
<!-- /features -->
前往:[“**部署文档**”](https://artalk.js.org/guide/deploy.html)
<!-- prettier-ignore-end -->
```ts
new Artalk({
el: '#Comments',
site: 'Artalk 的博客',
server: 'https://artalk.example.com'
})
```
## 安装
### Docker
通过 Docker 一键部署:
```bash
docker run -d \
--name artalk-go \
-p 8080:23366 \
-v $(pwd)/data:/data \
artalk/artalk-go
--name artalk \
-p 8080:23366 \
-v $(pwd)/data:/data \
-e "TZ=Asia/Shanghai" \
-e "ATK_LOCALE=zh-CN" \
-e "ATK_SITE_DEFAULT=Artalk 的博客" \
-e "ATK_SITE_URL=https://example.com" \
artalk/artalk-go
```
### Docker Compose
在网页中引入 Artalk:
```bash
vim docker-compose.yaml
<!-- prettier-ignore-start -->
```ts
Artalk.init({
el: '#Comments',
site: 'Artalk 的博客',
server: 'https://artalk.example.com',
pageKey: '/2018/10/02/hello-world.html'
})
```
```yaml
version: "3.5"
services:
artalk:
container_name: artalk
image: artalk/artalk-go
ports:
- 8080:23366
volumes:
- ./data:/data
```
<!-- prettier-ignore-end -->
```bash
docker-compose up -d
```
[**了解更多 →**](https://artalk.js.org/guide/deploy.html)
## For Developers
Pull requests are welcome!
See [Development](https://artalk.js.org/develop/) and [Contributing](./CONTRIBUTING.md) for information on working with the codebase, getting a local development setup, and contributing changes.
## Contributors
Your contributions enrich the open-source community, fostering learning, inspiration, and innovation. We deeply value your involvement. Thank you for being a vital part of our community! 🥰
[![](https://contrib.rocks/image?repo=ArtalkJS/Artalk)](https://github.com/ArtalkJS/Artalk/graphs/contributors)
## Supporters
@@ -106,102 +114,7 @@ docker-compose up -d
## Repobeats Analytics
![Alt](https://repobeats.axiom.co/api/embed/a9fc9191ac561bc5a8ee2cddc81e635ecaebafb6.svg "Repobeats analytics image")
## 特别致谢
感谢社区提供的帮助与反馈,若有好的建议与意见欢迎前往 [ISSUES](https://github.com/ArtalkJS/Artalk/issues) 随时告知。
## TODOs
- [x] [Golang 后端](https://github.com/ArtalkJS/ArtalkGo)
- [x] 多数据库支持
- [x] SQLite
- [x] MySQL
- [x] Postgres
- [x] SQLServer
- [x] 多缓存数据库支持
- [x] In-memory (内建缓存)
- [x] Redis
- [x] Memcache
- [x] 多站点支持
- [x] 评论获取分页
- [x] 评论点赞投票
- [x] 浏览量统计
- [x] 评论分页加载
- [x] 评论置顶 / 精华
- [x] 评论排序 (热度 / 时间)
- [x] 通知中心
- [x] 提及
- [x] 全部
- [x] 我的
- [x] 待审
- [x] 管理员控制台
- [x] 评论
- [x] 页面
- [x] 站点
- [x] 用户
- [x] 设置 (GUI)
- [x] 数据导入 ([Artransfer](https://artalk.js.org/guide/transfer.html))
- [x] Artrans
- [x] WordPress
- [x] Typecho ([插件](https://github.com/ArtalkJS/Artrans-Typecho) / [Artransfer-CLI](https://github.com/ArtalkJS/Artransfer-CLI))
- [x] Valine
- [x] Disqus
- [x] Commento
- [x] Waline ([Artransfer-CLI](https://github.com/ArtalkJS/Artransfer-CLI))
- [x] Twikoo
- [x] Artalk v1 (PHP)
- [x] 数据导出
- [x] 邮件多种发送方式
- [x] SMTP
- [x] 阿里云邮件
- [x] 系统调用 sendmail
- [x] 邮件多模板自定义
- [x] 邮件异步队列发送
- [ ] 队列持久化
- [x] 用户已读标记
- [x] 验证码
- [x] 图片验证码
- [x] [极验](https://www.geetest.com/)滑动验证码
- [x] 反垃圾
- [x] [Akismet](https://akismet.com/)
- [x] [阿里云内容安全](https://help.aliyun.com/document_detail/28417.html)
- [x] [腾讯云内容安全](https://cloud.tencent.com/document/product/1124/64508)
- [x] 关键字过滤
- [x] 评论通知管理员 ([notify](https://github.com/nikoksr/notify))
- [x] Telegram Bot
- [x] 飞书 WebHook Bot
- [x] 钉钉
- [x] Bark
- [x] Slack
- [x] LINE
- [x] 自定义 HTTP 回调
- [ ] 命令行管理
- [ ] 博客邮件订阅
- [x] 用户鉴权机制
- [x] 跨域非法请求阻止
- [x] 全局验证码操作次数限制
- [x] JWT 登陆状态验证
- [x] 时区自定义
- [x] 只看作者功能
- [x] 图片上传
- [x] 图片上传到图床 ([upgit](https://github.com/pluveto/upgit))
- [ ] 图片管理
- [ ] 附件上传 / 管理
- [ ] 表情包统一管理
- [ ] 导入表情包
- [ ] 表情包图片地址控制
- [ ] AT 提及 (@)
- [ ] 评论话题 (#)
- [ ] 评论标签分类系统
- [ ] 主题样式更换
- [ ] 规范化 API
- [ ] 扩展中心
- [ ] 开放用户注册
- [ ] 第三方登录接入
- [x] 多语言 / 国际化 (i18n)
- [x] 一键升级
![Alt](https://repobeats.axiom.co/api/embed/a9fc9191ac561bc5a8ee2cddc81e635ecaebafb6.svg 'Repobeats analytics image')
## Stargazers over time
@@ -209,7 +122,7 @@ docker-compose up -d
## License
[LGPL-3.0](./LICENSE)
[MIT](./LICENSE)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FArtalkJS%2FArtalk.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FArtalkJS%2FArtalk?ref=badge_shield)
+3
View File
@@ -0,0 +1,3 @@
# Reporting Security Issues
The features of Artalk are continuously being improved, and we are also striving to enhance security. However, potential issues may still exist. If you discover any security vulnerabilities in Artalk, please promptly contact us via [GitHub Issues](https://github.com/ArtalkJS/Artalk/issues) or email at artalkjs@gmail.com. We will make every effort to address the issue as quickly as possible. Thank you for your support!
+122
View File
@@ -0,0 +1,122 @@
package cmd
import (
"bufio"
"fmt"
"os"
"strings"
"syscall"
"github.com/ArtalkJS/Artalk/internal/entity"
"github.com/ArtalkJS/Artalk/internal/i18n"
"github.com/ArtalkJS/Artalk/internal/log"
"github.com/ArtalkJS/Artalk/internal/utils"
"github.com/spf13/cobra"
"golang.org/x/term"
)
func NewAdminCommand(app *ArtalkCmd) *cobra.Command {
adminCmd := &cobra.Command{
Use: "admin",
Short: "Create or edit an administrator account",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("--------------------------------")
fmt.Println(" " + i18n.T("Create admin account"))
fmt.Println("--------------------------------")
// get from flags
username, _ := cmd.Flags().GetString("name")
email, _ := cmd.Flags().GetString("email")
password, _ := cmd.Flags().GetString("password")
if username == "" || email == "" || password == "" {
var err error
username, email, password, err = credentials()
if err != nil {
log.Fatal(err)
}
}
findUser := app.Dao().FindUser(username, email)
if !findUser.IsEmpty() {
findUser.SetPasswordEncrypt(password)
findUser.IsAdmin = true
if err := app.Dao().UpdateUser(&findUser); err != nil {
log.Fatal(err)
}
log.Info(i18n.T("{{name}} already exists", map[string]interface{}{"name": i18n.T("Account")}) +
", " + i18n.T("Password updated"))
return
}
user := entity.User{
Name: username,
Email: email,
IsAdmin: true,
BadgeName: i18n.T("Admin"),
BadgeColor: "#0083FF",
}
user.SetPasswordEncrypt(password)
if err := app.Dao().CreateUser(&user); err != nil {
log.Fatal(err)
}
fmt.Println("--------------------------------")
fmt.Println(" Name: " + username)
fmt.Println(" Mail: " + email)
fmt.Println("--------------------------------")
},
}
flag(adminCmd, "name", "", i18n.T("Username"))
flag(adminCmd, "email", "", i18n.T("Email"))
flag(adminCmd, "password", "", i18n.T("Password"))
return adminCmd
}
func credentials() (string, string, string, error) {
reader := bufio.NewReader(os.Stdin)
fmt.Print(i18n.T("Enter {{name}}", map[string]interface{}{"name": i18n.T("Username")}) + ": ")
username, err := reader.ReadString('\n')
if err != nil {
return "", "", "", err
}
fmt.Print(i18n.T("Enter {{name}}", map[string]interface{}{"name": i18n.T("Email")}) + ": ")
email, err := reader.ReadString('\n')
if err != nil {
return "", "", "", err
}
if !utils.ValidateEmail(strings.TrimSpace(email)) {
return "", "", "", fmt.Errorf("invalid email format")
}
fmt.Print(i18n.T("Enter {{name}}", map[string]interface{}{"name": i18n.T("Password")}) + ": ")
bytePassword, err := term.ReadPassword(int(syscall.Stdin))
if err != nil {
return "", "", "", err
}
fmt.Println()
fmt.Print(i18n.T("Retype {{name}}", map[string]interface{}{"name": i18n.T("Password")}) + ": ")
byteRePassword, err := term.ReadPassword(int(syscall.Stdin))
if err != nil {
return "", "", "", err
}
fmt.Println()
password := strings.TrimSpace(string(bytePassword))
rePassword := strings.TrimSpace(string(byteRePassword))
if rePassword != password {
return "", "", "", fmt.Errorf("inconsistent password input")
}
return strings.TrimSpace(username), strings.TrimSpace(email), password, nil
}
+223
View File
@@ -0,0 +1,223 @@
package cmd
import (
"fmt"
"os"
"os/signal"
"syscall"
"github.com/ArtalkJS/Artalk/internal/config"
"github.com/ArtalkJS/Artalk/internal/core"
"github.com/ArtalkJS/Artalk/internal/log"
"github.com/fatih/color"
"github.com/spf13/cobra"
)
var Version = config.Version + `/` + config.CommitHash
var Banner = `
________ ________ _________ ________ ___ ___ __
|\ __ \|\ __ \|\___ ___\\ __ \|\ \ |\ \|\ \
\ \ \|\ \ \ \|\ \|___ \ \_\ \ \|\ \ \ \ \ \ \/ /|_
\ \ __ \ \ _ _\ \ \ \ \ \ __ \ \ \ \ \ ___ \
\ \ \ \ \ \ \\ \| \ \ \ \ \ \ \ \ \ \____\ \ \\ \ \
\ \__\ \__\ \__\\ _\ \ \__\ \ \__\ \__\ \_______\ \__\\ \__\
\|__|\|__|\|__|\|__| \|__| \|__|\|__|\|_______|\|__| \|__|
Artalk (` + Version + `)
-> A Self-hosted Comment System.
-> https://artalk.js.org
`
type ArtalkCmd struct {
*core.App
cfgFile string
workDir string
RootCmd *cobra.Command
}
const BootModeKey = "BootMode"
const (
MODE_FULL_BOOT = "FULL_BOOT"
MODE_MINI_BOOT = "MINI_BOOT"
)
func New() *ArtalkCmd {
cmd := &ArtalkCmd{
RootCmd: &cobra.Command{
Use: "artalk",
Short: "Artalk: A self-hosted comment system",
Long: Banner,
Version: Version,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(Banner)
fmt.Print("-------------------------------\n\n")
fmt.Println("NOTE: add `-h` flag to show help about any command.")
},
},
}
cmd.RootCmd.SetVersionTemplate("Artalk ({{printf \"%s\" .Version}})\n")
// Parse base flags
cmd.eagerParseFlags()
// Change work directory
if cmd.workDir != "" {
if err := os.Chdir(cmd.workDir); err != nil {
log.Fatal("Working directory change error: ", err)
}
}
return cmd
}
// Parses the global app flags before calling atk.RootCmd.Execute().
// so we can have all flags ready for use on initialization.
func (atk *ArtalkCmd) eagerParseFlags() error {
atk.RootCmd.PersistentFlags().StringVarP(&atk.cfgFile, "config", "c", "", "config file path (defaults are './artalk.yml')")
atk.RootCmd.PersistentFlags().StringVarP(&atk.workDir, "workdir", "w", "", "program working directory (defaults are './')")
return atk.RootCmd.ParseFlags(os.Args[1:])
}
func (atk *ArtalkCmd) addCommand(cmd *cobra.Command) {
originalPreRunFunc := cmd.PreRun
cmd.PreRun = func(cmd *cobra.Command, args []string) {
// ================
// APP Bootstrap
// ================
if cmd.Annotations[BootModeKey] != string(MODE_MINI_BOOT) {
// Load config
config, err := getConfig(atk.cfgFile)
if err != nil {
log.Fatal("Config fail: ", err)
}
// Create new instance
atk.App = core.NewApp(config)
// Bootstrap APP
if err := atk.App.Bootstrap(); err != nil {
panic(err)
}
}
if originalPreRunFunc != nil {
originalPreRunFunc(cmd, args) // extends original pre-run logic
}
}
atk.RootCmd.AddCommand(cmd)
}
func (atk *ArtalkCmd) mountCommands() {
atk.addCommand(NewServeCommand(atk))
atk.addCommand(NewAdminCommand(atk))
atk.addCommand(NewExportCommand(atk))
atk.addCommand(NewImportCommand(atk))
atk.addCommand(NewConfigCommand())
atk.addCommand(NewGenCommand())
atk.addCommand(NewUpgradeCommand())
atk.addCommand(NewVersionCommand())
}
func (atk *ArtalkCmd) Launch() error {
// ===================
// 1. Prepare Commands
// ===================
atk.mountCommands()
done := make(chan bool, 1) // shutdown signal
// listen for interrupt signal to gracefully shutdown the application
go func() {
sigch := make(chan os.Signal, 1)
signal.Notify(sigch, os.Interrupt, syscall.SIGTERM)
<-sigch
done <- true
}()
// ===================
// 2. Command Execute
// ===================
go func() {
if err := atk.RootCmd.Execute(); err != nil {
color.Red(err.Error())
}
done <- true
}()
<-done
// ===================
// 3. App Cleanups
// ===================
if atk.App != nil {
return atk.App.OnTerminate().Trigger(&core.TerminateEvent{
App: atk.App,
})
}
return nil
}
// Create new config instance by specific config filename
func getConfig(cfgFile string) (*config.Config, error) {
// Retrieve config file by default names when specific filename is empty
if cfgFile == "" {
cfgFile = config.RetrieveConfigFile()
}
// Generate new config file when retrieve failed
if cfgFile == "" {
cfgFile = config.CONF_DEFAULT_FILENAMES[0]
core.Gen("config", cfgFile, false)
}
// Create new config instance and return
return config.NewFromFile(cfgFile)
}
// -------------------------------------------------------------------
// Shortcut Functions
// -------------------------------------------------------------------
func flag(cmd *cobra.Command, name string, defaultVal interface{}, usage string) {
f := cmd.PersistentFlags()
switch y := defaultVal.(type) {
case bool:
f.Bool(name, y, usage)
case int:
f.Int(name, y, usage)
case string:
f.String(name, y, usage)
}
}
func flagP(cmd *cobra.Command, name, shorthand string, defaultVal interface{}, usage string) {
f := cmd.PersistentFlags()
switch y := defaultVal.(type) {
case bool:
f.BoolP(name, shorthand, y, usage)
case int:
f.IntP(name, shorthand, y, usage)
case string:
f.StringP(name, shorthand, y, usage)
}
}
func flagV(cmd *cobra.Command, name string, defaultVal interface{}, usage string) {
flag(cmd, name, defaultVal, usage)
}
func flagPV(cmd *cobra.Command, name, shorthand string, defaultVal interface{}, usage string) {
flagP(cmd, name, shorthand, defaultVal, usage)
}
+35
View File
@@ -0,0 +1,35 @@
package cmd
import (
"encoding/json"
"fmt"
"github.com/ArtalkJS/Artalk/internal/log"
"github.com/spf13/cobra"
)
func NewConfigCommand() *cobra.Command {
configCmd := &cobra.Command{
Use: "config",
Short: "Output Config Information",
Run: func(cmd *cobra.Command, args []string) {
// Get config filename from cmd flags
filename, _ := cmd.Flags().GetString("config")
// Get new config instance
config, err := getConfig(filename)
if err != nil {
log.Fatal("Config fail: ", err)
}
// Output JSON of config
buf, _ := json.MarshalIndent(config, "", " ")
fmt.Println(string(buf))
},
Annotations: map[string]string{
BootModeKey: MODE_MINI_BOOT,
},
}
return configCmd
}
+72
View File
@@ -0,0 +1,72 @@
package cmd
import (
"fmt"
"os"
"path"
"path/filepath"
"time"
"github.com/ArtalkJS/Artalk/internal/artransfer"
"github.com/ArtalkJS/Artalk/internal/i18n"
"github.com/ArtalkJS/Artalk/internal/log"
"github.com/ArtalkJS/Artalk/internal/utils"
"github.com/spf13/cobra"
)
func NewExportCommand(app *ArtalkCmd) *cobra.Command {
exportCmd := &cobra.Command{
Use: "export",
Aliases: []string{},
Short: "Artransfer export",
Long: "\n# Artransfer - Export\n\n See the documentation to learn more: https://artalk.js.org/guide/transfer.html",
Run: func(cmd *cobra.Command, args []string) {
jsonStr, err := artransfer.RunExportArtrans(app.Dao(), &artransfer.ExportParams{})
if err != nil {
log.Fatal(err)
}
if len(args) < 1 || args[0] == "" {
// write to stdout
fmt.Println(jsonStr)
} else {
filename := args[0]
// make sure is abs path
filename, err := filepath.Abs(filename)
if err != nil {
log.Fatal(err)
}
// check dir
stat, err := os.Stat(filename)
if err == nil {
if stat.IsDir() {
filename = path.Join(filename, "backup-"+time.Now().Format("20060102-150405")+".artrans")
}
}
// mkdir -p
if err := utils.EnsureDir(filepath.Dir(filename)); err != nil {
log.Fatal(err)
}
// touch
f, err := os.Create(filename)
if err != nil {
log.Fatal(err)
}
// >
_, err2 := f.WriteString(jsonStr)
if err2 != nil {
log.Fatal(err2)
}
log.Info(i18n.T("Export complete") + ": " + filename)
}
},
}
return exportCmd
}
+34
View File
@@ -0,0 +1,34 @@
package cmd
import (
"github.com/ArtalkJS/Artalk/internal/core"
"github.com/spf13/cobra"
)
func NewGenCommand() *cobra.Command {
genCmd := &cobra.Command{
Use: "gen <TYPE> <DEST>",
Short: "A collection of several useful generators",
Long: "Generate some content\ne.g. `artalk gen config ./artalk.yml`",
Args: cobra.RangeArgs(1, 2),
Run: func(cmd *cobra.Command, args []string) {
var (
specificPath string
isForce bool
)
if len(args) > 1 {
specificPath = args[1]
}
isForce, _ = cmd.Flags().GetBool("force")
core.Gen(args[0], specificPath, isForce)
},
Annotations: map[string]string{
BootModeKey: MODE_MINI_BOOT,
},
}
flagPV(genCmd, "force", "f", false, "Force overwrite an existing file")
return genCmd
}
+60
View File
@@ -0,0 +1,60 @@
package cmd
import (
"encoding/json"
"errors"
"os"
"github.com/ArtalkJS/Artalk/internal/artransfer"
"github.com/ArtalkJS/Artalk/internal/i18n"
"github.com/ArtalkJS/Artalk/internal/log"
"github.com/spf13/cobra"
)
func NewImportCommand(app *ArtalkCmd) *cobra.Command {
importCmd := &cobra.Command{
Use: "import <FILENAME>",
Aliases: []string{},
Short: "Artransfer import",
Long: "\n# Artransfer - Import\n\n See the documentation to learn more: https://artalk.js.org/guide/transfer.html",
Run: func(cmd *cobra.Command, args []string) {
// Prepare params
params := &artransfer.ImportParams{}
// Parse JSON parameters from flags
if jsonParams, _ := cmd.Flags().GetString("parameters"); jsonParams != "" {
if err := json.Unmarshal([]byte(jsonParams), params); err != nil {
log.Fatal("Failed to parse JSON parameters: ", err)
}
}
// If JSON file or JSON data is not provided in flags, try to get it from arguments
if params.JsonFile == "" && params.JsonData == "" {
if len(args) == 0 {
log.Fatal(i18n.T("{{name}} is required", map[string]interface{}{"name": "FILENAME"}))
}
params.JsonFile = args[0]
}
// Parse flags to params
if flagAssumeyes, err := cmd.Flags().GetBool("assumeyes"); err == nil {
params.Assumeyes = flagAssumeyes
}
// Check if file exists if JsonFile is provided
if params.JsonFile != "" {
if _, err := os.Stat(params.JsonFile); errors.Is(err, os.ErrNotExist) {
log.Fatal(i18n.T("{{name}} not found", map[string]interface{}{"name": i18n.T("File")}))
}
}
// Run import
artransfer.RunImportArtrans(app.Dao(), params)
},
}
flagPV(importCmd, "assumeyes", "y", false, "Automatically answer yes for all questions.")
flagPV(importCmd, "parameters", "p", "", "JSON format parameters for the import command.")
return importCmd
}
+35
View File
@@ -0,0 +1,35 @@
package cmd
import (
"fmt"
"github.com/ArtalkJS/Artalk/internal/log"
"github.com/ArtalkJS/Artalk/server"
"github.com/spf13/cobra"
)
func NewServeCommand(app *ArtalkCmd) *cobra.Command {
var serverCmd = &cobra.Command{
Use: "server",
Aliases: []string{"serve"},
Short: "Start the server",
Long: Banner,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(Banner)
fmt.Print("-------------------------------\n\n")
// init fiber app
_, err := server.Serve(app.App)
if err != nil {
log.Fatalln(err)
}
},
}
flagPV(serverCmd, "host", "", "0.0.0.0", "Listening IP")
flagPV(serverCmd, "port", "", 23366, "Listening port")
return serverCmd
}
+68
View File
@@ -0,0 +1,68 @@
package cmd
import (
"fmt"
"os"
"strings"
"github.com/ArtalkJS/Artalk/internal/config"
"github.com/ArtalkJS/Artalk/internal/i18n"
"github.com/ArtalkJS/Artalk/internal/log"
"github.com/blang/semver"
"github.com/rhysd/go-github-selfupdate/selfupdate"
"github.com/spf13/cobra"
)
func NewUpgradeCommand() *cobra.Command {
upgradeCmd := &cobra.Command{
Use: "upgrade",
Aliases: []string{"update"},
Short: "Upgrade to the latest version",
Long: "Upgrade Artalk to the latest version, \n update source is GitHub Releases, \n update need to restart Artalk to take effect.",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
log.Info(i18n.T("Checking for updates") + "...")
latest, found, err := selfupdate.DetectLatest("ArtalkJS/Artalk")
if err != nil {
log.Fatal("Error occurred while detecting version: ", err)
}
ignoreVersionCheck, _ := cmd.Flags().GetBool("force")
if !ignoreVersionCheck {
v := semver.MustParse(strings.TrimPrefix(config.Version, "v"))
if !found || latest.Version.LTE(v) {
log.Info(i18n.T("Current version is the latest") + " (v" + v.String() + ")")
return
}
}
log.Info(i18n.T("New version available") + ": v" + latest.Version.String())
log.Info(i18n.T("Downloading") + "...")
exe, err := os.Executable()
if err != nil {
log.Fatal("Could not locate executable path ", err)
}
if err := selfupdate.UpdateTo(latest.AssetURL, exe); err != nil {
log.Fatal(i18n.T("Update failed")+" ", err)
}
log.Info(i18n.T("Update complete"))
fmt.Printf("\n"+
"-------------------------------\n"+
" v%s Release Note\n"+
"-------------------------------\n\n"+
"%s\n",
latest.Version.String(), latest.ReleaseNotes)
},
Annotations: map[string]string{
BootModeKey: MODE_MINI_BOOT,
},
}
flagPV(upgradeCmd, "force", "f", false, "Force upgrade ignore version comparison.")
return upgradeCmd
}
+22
View File
@@ -0,0 +1,22 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
func NewVersionCommand() *cobra.Command {
versionCmd := &cobra.Command{
Use: "version",
Short: "Output version information",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Artalk (" + Version + ")")
},
Annotations: map[string]string{
BootModeKey: MODE_MINI_BOOT,
},
}
return versionCmd
}
+2
View File
@@ -0,0 +1,2 @@
ignore:
- "docs/*"
+252
View File
@@ -0,0 +1,252 @@
host: "0.0.0.0"
port: 23366
app_key: ""
debug: false
locale: en
timezone: Asia/Shanghai
site_default: Default Site
site_url: ""
login_timeout: 259200
db:
type: sqlite
file: ./data/artalk.db
table_prefix: ""
name: artalk
host: localhost
port: 3306
user: root
password: ""
charset: utf8mb4
ssl: false
prepare_stmt: true
http:
body_limit: 100
proxy_header: ""
log:
enabled: true
filename: ./data/artalk.log
cache:
enabled: false
type: builtin
expires: 30
warm_up: false
server: ""
redis:
network: tcp
username: ""
password: ""
db: 0
trusted_domains: []
ssl:
enabled: false
cert_path: ""
key_path: ""
moderator:
pending_default: false
api_fail_block: false
akismet_key: ""
tencent:
enabled: false
secret_id: ""
secret_key: ""
region: ap-guangzhou
aliyun:
enabled: false
access_key_id: ""
access_key_secret: ""
region: cn-shanghai
keywords:
enabled: false
pending: false
files:
- ./data/keywords_1.txt
file_sep: "\n"
replace_to: x
captcha:
enabled: true
always: false
captcha_type: image
action_limit: 3
action_reset: 60
turnstile:
site_key: ""
secret_key: ""
recaptcha:
site_key: ""
secret_key: ""
hcaptcha:
site_key: ""
secret_key: ""
geetest:
captcha_id: ""
captcha_key: ""
img_upload:
enabled: true
path: ./data/artalk-img/
max_size: 5
public_path: null
upgit:
enabled: false
exec: upgit -c UPGIT_CONF_FILE_PATH -t /artalk-img
del_local: true
email:
enabled: false
send_type: smtp
send_name: "{{reply_nick}}"
send_addr: noreply@example.com
mail_subject: "[{{site_name}}] You got a reply from @{{reply_nick}}"
mail_tpl: default
smtp:
host: smtp.qq.com
port: 587
username: example@qq.com
password: ""
ali_dm:
access_key_id: ""
access_key_secret: ""
account_name: noreply@example.com
admin_notify:
notify_tpl: default
notify_pending: false
noise_mode: false
email:
enabled: true
mail_subject: '[{{site_name}}] Post "{{page_title}}" has new a comment'
mail_tpl: ""
telegram:
enabled: false
api_token: ""
receivers:
- 7777777
bark:
enabled: false
server: http://day.app/xxxxxxx/
lark:
enabled: false
webhook_url: ""
msg_type: "text"
webhook:
enabled: false
url: ""
ding_talk:
enabled: false
token: ""
secret: ""
slack:
enabled: false
oauth_token: ""
receivers:
- "CHANNEL_ID"
line:
enabled: false
channel_secret: ""
channel_access_token: ""
receivers:
- "USER_ID_1"
- "GROUP_ID_1"
auth:
enabled: false
anonymous: false
callback: "http://localhost:23366/api/v2/auth/{provider}/callback"
email:
enabled: true
verify_subject: "Your Code - {{code}}"
verify_tpl: default
github:
enabled: false
client_id: ""
client_secret: ""
gitlab:
enabled: false
client_id: ""
client_secret: ""
gitea:
enabled: false
client_id: ""
client_secret: ""
google:
enabled: false
client_id: ""
client_secret: ""
mastodon:
enabled: false
client_id: ""
client_secret: ""
twitter:
enabled: false
client_id: ""
client_secret: ""
facebook:
enabled: false
client_id: ""
client_secret: ""
discord:
enabled: false
client_id: ""
client_secret: ""
steam:
enabled: false
api_key: ""
apple:
enabled: false
client_id: ""
client_secret: ""
microsoft:
enabled: false
client_id: ""
client_secret: ""
wechat:
enabled: false
client_id: ""
client_secret: ""
tiktok:
enabled: false
client_id: ""
client_secret: ""
slack:
enabled: false
client_id: ""
client_secret: ""
line:
enabled: false
client_id: ""
client_secret: ""
patreon:
enabled: false
client_id: ""
client_secret: ""
auth0:
enabled: false
client_id: ""
client_secret: ""
domain: ""
frontend:
placeholder: ""
noComment: ""
sendBtn: ""
editorTravel: true
emoticons: https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json
vote: true
voteDown: false
uaBadge: false
listSort: true
preview: true
flatMode: auto
darkMode: inherit
nestMax: 2
nestSort: DATE_ASC
gravatar:
mirror: https://www.gravatar.com/avatar/
params: sha256=1&d=mp&s=240
pagination:
pageSize: 20
readMore: true
autoLoad: true
heightLimit:
content: 300
children: 400
scrollable: false
imgLazyLoad: false
reqTimeout: 15000
versionCheck: true
pluginURLs: []
+449
View File
@@ -0,0 +1,449 @@
# Listen host
host: "0.0.0.0"
# Listen port
port: 23366
# App Key (for generation of JWT)
app_key: ""
# Debug mode
debug: false
# Language (follow Unicode BCP 47) ["en", "zh-CN", "zh-TW", "ja", "fr", "ko", "ru"]
# -- see https://www.techonthenet.com/js/language_tags.php --
locale: en
# Timezone (follow IANA Time Zone Database)
# -- see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones --
timezone: Asia/Shanghai
# Default site name (create when app is first launched)
site_default: Default Site
# Default site url
site_url: ""
# Login timeout (in seconds)
login_timeout: 259200
# Database
db:
# Database type ["sqlite", "mysql", "pgsql", "mssql"]
type: sqlite
# Database file (only for SQLite)
file: ./data/artalk.db
# Table prefix (e.g. "atk_")
table_prefix: ""
# -- The following is not necessary for SQLite --
# Database name
name: artalk
# Host address
host: localhost
# Host port
port: 3306
# Database user
user: root
# Database password
password: ""
# Database charset
charset: utf8mb4
# Enable SSL mode
ssl: false
# Prepared Statement
prepare_stmt: true
# Web server
http:
# Body size limit (unit: MB)
body_limit: 100
# Proxy Header (fill `X-Forwarded-For` to get user real IP if behind a trusted reverse proxy or CDN)
proxy_header: ""
# Logging
log:
# Enable logging
enabled: true
# Log file path
filename: ./data/artalk.log
# Cache
cache:
# Enable cache
enabled: false
# Cache type ["redis", "memcache", "builtin"]
type: builtin
# Cache expiration time (in minutes)
expires: 30
# Cache warm up (warm up cache when program starts)
warm_up: false
# -- The following is not necessary for `builtin` cache --
# Cache server address (e.g. "localhost:6379")
server: ""
# Redis config
redis:
# Connection type ["tcp", "unix"]
network: tcp
# Redis username
username: ""
# Redis password
password: ""
# Redis database number (e.g. 0)
db: 0
# Trusted domains
# -- e.g. ["https://artalk.example.com:23366"] add url of your site her --
trusted_domains: []
# SSL
ssl:
# Enable SSL
enabled: false
# Certificate file path
# (e.g. "/etc/letsencrypt/live/example.com/fullchain.pem")
cert_path: ""
# Key file path
# (e.g. "/etc/letsencrypt/live/example.com/privkey.pem")
key_path: ""
# Moderator
# -- Comment examination before being public --
moderator:
# Default pending (new comments need to be approved by admin)
pending_default: false
# Block when API request fails (set to false to let comments pass when API request fails)
api_fail_block: false
# Akismet Key
# (Akismet anti-spam service, https://akismet.com)
akismet_key: ""
# Tencent Cloud Content Security
# (Auto review comments with Tencent Cloud Content Security)
# -- see https://cloud.tencent.com/document/product/1124/64508 --
tencent:
enabled: false
secret_id: ""
secret_key: ""
region: ap-guangzhou
# Aliyun Content Security
# (Auto review comments with Aliyun Content Security)
# -- see https://help.aliyun.com/document_detail/28417.html --
aliyun:
enabled: false
access_key_id: ""
access_key_secret: ""
region: cn-shanghai
# Keyword filter (local offline dictionary)
keywords:
# Enable keyword filter
enabled: false
# Set to pending when match
pending: false
# Dictionary file (support multiple dictionary files)
files:
- ./data/keywords_1.txt
file_sep: "\n"
replace_to: x
# Captcha
captcha:
# Enable captcha
enabled: true
# Captcha is required always
always: false
# Captcha type ["image", "turnstile", "recaptcha", "hcaptcha", "geetest"]
captcha_type: image
# Action limit
# (the number of actions required to activate captcha)
action_limit: 3
# Reset Timeout (timeout to reset action counter. unit: s, set to -1 to disable)
action_reset: 60
# Turnstile
# (https://www.cloudflare.com/products/turnstile/)
turnstile:
site_key: ""
secret_key: ""
# reCaptcha
# (https://www.google.com/recaptcha/about/)
recaptcha:
site_key: ""
secret_key: ""
# hCaptcha (https://www.hcaptcha.com/)
hcaptcha:
site_key: ""
secret_key: ""
# Geetest (https://www.geetest.com)
geetest:
captcha_id: ""
captcha_key: ""
# Upload
img_upload:
# Enable image upload
enabled: true
# Image storage
path: ./data/artalk-img/
# Image size limit (unit: MB)
max_size: 5
# Image link base path (default: "/static/images/")
public_path: null
# Upgit config
upgit:
# Enable Upgit
enabled: false
# Command line arguments
exec: upgit -c UPGIT_CONF_FILE_PATH -t /artalk-img
# Delete local image after upload success
del_local: true
# Email
email:
# Enable email notification
enabled: false
# Send method ["smtp", "ali_dm", "sendmail"]
send_type: smtp
# Nick name of sender
send_name: "{{reply_nick}}"
# Email address of sender
send_addr: noreply@example.com
# Email subject
mail_subject: "[{{site_name}}] You got a reply from @{{reply_nick}}"
# Email template file (set to file path to use custom template)
mail_tpl: default
# SMTP send (set send method to "smtp" to enable)
smtp:
# Email address of sender
host: smtp.qq.com
# Email port
port: 587
# Email address of sender
username: example@qq.com
# Password
password: ""
# Aliyun mail push
# (set send method to "ali_dm" to enable; see: https://help.aliyun.com/document_detail/29444.html)
ali_dm:
access_key_id: ""
access_key_secret: ""
account_name: noreply@example.com
# Multi-Push
admin_notify:
# Notification template (set to file path to use custom template)
notify_tpl: default
# Pending comment still send notification (notifications are still sent when comments are intercepted)
notify_pending: false
# Noise mode
# -- noise_mode is disabled by default. --
# -- When this option is set to `false`, only messages sent to the administrator will be notified, --
# -- such as "user A" replies to "user B", the communication between these two users will not be notified to the administrator. --
noise_mode: false
# Notify admin
email:
# Enable (can be disabled when using other push methods)
enabled: true
# Email subject (email subject sent to admin)
mail_subject: '[{{site_name}}] Post "{{page_title}}" has new a comment'
# Admin email template file (set to file path to use custom template)
mail_tpl: ""
# Telegram
telegram:
enabled: false
api_token: ""
receivers:
- 7777777
# Bark
bark:
enabled: false
server: http://day.app/xxxxxxx/
# Lark
lark:
enabled: false
webhook_url: ""
# Message type ["text", "card"]
msg_type: "text"
# WebHook
webhook:
enabled: false
url: ""
# DingTalk
ding_talk:
enabled: false
token: ""
secret: ""
# Slack
slack:
enabled: false
oauth_token: ""
receivers:
- "CHANNEL_ID"
# LINE
line:
enabled: false
channel_secret: ""
channel_access_token: ""
receivers:
- USER_ID_1
- GROUP_ID_1
# Social Login
auth:
# Enable Social Login
enabled: false
# Allow anonymous commenting (Allow skipping verification, only fill in an anonymous nickname and email)
anonymous: false
# Callback URL (https://example.com/api/v2/auth/{provider}/callback)
callback: "http://localhost:23366/api/v2/auth/{provider}/callback"
# Email
email:
# Enable email password login
enabled: true
# Verification email subject
verify_subject: "Your Code - {{code}}"
# Verification email template (set to file path to use custom template)
verify_tpl: default
# GitHub
github:
enabled: false
client_id: ""
client_secret: ""
# GitLab
gitlab:
enabled: false
client_id: ""
client_secret: ""
# Gitea
gitea:
enabled: false
client_id: ""
client_secret: ""
# Google
google:
enabled: false
client_id: ""
client_secret: ""
# Mastodon
mastodon:
enabled: false
client_id: ""
client_secret: ""
# Twitter
twitter:
enabled: false
client_id: ""
client_secret: ""
# Facebook
facebook:
enabled: false
client_id: ""
client_secret: ""
# Discord
discord:
enabled: false
client_id: ""
client_secret: ""
# Steam
steam:
enabled: false
api_key: ""
# Apple
apple:
enabled: false
client_id: ""
client_secret: ""
# Microsoft
microsoft:
enabled: false
client_id: ""
client_secret: ""
# WeChat
wechat:
enabled: false
client_id: ""
client_secret: ""
# Tiktok
tiktok:
enabled: false
client_id: ""
client_secret: ""
# Slack
slack:
enabled: false
client_id: ""
client_secret: ""
# Line
line:
enabled: false
client_id: ""
client_secret: ""
# Patreon
patreon:
enabled: false
client_id: ""
client_secret: ""
# Auth0
auth0:
enabled: false
client_id: ""
client_secret: ""
domain: ""
# UI Settings
frontend:
# Comment box placeholder
placeholder: ""
# Text to display when there is
noComment: ""
# Text of the send button
sendBtn: ""
# Movable comment box
editorTravel: true
# Emoticons
emoticons: https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json
# Vote button
vote: true
# Dislike button
voteDown: false
# User UA badge
uaBadge: false
# Comment sorting
listSort: true
# Editor real-time preview
preview: true
# Flatten mode ["auto", true, false]
flatMode: auto
# Dark mode ["inherit", "auto"]
darkMode: inherit
# Maximum nesting level
nestMax: 2
# Nesting comment sorting rules ["DATE_ASC", "DATE_DESC", "VOTE_UP_DESC"]
nestSort: DATE_ASC
# Gravatar
gravatar:
# API URL
mirror: https://www.gravatar.com/avatar/
# API parameters
params: sha256=1&d=mp&s=240
# Comment pagination
pagination:
# Number of comments per page
pageSize: 20
# Load more mode (disabled to use pagination bar)
readMore: true
# Scroll loading
autoLoad: true
# Content height limit
heightLimit:
# Comment content height limit (unit: px)
content: 300
# Sub-comment area height limit (unit: px)
children: 400
# Scrollable (scrollable height limit area)
scrollable: false
# Image lazy load [false, "native", "data-src"]
imgLazyLoad: false
# Request timeout (unit: ms)
reqTimeout: 15000
# Version check
versionCheck: true
# Plugins
pluginURLs: []
@@ -10,47 +10,66 @@ app_key: ""
# 调试模式
debug: false
# 语言 ["en", "zh-CN", "zh-TW", "ja", "fr", "ko", "ru"]
locale: zh-CN
# 时间区域
timezone: "Asia/Shanghai"
timezone: Asia/Shanghai
# 默认站点名
site_default: "默认站点"
site_default: 默认站点
# 登陆有效时长 (单位:秒)
# 默认站点地址
site_url: ""
# 登录有效时长 (单位:秒)
login_timeout: 259200
# 数据库
db:
# 数据库类型 ["sqlite", "mysql", "pgsql", "mssql"]
type: "sqlite"
type: sqlite
# 数据库文件 (仅 SQLite 数据库需填写)
file: "./data/artalk-go.db"
file: ./data/artalk.db
# 数据库名称
name: "artalk"
name: artalk
# 数据库地址
host: "localhost"
host: localhost
# 数据库端口
port: 3306
# 数据库账户
user: "root"
user: root
# 数据库密码
password: ""
# 编码格式
charset: "utf8mb4"
charset: utf8mb4
# 表前缀 (例如:"atk_")
table_prefix: ""
# 启用 SSL
ssl: false
# 预编译语句
prepare_stmt: true
# 服务器
http:
# 请求体大小限制 (单位:MB)
body_limit: 100
# 代理标头名 (当使用 CDN 时填写 `X-Forwarded-For` 获取用户真实 IP)
proxy_header: ""
# 日志
log:
# 启用日志
enabled: true
# 日志文件路径
filename: "./data/artalk-go.log"
filename: ./data/artalk.log
# 缓存
cache:
# 启用缓存
enabled: false
# 缓存类型 ["redis", "memcache", "builtin"]
type: "builtin"
type: builtin
# 缓存过期时间 (单位:分钟)
expires: 30
# 缓存启动预热 (程序启动时预热缓存)
@@ -60,7 +79,7 @@ cache:
# Redis 配置
redis:
# 连接方式 ["tcp", "unix"]
network: "tcp"
network: tcp
# 用户名
username: ""
# 密码
@@ -69,7 +88,8 @@ cache:
db: 0
# 可信域名
trusted_domains: [] # 例如:["https://artalk.example.com:23366"]
# -- 例如:["https://artalk.example.com:23366"] --
trusted_domains: []
# SSL
ssl:
@@ -81,12 +101,14 @@ ssl:
key_path: ""
# 管理员账户
admin_users:
# - name: "admin"
# email: "admin@example.com"
# password: "" # 支持 bcrypt 或 md5 加密,如:"(md5)50c21190c6e4e5418c6a90d2b5031119"
# badge_name: "管理员"
# badge_color: "#FF6C00"
# --
# - name: "admin"
# email: "admin@example.com"
# password: "" # 支持 bcrypt 或 md5 加密,如:"(bcrypt)$2y$10$ti4vZYIrxVN8rLcYXVgXCO.GJND0dyI49r7IoF3xqIx8bBRmIBZRm"
# badge_name: "管理员"
# badge_color: "#0083FF"
# --
admin_users: []
# 评论审核
moderator:
@@ -103,14 +125,14 @@ moderator:
enabled: false
secret_id: ""
secret_key: ""
region: "ap-guangzhou"
region: ap-guangzhou
# 阿里云内容安全
# (https://help.aliyun.com/document_detail/28417.html)
aliyun:
enabled: false
access_key_id: ""
access_key_secret: ""
region: "cn-shanghai"
region: cn-shanghai
# 关键词过滤 (本地离线词库)
keywords:
enabled: false
@@ -118,11 +140,11 @@ moderator:
pending: false
# 词库文件 (支持多个词库文件)
files:
- "./data/词库_1.txt"
- ./data/词库_1.txt
# 词库文件内容分割符 (例如填写 "\n" 文件中一行一个关键词)
file_sep: "\n"
# 替换字符
replac_to: "x"
replace_to: x
# 验证码
captcha:
@@ -130,53 +152,46 @@ captcha:
enabled: true
# 总是需要验证码
always: false
# 验证类型 ["image", "turnstile", "recaptcha", "hcaptcha", "geetest"]
captcha_type: image
# 激活验证码所需操作次数
action_limit: 3
# 重置操作计数器超时 (单位:s, 设为 -1 不重置)
action_reset: 60
# Turnstile
# (https://www.cloudflare.com/products/turnstile/)
turnstile:
site_key: ""
secret_key: ""
# reCaptcha
# (https://www.google.com/recaptcha/about/)
recaptcha:
site_key: ""
secret_key: ""
# hCaptcha (https://www.hcaptcha.com/)
hcaptcha:
site_key: ""
secret_key: ""
# Geetest 极验 (https://www.geetest.com)
geetest:
enabled: false
captcha_id: ""
captcha_key: ""
# 邮件通知
email:
# 启用邮件通知
# IP 属地
ip_region:
# 启用 IP 属地展示
enabled: false
# 发送方式 ["smtp", "ali_dm", "sendmail"]
send_type: "smtp"
# 发信人昵称
send_name: "{{reply_nick}}"
# 发信人地址
send_addr: "noreply@example.com"
# 邮件标题
mail_subject: "[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复"
# 邮件模板文件 (填入文件路径使用自定义模板)
mail_tpl: "default"
# SMTP 发送 (启用请将发送方式设为 "smtp")
smtp:
# 发件地址
host: "smtp.qq.com"
# 发件端口
port: 587
# 用户名
username: "example@qq.com"
# 密码
password: ""
# 阿里云邮件推送
# (启用请将发送方式设为 "ali_dm";参考:https://help.aliyun.com/document_detail/29444.html)
ali_dm:
access_key_id: ""
access_key_secret: ""
account_name: "noreply@example.com"
# 数据文件路径 (.xdb 格式)
db_path: ./data/ip2region.xdb
# 显示精度 ["province", "city", "country"]
precision: province
# 图片上传
img_upload:
# 启用图片上传
enabled: true
# 图片存放路径
path: "./data/artalk-img/"
path: ./data/artalk-img/
# 图片大小限制 (单位:MB)
max_size: 5
# 图片链接基础路径 (默认为 "/static/images/")
@@ -187,14 +202,47 @@ img_upload:
# 启用 Upgit
enabled: false
# 命令行参数
exec: "./upgit -c <upgit配置文件路径> -t /artalk-img"
exec: upgit -c <upgit配置文件路径> -t /artalk-img
# 上传后删除本地的图片
del_local: true
# 邮件通知
email:
# 启用邮件通知
enabled: false
# 发送方式 ["smtp", "ali_dm", "sendmail"]
send_type: smtp
# 发信人昵称
send_name: "{{reply_nick}}"
# 发信人地址
send_addr: noreply@example.com
# 邮件标题
mail_subject: "[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复"
# 邮件模板文件 (填入文件路径使用自定义模板)
mail_tpl: default
# SMTP 发送 (启用请将发送方式设为 "smtp")
smtp:
# 发件地址
host: smtp.qq.com
# 发件端口
port: 587
# 用户名
username: example@qq.com
# 密码
password: ""
# 阿里云邮件推送
# (启用请将发送方式设为 "ali_dm";参考:https://help.aliyun.com/document_detail/29444.html)
ali_dm:
access_key_id: ""
access_key_secret: ""
account_name: noreply@example.com
# 多元推送
admin_notify:
# 通知模版 (填入文件路径使用自定义模板)
notify_tpl: "default"
notify_tpl: default
# 待审评论仍然发送通知 (当评论被拦截时仍然发送通知)
notify_pending: false
# 嘈杂模式
noise_mode: false
# 邮件通知管理员
@@ -203,6 +251,8 @@ admin_notify:
enabled: true
# 邮件标题 (发送给管理员的邮件标题)
mail_subject: "[{{site_name}}] 您的文章「{{page_title}}」有新回复"
# 管理员邮件模板文件 (填入文件路径使用自定义模板)
mail_tpl: ""
# Telegram
telegram:
enabled: false
@@ -212,11 +262,13 @@ admin_notify:
# Bark
bark:
enabled: false
server: "http://day.app/xxxxxxx/"
server: http://day.app/xxxxxxx/
# 飞书
lark:
enabled: false
webhook_url: ""
# 消息类型 ["text", "card"]
msg_type: "text"
# WebHook
webhook:
enabled: false
@@ -231,58 +283,158 @@ admin_notify:
enabled: false
oauth_token: ""
receivers:
- "CHANNEL_ID"
- CHANNEL_ID
# LINE
line:
enabled: false
channel_secret: ""
channel_access_token: ""
receivers:
- "USER_ID_1"
- "GROUP_ID_1"
- USER_ID_1
- GROUP_ID_1
# 前端配置
# 社交登录
auth:
# 启用社交登录
enabled: false
# 允许匿名评论 (允许跳过验证,仅填写匿名的昵称和邮箱)
anonymous: false
# 回调地址 (https://example.com/api/v2/auth/{provider}/callback)
callback: "http://localhost:23366/api/v2/auth/{provider}/callback"
# Email
email:
# 启用邮箱密码登录
enabled: true
# 邮箱验证邮件标题
verify_subject: "您的验证码是 - {{code}}"
# 邮箱验证邮件模板 (填入文件路径使用自定义模板)
verify_tpl: default
# GitHub
github:
enabled: false
client_id: ""
client_secret: ""
# GitLab
gitlab:
enabled: false
client_id: ""
client_secret: ""
# Gitea
gitea:
enabled: false
client_id: ""
client_secret: ""
# Google
google:
enabled: false
client_id: ""
client_secret: ""
# Mastodon
mastodon:
enabled: false
client_id: ""
client_secret: ""
# Twitter
twitter:
enabled: false
client_id: ""
client_secret: ""
# Facebook
facebook:
enabled: false
client_id: ""
client_secret: ""
# Discord
discord:
enabled: false
client_id: ""
client_secret: ""
# Steam
steam:
enabled: false
api_key: ""
# Apple
apple:
enabled: false
client_id: ""
client_secret: ""
# Microsoft
microsoft:
enabled: false
client_id: ""
client_secret: ""
# 微信
wechat:
enabled: false
client_id: ""
client_secret: ""
# Tiktok
tiktok:
enabled: false
client_id: ""
client_secret: ""
# Slack
slack:
enabled: false
client_id: ""
client_secret: ""
# Line
line:
enabled: false
client_id: ""
client_secret: ""
# Patreon
patreon:
enabled: false
client_id: ""
client_secret: ""
# Auth0
auth0:
enabled: false
client_id: ""
client_secret: ""
domain: ""
# 界面配置
frontend:
# 评论框占位文字
placeholder: "键入内容..."
placeholder: ""
# 无评论显示文字
noComment: "「此时无声胜有声」"
noComment: ""
# 发送按钮文字
sendBtn: "发送评论"
# 评论框旅行
sendBtn: ""
# 评论框穿梭
editorTravel: true
# 暗黑模式
darkMode: false
# 表情包
emoticons: "https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json"
emoticons: https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json
# 投票按钮
vote: true
# 反对按钮
voteDown: false
# 用户 UA 徽标
uaBadge: true
uaBadge: false
# 评论排序功能
listSort: true
# 页面 PV 绑定元素
pvEl: "#ArtalkPV"
# 评论数绑定元素
countEl: "#ArtalkCount"
# 编辑器实时预览功能
preview: true
# 平铺模式 ["auto", true, false]
flatMode: "auto"
flatMode: auto
# 夜间模式 ["inherit", "auto"]
darkMode: inherit
# 最大嵌套层数
nestMax: 2
# 嵌套评论排序规则 ["DATE_ASC", "DATE_DESC", "VOTE_UP_DESC"]
nestSort: DATE_ASC
# 头像
# 头像 Gravatar
gravatar:
# Gravatar 镜像地址
mirror: "https://cravatar.cn/avatar/"
# 默认头像
default: "mp"
# API 地址
mirror: https://weavatar.com/avatar/
# API 参数
params: sha256=1&d=mp&s=240
# 评论分页
pagination:
# 每页评论数
pageSize: 20
# 加载更多模式 (关闭则使用分页条)
readMore: true
# 滚动加载
@@ -293,7 +445,13 @@ frontend:
content: 300
# 子评论区域限高 (单位:px)
children: 400
# 滚动限高 (允许限高区域滚动)
scrollable: false
# 图片懒加载 [false, "native", "data-src"]
imgLazyLoad: false
# 请求超时 (单位:毫秒)
reqTimeout: 15000
# 版本检测
versionCheck: true
# 插件
pluginURLs: []
+18
View File
@@ -0,0 +1,18 @@
version: "3.8"
services:
artalk:
container_name: artalk
image: artalk/artalk-go
restart: unless-stopped
build:
context: ./
dockerfile: Dockerfile
ports:
- 8080:23366
volumes:
- ./data:/data
environment:
- TZ=Asia/Shanghai
- ATK_LOCALE=zh-CN
- ATK_SITE_DEFAULT=Artalk 的博客
- ATK_SITE_URL=https://example.com
+26
View File
@@ -0,0 +1,26 @@
#!/bin/bash
set -e
if [ "$1" != 'gen' ] && ( [ ! -e /data/artalk.yml ] && [ ! -e /data/artalk-go.yml ] ); then
if [ -e /conf.yml ]; then
# Move original config to `/data/` for upgrade (<= v2.1.8)
cp /conf.yml /data/artalk.yml
upMsg=""
upMsg+=$'# [v2.1.9+ Updated]\n'
upMsg+=$'# The new version of the Artalk container recommends mounting\n'
upMsg+=$'# an entire folder instead of a single file to avoid some issues.\n'
upMsg+=$'#\n'
upMsg+=$'# The original config file has been moved to the "/data/" folder,\n'
upMsg+=$'# please unmount the config file volume from your container\n'
upMsg+=$'# and edit "/data/artalk.yml" for configuration.'
echo "$upMsg" > /conf.yml
echo "$(date) [info][docker] Copy config file from '/conf.yml' to '/data/artalk.yml' for upgrade"
else
# Generate new config
artalk gen conf /data/artalk.yml
echo "$(date) [info][docker] Generate new config file to '/data/artalk.yml'"
fi
fi
# Run Artalk
/usr/bin/artalk "$@"
+2
View File
@@ -0,0 +1,2 @@
.vitepress/dist/**
.vitepress/cache/**
+222
View File
@@ -0,0 +1,222 @@
import { defineConfig } from 'vitepress'
import iterator from 'markdown-it-for-inline'
import * as Version from '../code/ArtalkVersion.json'
export default defineConfig({
title: 'Artalk',
description: '一款简洁的自托管评论系统',
lang: 'zh-CN',
head: [
['link', { rel: 'icon', href: '/favicon.png' }],
[
'meta',
{
name: 'viewport',
content:
'width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi',
},
],
],
lastUpdated: true,
markdown: {
// @link https://github.com/shikijs/shiki
theme: {
light: 'github-light',
dark: 'github-dark',
},
config: (md) => {
md.use(iterator, 'artalk_version', 'text', function (tokens, idx) {
tokens[idx].content = tokens[idx].content.replace(
/:ArtalkVersion:/g,
Version.latest,
)
})
md.use(iterator, 'artalk_version_link', 'link_open', (tokens, idx) => {
const href = tokens[idx].attrGet('href')
tokens[idx].attrSet(
'href',
href.replace(/:ArtalkVersion:/g, Version.latest),
)
})
},
},
locales: {
root: {
label: '简体中文',
lang: 'zh',
link: 'https://artalk.js.org/',
},
en: {
label: 'English',
lang: 'en',
link: 'https://artalk-js-org.translate.goog/guide/intro?_x_tr_sl=auto&_x_tr_tl=en-US&_x_tr_hl=en-US&_x_tr_pto=wapp',
},
},
themeConfig: {
sidebar: {
'/guide/': [
{
text: '快速开始',
collapsed: false,
items: [
{ text: '项目介绍', link: '/guide/intro.md' },
{ text: '程序部署', link: '/guide/deploy.md' },
{ text: '数据迁移', link: '/guide/transfer.md' },
],
},
{
text: '核心指南',
collapsed: false,
items: [
{ text: '侧边栏', link: '/guide/frontend/sidebar.md' },
{ text: '邮件通知', link: '/guide/backend/email.md' },
{ text: '多元推送', link: '/guide/backend/admin_notify.md' },
{ text: '社交登录', link: '/guide/frontend/auth.md' },
{ text: '评论审核', link: '/guide/backend/moderator.md' },
{ text: '验证码', link: '/guide/backend/captcha.md' },
{ text: '图片上传', link: '/guide/backend/img-upload.md' },
{ text: '账户与多站点', link: '/guide/backend/multi-site.md' },
{ text: '解析相对路径', link: '/guide/backend/relative-path.md' },
],
},
{
text: '进阶指南',
collapsed: false,
items: [
{ text: '表情包', link: '/guide/frontend/emoticons.md' },
{ text: '浏览量统计', link: '/guide/frontend/pv.md' },
{ text: 'LaTeX', link: '/guide/frontend/latex.md' },
{ text: '图片灯箱', link: '/guide/frontend/lightbox.md' },
{ text: '图片懒加载', link: '/guide/frontend/img-lazy-load.md' },
{ text: 'IP 属地', link: '/guide/frontend/ip-region.md' },
{ text: '多语言', link: '/guide/frontend/i18n.md' },
{ text: '开发文档', link: '/develop/index.md' },
],
},
{
text: '配置文档',
collapsed: false,
items: [
{ text: '环境变量', link: '/guide/env.md' },
{ text: '配置文件', link: '/guide/backend/config.md' },
{ text: '界面配置', link: '/guide/frontend/config.md' },
],
},
{
text: '部署说明',
collapsed: true,
items: [
{ text: '守护进程', link: '/guide/backend/daemon.md' },
{ text: '反向代理', link: '/guide/backend/reverse-proxy.md' },
{ text: '编译构建', link: '/develop/contributing.md' },
{ text: '程序升级', link: '/guide/backend/update.md' },
{ text: 'Docker', link: '/guide/backend/docker.md' },
],
},
{
text: '更多内容',
collapsed: true,
items: [
{ text: '安全防范', link: '/guide/security.md' },
{ text: '扩展阅读', link: '/guide/extras.md' },
{ text: '案例展示', link: '/guide/cases.md' },
{ text: '关于我们', link: '/guide/about.md' },
],
},
],
'/develop/': [
{
text: '开发文档',
items: [
{ text: '开发说明', link: '/develop/index.md' },
{ text: '贡献指南', link: '/develop/contributing.md' },
{ text: '置入博客', link: '/develop/import-blog.md' },
{ text: '置入框架', link: '/develop/import-framework.md' },
{ text: '前端 API', link: '/develop/fe-api.md' },
{ text: '前端 Event', link: '/develop/event.md' },
{ text: '插件开发', link: '/develop/plugin.md' },
{ text: '兼容性', link: '/develop/compatibility.md' },
{
text: 'HTTP API',
link: 'https://artalk.js.org/http-api.html',
},
],
},
],
},
nav: [
// NavbarItem
{
text: '介绍',
link: '/guide/intro',
},
{
text: '部署',
link: '/guide/deploy',
},
{
text: '配置',
link: '/guide/backend/config',
},
{
text: '迁移',
link: '/guide/transfer',
},
{
text: '案例',
link: '/guide/cases',
},
{
text: '开发',
link: '/develop/',
},
// NavbarGroup
{
text: '传送',
items: [
{
text: '代码仓库',
link: 'https://github.com/ArtalkJS/Artalk',
},
// {
// text: "文档镜像 (国内)",
// link: "https://artalk-docs.qwqaq.com",
// },
],
},
],
socialLinks: [
{ icon: 'github', link: 'https://github.com/ArtalkJS/Artalk' },
],
search: {
provider: 'algolia',
options: {
appId: '2WNJ32WVTY',
apiKey: '6c6ebc345a87b738264f19095b78c91c',
indexName: 'artalk-js',
searchParameters: {
facetFilters: ['lang:zh-CN'],
},
},
},
editLink: {
pattern: 'https://github.com/ArtalkJS/Artalk/edit/master/docs/docs/:path',
text: '完善文档',
},
},
vite: {
server: {
open: '/guide/intro.html',
},
},
})
+82
View File
@@ -0,0 +1,82 @@
<template>
<div ref="el" style="margin-top: 20px"></div>
</template>
<script setup lang="ts">
import { watch, nextTick, ref, onMounted, onUnmounted } from 'vue'
import { useData, useRouter } from 'vitepress'
import Artalk from 'artalk'
import { ArtalkKatexPlugin } from '@artalk/plugin-katex'
import { ArtalkLightboxPlugin } from '@artalk/plugin-lightbox'
import 'lightgallery/css/lightgallery.css'
import 'katex/dist/katex.min.css'
import 'artalk/dist/Artalk.css'
const el = ref<HTMLElement | null>(null)
const router = useRouter()
const page = useData().page
let artalk: Artalk
onMounted(() => {
nextTick(() => {
initArtalk(getConfByPage())
})
})
watch(
() => router.route.path,
() => {
nextTick(() => {
artalk.update(getConfByPage())
artalk.reload()
})
},
)
onUnmounted(() => {
artalk.destroy()
})
function initArtalk(conf: any) {
Artalk.use(ArtalkKatexPlugin)
Artalk.use(ArtalkLightboxPlugin, {
lightGallery: {
lib: async () => (await import('lightgallery')).default
}
})
artalk = Artalk.init({
el: el.value,
emoticons: '/assets/emoticons/default.json',
...conf,
})
loadExtraFuncs()
}
function getConfByPage() {
return {
pageKey: 'https://artalk.js.org' + router.route.path,
pageTitle: page.value.title,
server: 'https://artalk.qwqaq.com',
site: 'ArtalkDocs',
}
}
function loadExtraFuncs() {
// 夜间模式
const darkMode = document.querySelector('html').classList.contains('dark')
artalk.setDarkMode(darkMode)
new MutationObserver((mList) => {
mList.forEach((m) => {
if (m.attributeName !== 'class') return
const darkMode = (<HTMLElement>m.target).classList.contains('dark')
artalk.setDarkMode(darkMode)
})
}).observe(document.querySelector('html'), { attributes: true })
}
</script>
+37
View File
@@ -0,0 +1,37 @@
<template>
<iframe
id="artransferIframe"
src="https://artransfer.netlify.app/?iframe=1"
style="width: 100%; height: 520px; border: 0"
></iframe>
</template>
<script lang="ts">
import { defineComponent, nextTick } from 'vue'
function setArtransferIframeDarkMode(value: boolean) {
const iframe = document.querySelector<HTMLIFrameElement>('#artransferIframe')!
if (value) {
iframe.src = iframe.src + '&dark=1'
} else {
iframe.src = iframe.src.replace(/&dark=1$/, '')
}
}
export default defineComponent({
mounted: () => {
const darkMode = document.querySelector('html').classList.contains('dark')
setArtransferIframeDarkMode(darkMode)
// dark_mode 监听
new MutationObserver((mList) => {
mList.forEach((m) => {
if (m.attributeName !== 'class') return
const darkMode = (<HTMLElement>m.target).classList.contains('dark')
setArtransferIframeDarkMode(darkMode)
})
}).observe(document.querySelector('html'), { attributes: true })
},
})
</script>
+15
View File
@@ -0,0 +1,15 @@
<script setup>
import DefaultTheme from 'vitepress/theme'
import { onMounted } from 'vue'
import './style.scss'
const { Layout } = DefaultTheme
</script>
<template>
<Layout>
<template #doc-after>
<Artalk />
</template>
</Layout>
</template>
+1
View File
@@ -0,0 +1 @@
declare const Artalk: any
+20
View File
@@ -0,0 +1,20 @@
import DefaultTheme from 'vitepress/theme'
import { Theme } from 'vitepress'
import Layout from './Layout.vue'
import Artalk from './Artalk.vue'
import Artransfer from './Artransfer.vue'
export default {
...DefaultTheme,
Layout,
enhanceApp({ app, router, siteData }) {
app.component('Artransfer', Artransfer)
app.component('Artalk', Artalk)
// app is the Vue 3 app instance from `createApp()`.
// router is VitePress' custom router. `siteData` is
// a `ref` of current site-level metadata.
},
} as Theme
+155
View File
@@ -0,0 +1,155 @@
:root {
--vp-c-brand: #558fb5;
--vp-c-brand-light: #498cb8;
--vp-c-brand-lighter: #549ccc;
--vp-c-brand-dark: #366482;
--vp-c-brand-darker: #244f6b;
--vp-code-block-bg: #f6f8fa;
--vp-c-divider: #dfe2e5;
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: linear-gradient(90deg, #0083ff, #37dfd9);
}
.dark {
--vp-c-bg: #22272e;
--vp-c-bg-alt: #22272e;
--vp-code-block-bg: #2b313a;
--vp-c-text-2: #8094a8;
--vp-button-alt-bg: #1e2224;
--vp-button-alt-border: #2d3235;
--vp-c-bg-soft: #1e2224;
--vp-c-divider-light: #2d3235;
--vp-c-divider: #34404c;
--vp-c-black: #22272e;
--vp-c-bg-soft: #2b313a;
}
.VPHome .clip {
font-weight: 500;
font-size: 1.5em;
margin-bottom: 0.5em;
display: inline-block;
}
.VPHome .VPButton.brand {
border-color: #0083ff;
color: #fff;
background-color: #0083ff;
&:hover {
border-color: #007cf0;
color: #fff;
background-color: #007cf0;
}
}
/** 一起摇摆 **/
.wave {
display: inline-block;
transform-origin: center bottom;
animation: upAnimation 2.33s ease 0.8s 3 both;
}
@keyframes upAnimation {
0% {
transform: rotate(0deg);
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
10% {
transform: rotate(-12deg);
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
20% {
transform: rotate(12deg);
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
28% {
transform: rotate(-10deg);
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
36% {
transform: rotate(10deg);
transition-timing-function: cubic-bezier(0.755, 0.5, 0.855, 0.06);
}
42% {
transform: rotate(-8deg);
transition-timing-function: cubic-bezier(0.755, 0.5, 0.855, 0.06);
}
48% {
transform: rotate(8deg);
transition-timing-function: cubic-bezier(0.755, 0.5, 0.855, 0.06);
}
52% {
transform: rotate(-4deg);
transition-timing-function: cubic-bezier(0.755, 0.5, 0.855, 0.06);
}
56% {
transform: rotate(4deg);
transition-timing-function: cubic-bezier(0.755, 0.5, 0.855, 0.06);
}
60% {
transform: rotate(0deg);
transition-timing-function: cubic-bezier(0.755, 0.5, 0.855, 0.06);
}
100% {
transform: rotate(0deg);
transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
}
.vp-doc > div > img {
max-width: 100%;
margin: 1.5em auto;
}
img[atk-emoticon] {
display: initial;
}
/* 由于 body 未添加一致的 transition,导致其他地方暗黑模式切换加 transition 比较怪 */
.vp-doc div[class*='language-'] {
transition: none;
}
.vp-doc :not(pre) > code {
transition: none;
}
.vp-doc {
table {
border-collapse: collapse;
margin: 1rem 0;
display: block;
overflow-x: auto;
}
td,
th {
padding: 0.6em 1em;
}
}
/* 侧边栏 */
.VPSidebar::-webkit-scrollbar {
width: 7px;
}
.VPSidebar::-webkit-scrollbar-track {
background-color: transparent;
}
.VPSidebar::-webkit-scrollbar-thumb {
background-color: var(--vp-c-divider);
}
// details block patch
.custom-block.details > summary {
cursor: pointer;
}
.vp-code-group .tabs > * {
color: var(--vp-c-text-1) !important;
}
.vp-code-group .tabs::after {
background-color: var(--vp-c-divider);
}
+5
View File
@@ -0,0 +1,5 @@
declare module '*.vue' {
import { defineComponent } from 'vue'
const component: ReturnType<typeof defineComponent>
export default component
}
+20
View File
@@ -0,0 +1,20 @@
# Artalk Documentation
[![Netlify Status](https://api.netlify.com/api/v1/badges/6580cce0-4b27-465e-8d73-1e6a832942e9/deploy-status)](https://app.netlify.com/sites/artalk/deploys)
Documentation of Artalk
## Build
```bash
pnpm dev:docs
pnpm build:docs
```
## Deploy
文档通过 [Netlify](https://www.netlify.com/) 对 master 分支进行自动部署。
## Licensed
CC BY-NC-SA 4.0
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

+3
View File
@@ -0,0 +1,3 @@
{
"latest": "2.9.0"
}
+17
View File
@@ -0,0 +1,17 @@
<!-- CSS -->
<link href="http://localhost:8080/dist/Artalk.css" rel="stylesheet">
<!-- JS -->
<script src="http://localhost:8080/dist/Artalk.js"></script>
<!-- Artalk -->
<div id="Comments"></div>
<script>
Artalk.init({
el: '#Comments', // 绑定元素的 Selector
pageKey: '/post/1', // 固定链接
pageTitle: '关于引入 Artalk 这档子事', // 页面标题 (留空自动获取)
server: 'http://localhost:8080', // 后端地址
site: 'Artalk 的博客', // 你的站点名
})
</script>
@@ -0,0 +1,4 @@
$ tar xvzf artalk.tar.gz
$ cd artalk
$ vim artalk.yml
$ ./artalk server
+592
View File
@@ -0,0 +1,592 @@
# HTTP API
::: warning
该 HTTP API 文档已过时
:::
::: tip 无特殊说明时 API 调用响应格式
| 字段名 | 类型 | 说明 |
| --------- | ------- | --------------------------------------------- |
| `success` | Boolean | 接口调用结果 |
| `msg` | String | 返回消息,出错时此字段包含错误消息 |
| `data` | Any | 返回数据,可能为 Object / String / Array 类型 |
:::
## Normal API
### 评论新增
**POST** `/api/add`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------------ | -------- | :--: | ------------------------------------------------- |
| `name` | String | 是 | 待新增评论者昵称 |
| `email` | String | 是 | 待新增评论者邮箱 |
| `link` | String | 否 | 待新增评论者链接 |
| `content` | String | 是 | 待新增评论内容 |
| `rid` | Number | 否 | 待新增评论为回复评论时传入父评论 `ID`,否则为 `0` |
| `page_key` | String | 是 | 待新增评论目标页面唯一标识符 |
| `page_title` | String | 否 | 待新增评论目标页面标题 |
| `token` | String | 否 | 评论请求 Token |
| `site_name` | String | 否 | 待新增评论目标站点名称 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| ------------------------------ | -------- | :----: | -------------------------------------- |
| `success` | Boolean | `true` | 评论新增成功 |
| `data.comment` | Object | - | 评论数据 |
| `data.comment.id` | Number | - | 评论 ID |
| `data.comment.content` | String | - | 评论正文 |
| `data.comment.nick` | String | - | 评论者昵称 |
| `data.comment.email_encrypted` | String | - | 评论者邮箱 SHA256 加密值 |
| `data.comment.link` | String | - | 评论者链接 |
| `data.comment.ua` | String | - | 评论者 User-Agent |
| `data.comment.date` | String | - | 评论时间,格式为 `1970-01-01 00:00:00` |
| `data.comment.is_collapsed` | Boolean | - | 评论是否折叠 |
| `data.comment.is_pending` | Boolean | - | 评论是否待审 |
| `data.comment.is_allow_reply` | Boolean | - | 评论是否允许回复 |
| `data.comment.rid` | Number | `0` | 待新增评论为回复评论时返回父评论 `ID` |
| `data.comment.badge_name` | String | - | 评论者徽章文字 |
| `data.comment.badge_color` | String | - | 评论者徽章颜色 |
| `data.comment.visible` | Boolean | `true` | 评论是否可见 |
| `data.comment.vote_up` | Number | `0` | 评论赞同数 |
| `data.comment.vote_down` | Number | `0` | 评论反对数 |
| `data.comment.page_key` | String | - | 评论所在页面唯一标识符 |
| `data.comment.site_name` | String | - | 评论所在站点名称 |
### 评论获取
**POST** `/api/get`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ----------- | -------- | :--: | -------------------------- |
| `page_key` | String | 是 | 待获取评论页面的唯一标识符 |
| `limit` | Number | 否 | 待获取评论的数量限制 |
| `offset` | Number | 否 | 待获取评论的起始位置偏移 |
| `type` | String | 否 | 获取指定类型的评论 |
| `name` | String | 否 | 获取指定昵称的评论 |
| `email` | String | 否 | 获取指定邮箱的评论 |
| `site_name` | String | 否 | 获取指定站点名称的评论 |
| `flat_mode` | Boolean | 否 | 待获取评论是否平铺模式 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| ---------------------- | -------- | :----: | ------------------------------ |
| `success` | Boolean | `true` | 评论获取成功 |
| `data.comments` | Array | - | 页面评论数据 |
| `data.total` | Number | - | 页面评论总数(包括所有子评论) |
| `data.total_parents` | Number | - | 页面评论中父级评论总数 |
| `data.page` | Object | - | 页面数据 |
| `data.page.id` | Number | - | 页面 ID |
| `data.page.admin_only` | Boolean | - | 页面是否仅管理员可评论 |
| `data.page.key` | String | - | 页面唯一标识符 |
| `data.page.url` | String | - | 页面链接 |
| `data.page.title` | String | - | 页面标题 |
| `data.page.site_name` | String | - | 页面所在站点名称 |
| `data.page.vote_up` | Number | - | 页面赞同数 |
| `data.page.vote_down` | Number | - | 页面反对数 |
| `data.unread` | Array | - | 未读的评论提醒数据 |
| `data.unread_count` | Number | - | 未读的评论提醒数据总数 |
| `data.api_version` | Object | - | 目标 Artalk 后端版本数据 |
::: tip
- `data.comments` 数组中元素结构参考 [评论新增接口](#评论新增) `/api/add` 响应的 `data.comment`
- `data.unread` 数组中元素结构如下
| 字段名 | 数据类型 | 默认 | 说明 |
| ----- | ------- | :-: | --- |
| `id` | Number | - | 评论提醒 ID |
| `user_id` | Number | - | 评论提醒目标用户 ID |
| `comment_id` | Number | - | 评论提醒来源评论 ID |
| `is_read` | Boolean | - | 评论提醒是否已读 |
| `is_emailed` | Boolean | - | 评论提醒是否已发送邮件 |
| `read_link` | String | - | 评论提醒已读地址 |
- `data.api_version` 对象结构参考 [Artalk 版本接口](#artalk-版本) `/api/version` 响应
:::
### 用户获取
**POST** `/api/user-get`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------- | -------- | :--: | ---------------- |
| `name` | String | 否 | 待获取用户的昵称 |
| `email` | String | 否 | 待获取用户的邮箱 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| ----------------------- | -------- | :----: | ---------------------------------- |
| `success` | Boolean | `true` | 用户获取成功 |
| `data.user` | Object | `null` | 获取的用户数据,若用户不存在返回空 |
| `data.user.id` | Number | - | 用户 ID |
| `data.user.name` | String | - | 用户昵称 |
| `data.user.email` | String | - | 用户邮箱 |
| `data.user.link` | String | - | 用户链接 |
| `data.user.badge_name` | String | - | 用户徽章文字 |
| `data.user.badge_color` | String | - | 用户徽章颜色 |
| `data.user.is_admin` | Boolean | - | 用户是否管理员 |
| `data.is_login` | Boolean | - | 用户是否登录 |
| `data.unread` | Array | `[]` | 用户未读的评论提醒数据 |
| `data.unread_count` | Number | `0` | 用户未读的评论提醒数据总数 |
::: tip
- `data.unread` 数组中元素结构参考 [评论获取接口](#评论获取) `/api/get` **TIP**
:::
### 用户登录
**GET/POST** `/api/login`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ---------- | -------- | :--: | ---------------------------------- |
| `name` | String | 是 | 待登录用户的昵称 |
| `email` | String | 是 | 待登录用户的邮箱 |
| `password` | String | 是 | 待登录用户的密码(管理员身份验证) |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| ------------ | -------- | :----: | ---------------- |
| `success` | Boolean | `true` | 用户登录成功 |
| `data.token` | String | - | 登录的用户 Token |
### 提醒已读
**POST** `/api/mark-read`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------------ | -------- | :--: | -------------------- |
| `notify_key` | String | 否 | 评论提醒唯一标识符 |
| `name` | String | 否 | 评论提醒用户的昵称 |
| `email` | String | 否 | 评论提醒用户的邮箱 |
| `all_read` | Boolean | 否 | 评论提醒是否已读 |
| `site_name` | String | 否 | 评论提醒所在站点名称 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------- | -------- | :----: | ------------ |
| `success` | Boolean | `true` | 提醒已读成功 |
### 评论投票
**POST** `/api/vote`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ----------- | -------- | :--: | ----------------------------------------------------------------------------------------------------------- |
| `target_id` | Number | 是 | 待投票评论 ID |
| `type` | String | 否 | 待投票类型,前缀 `comment_`、`page_` 依次代表对评论投票、对页面投票,后缀 `_up`、`_down` 依次代表赞同、反对 |
| `name` | String | 否 | 投票用户昵称 |
| `email` | String | 否 | 投票用户邮箱 |
| `site_name` | String | 否 | 投票目标评论或页面所在站点名称 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------------- | -------- | :----: | ------------------------------ |
| `success` | Boolean | `true` | 评论投票成功 |
| `data.vote_num` | Number | - | 目标评论或页面指定类型投票数据 |
### Artalk 版本
::: warning
此接口较特殊,返回结果不包含 `success`、`msg`、`data` 字段,直接返回包含指定字段的 JSON。
:::
**GET/POST** `/api/version`
**参数** 无
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| ---------------- | -------- | :------: | ------------------------------- |
| `app` | String | `artalk` | Artalk 后端程序名 |
| `version` | String | - | Artalk 后端程序版本号 |
| `commit_hash` | String | - | Artalk 后端程序 Git 提交哈希值 |
| `fe_min_version` | String | - | Artalk 后端程序所需前端最低版本 |
## Captcha API
### 验证码刷新
**GET** `/api/captcha/refresh`
**参数** 无
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------------- | -------- | :----: | ------------------------------------ |
| `success` | Boolean | `true` | 验证码刷新成功 |
| `data.img_data` | String | - | 根据 IP 获取的验证码图片 Base64 编码 |
### 验证码检验
**GET** `/api/captcha/check`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------- | -------- | :--: | ------ |
| `value` | String | 是 | 验证码 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------------- | -------- | :----: | -------------------------------------------------------- |
| `success` | Boolean | `true` | 验证码检验成功 |
| `data.img_data` | String | - | 新的验证码图片 Base64 编码,仅验证码检验出错时存在此字段 |
## Admin API
### 评论编辑
**POST** `/api/admin/comment-edit`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| -------------- | -------- | :--: | ------------------------------------------------- |
| `id` | Number | 是 | 待编辑评论 ID,**不可修改** |
| `site_name` | String | 否 | 待编辑评论所在站点名称,**不可修改** |
| `content` | String | 否 | 待编辑评论正文 |
| `page_key` | String | 否 | 待编辑评论所在页面唯一标识符 |
| `nick` | String | 否 | 待编辑评论所属用户昵称 |
| `email` | String | 否 | 待编辑评论所属用户邮箱 |
| `link` | String | 否 | 待编辑评论所属用户链接 |
| `rid` | String | 否 | 待编辑评论为回复评论时传入父评论 `ID`,否则为 `0` |
| `ua` | String | 否 | 待编辑评论所属用户 User-Agent |
| `ip` | String | 否 | 待编辑评论所属用户 IP |
| `is_collapsed` | Boolean | 否 | 待编辑评论是否折叠 |
| `is_pending` | Boolean | 否 | 待编辑评论是否待审 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| -------------- | -------- | :----: | ---------------- |
| `success` | Boolean | `true` | 评论编辑成功 |
| `data.comment` | Object | - | 编辑评论的新数据 |
::: tip
- `data.comment` 对象结构参考 [评论新增接口](#评论新增) `/api/add` 响应的 `data.comment`
:::
### 评论删除
::: danger
此接口不推荐外部调用。
调用此接口前请务必核实评论 ID,一旦调用成功将删除该评论下所有相关数据。
:::
**POST** `/api/admin/comment-del`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ----------- | -------- | :--: | ---------------------- |
| `id` | Number | 是 | 待删除评论 ID |
| `site_name` | String | 是 | 待删除评论所在站点名称 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------- | -------- | :----: | ------------ |
| `success` | Boolean | `true` | 评论删除成功 |
### 页面获取
**POST** `/api/admin/page-get`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ----------- | -------- | :--: | ---------------------- |
| `site_name` | String | 是 | 待获取页面目标站点名称 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| ------------ | -------- | :----: | ------------------ |
| `success` | Boolean | `true` | 页面获取成功 |
| `data.pages` | Array | - | 目标站点的页面数据 |
| `data.sites` | Array | - | 所有站点数据 |
::: tip
- `data.pages` 数组中元素结构参考 [评论获取接口](#评论获取) `/api/get` 响应的 `data.page`
- `data.sites` 数组中元素结构参考 [站点编辑接口](#站点编辑) `/api/admin/site-edit` 响应的 `data.site`
:::
### 页面编辑
**POST** `/api/admin/page-edit`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------------ | -------- | :--: | ------------------------------------ |
| `id` | Number | 是 | 待编辑页面 ID,**不可修改** |
| `site_name` | String | 否 | 待编辑页面所在站点名称,**不可修改** |
| `key` | String | 否 | 待编辑页面唯一标识符 |
| `title` | String | 否 | 待编辑页面标题 |
| `admin_only` | Boolean | 否 | 待编辑页面是否仅管理员可评论 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| ----------- | -------- | :----: | ---------------- |
| `success` | Boolean | `true` | 页面编辑成功 |
| `data.page` | Object | - | 编辑页面的新数据 |
::: tip
- `data.page` 对象结构参考 [评论获取接口](#评论获取) `/api/get` 响应的 `data.page`
:::
### 页面删除
::: danger
此接口不推荐外部调用。
调用此接口前请务必核实页面 ID,一旦调用成功将删除该页面下所有相关数据。
:::
**POST** `/api/admin/page-del`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ----------- | -------- | :--: | ---------------------- |
| `key` | String | 是 | 待删除页面唯一标识符 |
| `site_name` | String | 是 | 待删除页面所在站点名称 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------- | -------- | :----: | ------------ |
| `success` | Boolean | `true` | 页面删除成功 |
### 页面更新
**POST** `/api/admin/page-fetch`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------ | -------- | :--: | ------------- |
| `id` | Number | 是 | 待更新页面 ID |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| ----------- | -------- | :----: | ---------------- |
| `success` | Boolean | `true` | 页面更新成功 |
| `data.page` | Object | - | 更新页面的新数据 |
::: tip
- `data.page` 对象结构参考 [评论获取接口](#评论获取) `/api/get` 响应的 `data.page`
:::
### 站点获取
**POST** `/api/admin/site-get`
**参数** 无
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| ------------ | -------- | :----: | ------------ |
| `success` | Boolean | `true` | 站点获取成功 |
| `data.sites` | Array | - | 所有站点数据 |
::: tip
- `data.sites` 数组中元素结构参考 [站点编辑接口](#站点编辑) `/api/admin/site-edit` 响应的 `data.site`
:::
### 站点新增
**POST** `/api/admin/site-add`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------ | -------- | :--: | ------------------------------------------------- |
| `name` | String | 是 | 待新增站点名称 |
| `urls` | String | 是 | 待新增站点链接,如有多个需以英文半角符号 `,` 分割 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------------------- | -------- | :----: | ----------------------------------------------- |
| `success` | Boolean | `true` | 站点新增成功 |
| `data.site` | Object | - | 新增站点的数据 |
| `data.site.id` | Number | - | 站点 ID |
| `data.site.name` | String | - | 站点名称 |
| `data.site.urls` | Array | - | 站点链接数组,元素为单个站点链接字符串 |
| `data.site.urls_raw` | String | - | 站点链接数组合并字符串,以英文半角符号 `,` 分割 |
| `data.site.first_url` | String | - | 站点第一链接 |
### 站点编辑
**POST** `/api/admin/site-edit`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------ | -------- | :--: | ---------------- |
| `id` | Number | 是 | 待编辑站点 ID |
| `name` | String | 是 | 待编辑站点新名称 |
| `urls` | String | 是 | 待编辑站点新链接 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------------------- | -------- | :----: | ----------------------------------------------- |
| `success` | Boolean | `true` | 站点编辑成功 |
| `data.site` | Object | - | 编辑站点的新数据 |
| `data.site.id` | Number | - | 站点 ID |
| `data.site.name` | String | - | 站点名称 |
| `data.site.urls` | Array | - | 站点链接数组,元素为单个站点链接字符串 |
| `data.site.urls_raw` | String | - | 站点链接数组合并字符串,以英文半角符号 `,` 分割 |
| `data.site.first_url` | String | - | 站点第一链接 |
### 站点删除
::: danger
此接口不推荐外部调用。
调用此接口前请务必核实站点 ID,一旦调用成功将删除该站点下所有相关数据。
:::
**POST** `/api/admin/site-del`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------------- | -------- | :--: | ------------------------------------------------------------------- |
| `id` | Number | 是 | 待删除站点 ID |
| `del_content` | Boolean | 否 | 是否删除站点所有数据,为 `false` 时仅删除站点配置而保留站点评论数据 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------- | -------- | :----: | ------------ |
| `success` | Boolean | `true` | 站点删除成功 |
### 设置获取
**POST** `/api/admin/setting-get`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------ | -------- | :--: | -------------- |
| `id` | Number | 是 | 管理员用户 ID |
| `name` | String | 否 | 管理员用户昵称 |
| `url` | String | 否 | 管理员用户链接 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------- | -------- | :----: | ------------ |
| `success` | Boolean | `true` | 设置获取成功 |
### 设置保存
**POST** `/api/admin/setting-save`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| ------ | -------- | :--: | -------------- |
| `id` | Number | 是 | 管理员用户 ID |
| `name` | String | 否 | 管理员用户昵称 |
| `url` | String | 否 | 管理员用户链接 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------- | -------- | :----: | ------------ |
| `success` | Boolean | `true` | 设置保存成功 |
### 邮件发送
::: warning
页面收到评论、评论收到回复等满足需要发送邮件提醒条件时,后端将自动向目标地址发送邮件提醒,不需手动处理邮件发送。请勿滥用此接口。
:::
**POST** `/api/admin/send-mail`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| --------- | -------- | :--: | ---------- |
| `subject` | String | 是 | 邮件主题 |
| `body` | String | 是 | 邮件正文 |
| `to_addr` | String | 是 | 邮件收件人 |
**响应**
| 字段名 | 数据类型 | 默认 | 说明 |
| --------- | -------- | :----: | ------------ |
| `success` | Boolean | `true` | 邮件发送成功 |
### Artrans 接口
::: warning
此接口暂不稳定,请避免使用!
:::
**POST** `/api/admin/artransfer`
**参数**
| 字段名 | 数据类型 | 必需 | 说明 |
| --------- | -------- | :--: | ------------ |
| `type` | String | 是 | 导入数据类型 |
| `payload` | String | 否 | 导入数据 |
**响应** 无
+3
View File
@@ -0,0 +1,3 @@
# HTTP API
参考:<a href="/http-api.html" target="_blank">Artalk API 文档 (OpenAPI)</a>
+18
View File
@@ -0,0 +1,18 @@
# 兼容性
## 浏览器兼容性
Artalk 客户端生产环境代码的构建通过 esbuild 执行,构建目标为 `es2015`。但请注意,构建仅会处理语法转义遵循 `es2015` 标准,不会处理 API 的兼容性(不包含任何 polyfill)。
如果你的项目需要支持较旧的浏览器和设备,请考虑在捆绑应用程序中包含全局 polyfill。我们推荐使用 [Polyfill.io](https://polyfill.io/) 服务,它会根据用户的 User-Agent 动态返回所需的 polyfill。另外,你也可以使用 [core-js](https://github.com/zloirock/core-js) 或 [Babel](https://babeljs.io/) 来手动添加 polyfill。
以下是 Artalk 使用的现代功能的列表:
- [All ECMAScript 2015 (ES6) features](https://compat-table.github.io/compat-table/es6/)
- [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
- [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
- [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
## 服务器兼容性
Artalk 服务端程序基于 Golang 开发,支持 Linux、Windows 和 macOS 等操作系统。当前 Artalk 的 Golang 版本可通过 [go.mod](https://github.com/ArtalkJS/Artalk/blob/master/go.mod#L3) 查看。关于 Golang 的最低操作系统要求,可参考 [Go Wiki](https://go.dev/wiki/MinimumRequirements)。
+298
View File
@@ -0,0 +1,298 @@
# 开发者贡献指南
本指南帮助开发者了解如何在 Artalk 项目中贡献代码、文档、测试和反馈。我们欢迎所有形式的贡献,无论是大型功能开发、小型修复、文档改进还是测试。我们相信每一个贡献都是推动项目前进的重要一环。
本指南包含多语言版本:[English](https://github.com/ArtalkJS/Artalk/blob/master/CONTRIBUTING.md) • [简体中文](https://artalk.js.org/develop/contributing.html)
## 克隆仓库
克隆仓库:
```sh
git clone https://github.com/ArtalkJS/Artalk.git
```
建议您先 fork 仓库,然后克隆 fork 后的仓库。
导航到目录:
```sh
cd Artalk
```
## 开发环境
为了开发 Artalk 的前端和后端,请安装以下工具:
- [Node.js](https://nodejs.org/en/) (>= 20.17.0)
- [PNPM](https://pnpm.io/) (>= 9.9.0)
- [Go](https://golang.org/) (>= 1.22)
- [Docker](https://www.docker.com/) (>= 20.10.0)(可选)
- [Docker Compose](https://docs.docker.com/compose/) (>= 1.29.0)(可选)
## 开发工作流程概述
开发工作流程包括以下步骤:
1. **搭建完整的开发实例**:
- 导航到 Artalk 仓库目录。
- 执行 `make dev` 在端口 `23366` 上运行后端。
- 执行 `pnpm dev` 在端口 `5173` 上运行前端。
- 可选地,执行 `pnpm dev:sidebar` 在端口 `23367` 上运行侧边栏前端。
2. **访问前端进行开发**:
- 打开浏览器,访问 `http://localhost:5173` 进行开发和测试。
3. **测试**:
- 使用 `make test` 运行后端单元测试。
- 使用 `pnpm test` 运行 UI 单元测试。
- 使用 `make test-frontend-e2e` 运行 UI 端到端测试。
4. **构建前端代码**:
- 当您对前端代码进行更改后,使用 `pnpm build:all` 构建完整的前端程序。
- JavaScript 和 CSS 代码将在 `ui/artalk/dist` 目录中找到。
- 前端代码由 GitHub Actions 自动部署到 NPM。
5. **构建后端代码**:
- 当您对后端代码进行更改后,注意后端程序会嵌入前端代码。
- 在构建后端之前,运行 `make build-frontend`(它运行 `scripts/build-frontend.sh`)。这将把嵌入的前端主程序和侧边栏前端程序放入 `/public` 目录。
- 然后,使用 `make build` 构建后端程序。
更多探索:
- **开发 Artalk 插件或主题**:
请参考 [Artalk 插件开发指南](https://artalk.js.org/develop/plugin.html)。
- **Makefile**:
您可以探索 `Makefile` 中的过程和命令。
- **GitHub 上的自动化 CI**:
GitHub 上的自动化 CI 流水线位于 `.github/workflows` 目录中,负责构建前端、后端和 Docker 镜像,发布 Docker 镜像到 Docker Hub,处理 npm 包发布,并创建 GitHub Releases,同时测试前端和后端。
以下部分提供了更详细的开发工作流程信息。
## 项目结构
Artalk 是一个 monorepo 项目,这意味着所有源代码都在一个仓库中。尽管如此,前端和后端保持分离。前端部分位于 `./ui` 目录中。
### 目录概览
- `bin/`:编译的二进制文件。(此目录被 git 忽略)
- `cmd/`:命令行工具的源代码。
- `conf/`:示例配置文件。
- `data/`:本地数据。(此目录被 git 忽略)
- `docs/`:文档站点的源代码。
- `i18n/`:翻译文件。
- `local/`:本地文件。(此目录被 git 忽略)
- `internal/`:内部包的 Go 源代码。
- `public/`:静态文件。构建的前端文件将被复制到这里。
- `scripts/`:开发和构建的脚本。
- `server/`:后端的 Go 源代码。
- `ui/`:前端的 UI 源代码。
- `.github/`:GitHub Actions 工作流。
- `.vscode/`:VSCode 设置。
## 后端开发
### 运行后端
1. **创建配置文件**:
- 将 `./conf/artalk.example.yml` 复制到根目录。
- 重命名为 `artalk.yml`。
- 根据需要修改文件。
2. **启动后端程序**:
- 运行 `make dev` 启动后端,端口为 `23366`。
- 通过 `http://localhost:23366` 访问。
- 建议保留默认端口进行测试。
- (替代)使用 `ARGS="version" make dev` 传递启动参数(默认是 `ARGS="server"`)。
`make dev` 命令会带有调试符号构建后端,这方便使用 GDB 进行调试。
如果您使用 VSCode,可以使用 `F5` 键(或运行按钮)直接启动调试后端程序。
### 构建后端
1. **获取最新的 Git 标签**:
执行 `git fetch --tags` 获取最新的 Git 标签信息。此标签将用作后端应用程序的版本号。或者,通过环境变量指定:`VERSION="v1.0.0"` 和 `COMMIT_HASH="66128e"`。
2. **构建前端**:
运行 `make build-frontend` 构建前端,因为后端应用程序会嵌入前端代码。
3. **构建后端**:
执行 `make build` 构建后端程序。
构建的二进制文件将位于 `./bin` 目录中。
## 前端开发(UI)
### 运行前端
1. **安装依赖**:
运行 `pnpm install` 安装所有必要的依赖。
2. **启动开发服务器**:
执行 `pnpm dev --port 5173` 启动前端开发服务器。
3. **访问前端**:
前端应用程序默认将在端口 `5173` 上运行。在浏览器中访问 `http://localhost:5173`。
4. **侧边栏开发**:
要运行侧边栏部分的前端,请使用 `pnpm dev:sidebar`。
端口 `5173` 和 `23367` 用于前端开发和测试。这些端口被包括在后端程序的 `ATK_TRUSTED_DOMAINS` 配置中。
### 构建前端
要构建前端,请运行以下命令:
```sh
make build-frontend
```
编译的 JavaScript 和 CSS 文件将位于 `/public` 目录中,嵌入到后端程序中。
更多详细信息,请参考 `scripts/build-frontend.sh` 脚本。
## Docker 开发
### 构建 Docker 镜像
要构建 Docker 镜像,请运行以下命令:
```sh
docker build -t artalk:TAG .
```
将 `TAG` 替换为所需的标签名(例如 `latest`)。
### 跳过前端构建
如果您已经在 Docker 容器外部构建了前端,可以跳过容器内的前端构建过程以加快构建速度。使用以下命令:
```sh
docker build --build-arg SKIP_FRONTEND_BUILD=true -t artalk:latest .
```
更多详细信息,请参考 `Dockerfile`。
## 测试
### 测试后端
要测试后端 Go 程序,可以使用以下命令:
- **单元测试**:
运行 `make test` 执行单元测试。结果将输出在终端。
- **测试覆盖率**:
运行 `make test-coverage` 检查代码测试覆盖率。
- **HTML 覆盖率报告**:
运行 `make test-coverage-html` 生成并浏览 HTML 格式的测试覆盖率报告。
- **运行特定测试**:
要运行特定测试,请使用带有环境变量的命令:
```sh
TEST_PATHS="./server/..." make test
```
### 测试前端
前端测试包括单元测试和端到端(E2E)测试。
- **单元测试**:
前端的单元测试使用 Vitest 进行。运行 `pnpm test` 开始单元测试。
- **端到端测试**:
E2E 测试使用 Playwright 进行。要启动 E2E 测试,运行:
```sh
make test-frontend-e2e
```
### 持续集成测试
前端和后端的测试都是自动化的,并将在 Git pull 请求和构建过程中使用 CircleCI 或 GitHub Actions 执行。
## 配置
模板配置文件位于 `/conf` 目录中,模板以多种语言注释,命名格式为 `artalk.example.[lang].yml`(例如,`artalk.example.zh-CN.yml`)。Artalk 将解析这些模板配置文件以生成设置界面、环境变量名称和文档。为了提高性能,程序运行期间将缓存部分数据以消除解析时间。
在 `internal/config/config.go` 文件中,有一个名为 `Config` 的结构体定义,该结构体用于将 yml 文件解析为 Go 结构体。该结构体包含更精确的类型定义。如果需要添加、修改或删除配置项,必须同时修改 `/conf` 目录中的配置文件模板和 `Config` 结构体。
当您修改配置文件后,请运行以下命令以更新配置数据缓存:
```sh
make update-conf
```
要更新环境变量文档,可以运行以下命令:
```sh
make update-conf-docs
```
## 文档
文档由三个部分组成,每个部分与特定包相关:**指南文档**、**着陆页**和 **Swagger API 文档**。下面是每个包的相关命令及其输出的总结。
### 指南文档 (`docs`)
- **目录**:`docs/docs/guide`
- **开发命令**:`pnpm -F docs dev:docs`
- **构建命令**:`pnpm -F docs build:docs`
- **输出目录**:`docs/docs/.vitepress/dist`
### 着陆页 (`docs-landing`)
- **目录**:`docs/landing`
- **开发命令**:`pnpm -F docs-landing dev:landing`
- **构建命令**:`pnpm -F docs-landing build:landing`
- **输出目录**:`docs/landing/dist`
### Swagger API 文档 (`docs-swagger`)
- **目录**:`docs/swagger`
- **构建命令**:`make update-swagger`
- **输出目录**:`docs/swagger`
Swagger 定义位于后端代码的 `/server` 目录中。修改 Swagger 定义后,运行构建命令将更新 Swagger 文档并在 `/ui/artalk/src/api/v2.ts` 生成 HTTP 客户端代码。
### 综合构建
- **构建所有包的命令**:`pnpm build:docs`
- **综合输出目录**:`docs/docs/.vitepress/dist`
此命令构建并组合所有三个包到单个目录中,准备发布。
### 环境变量文档
- **文件**:`docs/docs/guide/env.md`
- **更新命令**:`make update-conf-docs`
此命令读取位于 `/conf` 的配置模板文件以更新环境变量文档。在修改配置模板文件后运行此命令。
## 翻译 (i18n)
如果您编写了新功能或进行了修复/重构,请使用以下命令通过解析源代码中的 `i18n.T` 函数调用来增量生成翻译文件:
```sh
make update-i18n
```
如果您不是程序员,但希望帮助改进翻译,可以直接编辑 `/i18n` 目录中的翻译文件,然后提交 pull 请求。
## 结尾
感谢您耐心阅读本指南,并感谢您对 Artalk 的兴趣和支持。我们深知,一个开源项目的成功依赖于每一位开发者的贡献。无论是通过代码、文档、测试还是反馈,您的参与是推动项目持续进步的动力。我们诚挚邀请您加入我们,共同改进和增强 Artalk。
通过合作,我们可以创建一个更加健壮和多功能的平台,造福整个社区。您的独特见解和专业知识是无价的,只有共同努力,我们才能实现显著的进步。无论您是经验丰富的开发者,还是刚刚起步的新手,我们的项目中总有您可以贡献的一席之地。
如果您有任何问题或需要帮助,请随时在我们的 GitHub 页面上的 issue 部分提问:<https://github.com/ArtalkJS/Artalk/issues>。再次感谢您的支持,我们期待与您合作。
+50
View File
@@ -0,0 +1,50 @@
# Frontend Event
## 基本事件
| 事件名 | 描述 |
| ------------------- | -------------------- |
| `created` | 初始化后 |
| `mounted` | 数据加载后 |
| `updated` | 数据更新后 |
| `unmounted` | 销毁后 |
| `list-fetch` | 评论列表请求时 |
| `list-fetched` | 评论列表请求后 |
| `list-load` | 评论装载前 |
| `list-loaded` | 评论装载后 |
| `list-failed` | 评论加载错误时 |
| `list-goto-first` | 评论列表归位时 |
| `list-reach-bottom` | 评论列表滚动到底部时 |
| `comment-inserted` | 评论插入后 |
| `comment-updated` | 评论更新后 |
| `comment-deleted` | 评论删除后 |
| `comment-rendered` | 评论节点渲染后 |
| `notifies-updated` | 未读消息变更时 |
| `list-goto` | 评论跳转时 |
| `page-loaded` | 页面数据更新后 |
| `editor-submit` | 编辑器提交时 |
| `editor-submitted` | 编辑器提交后 |
| `user-changed` | 本地用户数据变更时 |
| `sidebar-show` | 侧边栏显示 |
| `sidebar-hide` | 侧边栏隐藏 |
事件声明代码:[@ArtalkJS/Artalk - src/types/event.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/types/event.ts)
## 添加事件监听
```js
artalk.on('list-loaded', () => {
alert('评论已加载完毕')
})
```
## 解除事件监听
```js
let foo = function () {
/* do something */
}
artalk.on('list-loaded', foo)
artalk.off('list-loaded', foo)
```
+195
View File
@@ -0,0 +1,195 @@
# Frontend API
## 安装依赖
用你喜欢的包管理器安装 Artalk:
```bash
pnpm add artalk
# 或者使用 npm
npm install artalk
```
## 创建实例 `init`
调用该函数将创建并得到一个 Artalk 的实例化对象,可用于后续操作。
<!-- prettier-ignore-start -->
```js
import Artalk from 'artalk'
const artalk = Artalk.init({
el: '#Comments',
pageKey: '/post/1',
pageTitle: '关于引入 Artalk 的这档子事',
server: 'http://your_domain:8080',
site: 'Artalk 的博客',
})
```
<!-- prettier-ignore-end -->
调用该函数会异步地向后端发起请求:
1. 获取前端配置
2. 获取评论列表
配置和插件加载完毕后会触发 `mounted` 事件。
评论列表加载完毕后会触发 `list-loaded` 事件。
> 注:前端界面配置可能会被覆盖,详情见:[界面配置](../guide/frontend/config.md)。
## 释放资源 `destroy`
销毁 Artalk 实例,用于资源释放。
```js
const artalk = Artalk.init({ ... })
artalk.destroy()
```
调用该函数时,将触发 `unmounted` 事件。释放资源将执行 Artalk 挂载的 DOM 节点删除,以及解除 Artalk 事件监听等操作。当该函数执行完毕后,Artalk 实例将不再可用。
在 Vue / React 等框架中,务必在组件销毁时调用该函数,否则会造成内存泄漏:
```ts
import { onUnmounted } from 'vue'
onUnmounted(() => {
artalk.destroy()
})
```
## 更新配置 `update`
修改 Artalk 当前配置。
```js
const artalk = Artalk.init({ ... })
artalk.update({
// 新的配置...
})
```
调用该函数将触发 `updated` 事件。
更新配置不会自动刷新评论列表,可按需继续执行 `artalk.reload()` 函数。
请注意,该函数是一个实例化对象中的成员方法,并非全局函数。
前端配置参考:[前端配置](../guide/frontend/config.md)
## 重新加载 `reload`
重新从后端加载 Artalk 评论列表数据。
```js
const artalk = Artalk.init({ ... })
artalk.reload()
```
列表加载前将触发 `list-load` 事件,加载完毕后将触发 `list-loaded` 事件。
## 监听事件 `on`
添加 Artalk 事件监听。
```js
const artalk = Artalk.init({ ... })
artalk.on('list-loaded', (comments) => {
// comments 包含当前页面所有评论数据 (而非仅本次请求获取的部分评论)
console.log('评论列表加载完毕: ', comments)
})
```
可参考:[前端 Event](./event.md)。
## 解除监听 `off`
解除 Artalk 事件监听。
```js
const artalk = Artalk.init({ ... })
const handler = () => {
alert('评论列表加载完毕')
}
artalk.on('list-loaded', handler)
artalk.off('list-loaded', handler)
```
## 触发事件 `trigger`
触发 Artalk 事件。
```js
const artalk = Artalk.init({ ... })
artalk.trigger('list-loaded', [...])
```
## 加载插件 `use`
通过 `Artalk.use` 函数加载插件。请注意,该函数是一个全局函数,并非实例化对象中的方法。通过该函数加载的插件将对所有 Artalk 实例生效。
```js
import Artalk from 'artalk'
Artalk.use((ctx) => {
ctx.editor.setContent("Hello World")
})
const artalk = Artalk.init({ ... })
```
详情见:[插件开发](./plugin.md)
## 夜间模式 `setDarkMode`
修改夜间模式,可以配合博客主题调用,例如当用户点击夜间模式切换按钮。
```js
const artalk = Artalk.init({ ... })
artalk.setDarkMode(true)
```
也可以通过调用 `Artalk.init` 时,通过 `darkMode` 参数设置初始夜间模式。
```js
const artalk = Artalk.init({
// ...其他配置
darkMode: 'auto',
})
```
## 浏览量组件 `loadCountWidget`
详情见:[浏览量统计](../guide/frontend/pv.md)
## 获取配置 `getConf`
获取当前 Artalk 配置。
```js
const artalk = Artalk.init({ ... })
const conf = artalk.getConf()
```
## 获取挂载元素 `getEl`
获取当前 Artalk 挂载的 DOM 元素。
```js
const artalk = Artalk.init({ ... })
const el = artalk.getEl()
```
+175
View File
@@ -0,0 +1,175 @@
# 置入博客
## 通用方法
<<< @/code/quick-start/cdn.html
#### 什么时候执行 `Artalk.init({})`?
- 可以在任意位置引入 JS 和 CSS 资源,但需确保 JS 引入在执行 `Artalk.init({})` 前。
- 执行 `Artalk.init({ el: '#artalk' })` 前需要确保 `<div id="artalk"></div>` 在页面当中。
## Hugo
创建模板文件 `/主题目录/layouts/partials/comment/artalk.html`:
<!-- prettier-ignore-start -->
```html
<link href="/lib/artalk/Artalk.css" rel="stylesheet" />
<script src="/lib/artalk/Artalk.js"></script>
<!-- Artalk -->
<div id="Comments"></div>
<script>
Artalk.init({
el: '#Comments',
pageKey: '{{ .Permalink }}',
pageTitle: '{{ .Title }}',
server: '{{ $.Site.Params.artalk.server }}',
site: '{{ $.Site.Params.artalk.site }}',
// ...你的其他配置
})
</script>
```
<!-- prettier-ignore-end -->
文章页模板 `/主题目录/layouts/_default/single.html` 合适的位置添加:
```html
<div class="article-comments">{{- partial "comment/artalk" . -}}</div>
```
修改 Hugo 配置文件:
::: code-group
```toml [config.toml]
[params.artalk]
server = 'https://artalk.example.org'
site = '你的站点名'
```
```yaml [config.yaml]
params:
artalk:
server: 'https://artalk.example.org'
site: '你的站点名'
```
:::
## Hexo
创建 `/主题目录/layout/comment/artalk.ejs`:
```html
<link href="/lib/artalk/Artalk.css" rel="stylesheet" />
<script src="/lib/artalk/Artalk.js"></script>
<div id="Comments"></div>
<script>
var artalk = Artalk.init({
el: '#Comments',
pageKey: '<%= page.permalink %>',
pageTitle: '<%= page.title %>',
server: '<%= theme.comment.artalk.server %>',
site: '<%= theme.comment.artalk.site %>',
})
</script>
```
修改文章模板文件,例如 `/主题目录/layout/post.ejs`:
```html
<div class="article-comments"><%- partial('comment/artalk') %></div>
```
编辑主题配置 `/主题目录/_config.example.yml`:
```yaml
comment:
artalk:
site: '你的站点名'
server: 'https://artalk.example.org'
```
::: tip
NexT 主题可以安装 [Hexo NexT 主题的 Artalk 插件](https://github.com/leirock/hexo-next-artalk)
:::
## VitePress
可参考:[docs/.vitepress](https://github.com/ArtalkJS/Artalk/tree/master/docs/docs/.vitepress)
- `config.ts` 修改配置引入 CSS 资源
- `theme/Artalk.vue` 创建组件
- `theme/index.ts` 注册组件
- `theme/Layout.vue` 使用组件
参考代码:[docs/.vitepress/theme/Artalk.vue](https://github.com/ArtalkJS/Artalk/blob/master/docs/docs/.vitepress/theme/Artalk.vue)
## VuePress
(待补充)
::: tip 提示
可参考:[置入框架](./import-framework.md)
:::
## Typecho
修改主题文章模板文件,例如 `post.php`:
```php
<!-- CSS -->
<link href="/lib/artalk/Artalk.css" rel="stylesheet">
<!-- JS -->
<script src="/lib/artalk/Artalk.js"></script>
<!-- Artalk -->
<div id="Comments"></div>
<script>
Artalk.init({
el: '#Comments',
pageKey: '<?php $this->permalink() ?>',
pageTitle: '<?php $this->title() ?>',
server: '<后端地址>',
site: '<?php $this->options->title() ?>',
// ...你的其他配置
})
</script>
```
## WordPress
修改主题文章模板文件,例如 `single.php`:
```php
<!-- CSS -->
<link href="/lib/artalk/Artalk.css" rel="stylesheet">
<!-- JS -->
<script src="/lib/artalk/Artalk.js"></script>
<!-- Artalk -->
<div id="Comments"></div>
<script>
Artalk.init({
el: '#Comments',
pageKey: '<?= addslashes(get_permalink()) ?>',
pageTitle: '<?= addslashes(get_the_title()) ?>',
server: '<后端地址>',
site: '<?= addslashes(get_bloginfo('name')) ?>',
// ...你的其他配置
})
</script>
```
+227
View File
@@ -0,0 +1,227 @@
# 置入框架
## 安装 Artalk
通过包管理工具引入 Artalk,推荐使用 [pnpm](https://pnpm.io/zh/)
```bash
pnpm add artalk
```
## Vue
::: code-group
```vue [Vue 3]
<script lang="ts" setup>
import Artalk from 'artalk'
import { onMounted, onBeforeUnmount, ref } from 'vue'
import 'artalk/dist/Artalk.css'
const el = ref<HTMLElement>()
let artalk: Artalk
onMounted(() => {
artalk = Artalk.init({
el: el.value,
pageKey: location.pathname,
pageTitle: `${document.title}`,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
})
})
onBeforeUnmount(() => {
artalk.destroy()
})
</script>
<template>
<view ref="el"></view>
</template>
```
```vue [Vue 3 + Vue Router]
<script lang="ts" setup>
import Artalk from 'artalk'
import { onMounted, onBeforeUnmount, ref, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import 'artalk/dist/Artalk.css'
const el = ref<HTMLElement>()
const router = useRouter()
let artalk: Artalk
onMounted(() => {
artalk = Artalk.init({
el: el.value,
pageKey: router.route.path,
pageTitle: document.title,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
})
})
watch(
() => router.route.path,
(path) => {
nextTick(() => {
artalk.update({
pageKey: path,
pageTitle: document.title,
})
artalk.reload()
})
}
)
onBeforeUnmount(() => {
artalk.destroy()
})
</script>
<template>
<view ref="el"></view>
</template>
```
:::
## React
::: code-group
```tsx [React Hooks]
import React, { useEffect, useRef } from 'react'
import { useLocation } from 'react-router-dom'
import 'artalk/dist/Artalk.css'
import Artalk from 'artalk'
const ArtalkComment = () => {
const container = useRef<HTMLDivElement>(null)
const location = useLocation()
const artalk = useRef<Artalk>()
useEffect(() => {
artalk.current = Artalk.init({
el: container.current!,
pageKey: location.pathname,
pageTitle: document.title,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
})
return () => {
artalk.current?.destroy()
}
}, [container, location.pathname])
return <div ref={container}></div>
}
export default ArtalkComment
```
```jsx [React Class]
import React, { createRef } from 'react'
import 'artalk/dist/Artalk.css'
import Artalk from 'artalk'
export default class Artalk extends React.Component {
el = createRef()
artalk = null
componentDidMount() {
this.artalk = Artalk.init({
el: this.el.current,
pageKey: location.pathname,
pageTitle: document.title,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
})
}
componentWillUnmount() {
this.artalk?.destroy()
}
render() {
return <div ref={this.el} />
}
}
```
:::
## SolidJS
```tsx
import { onCleanup, onMount } from 'solid-js'
import Artalk from 'artalk'
import 'artalk/dist/Artalk.css'
const ArtalkComment = () => {
let el: HTMLDivElement
let artalk: Artalk
onMount(() => {
artalk = Artalk.init({
el: el,
pageKey: location.pathname,
pageTitle: document.title,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
})
onCleanup(() => {
artalk.destroy()
})
})
return <div ref={el} />
}
```
## Svelte
```html
<script>
import Artalk from 'artalk'
import { onMount, onDestroy } from 'svelte'
import 'artalk/dist/Artalk.css'
let el
let artalk
onMount(() => {
artalk = Artalk.init({
el: el,
pageKey: location.pathname,
pageTitle: document.title,
server: 'http://localhost:8080',
site: 'Artalk 的博客',
// ...
})
onDestroy(() => {
if (artalk) {
artalk.destroy()
}
})
})
</script>
<div bind:this="{el}"></div>
```
+39
View File
@@ -0,0 +1,39 @@
# 开发文档
欢迎来到 Artalk 官方开发文档,这里提供了构建 Artalk 插件和主题的指南。如果你需要搭建 Artalk 的开发环境,可以阅读 [开发者贡献指南](./contributing.md)。
感谢对 Artalk 的关注和支持。我们深知开源项目的成功离不开每一位开发者的贡献,无论是代码、文档、测试还是意见反馈,您的参与都是推动项目不断前进的动力。诚挚地邀请您加入我们,共同完善和提升 Artalk。
## 索引
- [开发者贡献指南](./contributing.md) ⭐️
**前端界面**
- [置入博客](./import-blog.md)
- [置入框架](./import-framework.md)
- [前端 API 文档](./fe-api.md)
- [前端 Event](./event.md)
- [前端配置](../guide/frontend/config.md)
**插件开发**
- [插件开发](./plugin.md)
- [插件开发 Vite 集成](https://github.com/ArtalkJS/Artalk/blob/master/ui/plugin-kit/README.md)
**后端程序**
- <a href="/http-api.html" target="_blank">HTTP API 文档</a>
- [环境变量](../guide/env.md)
- [配置文件](../guide/backend/config.md)
**其他内容**
- [兼容性](../develop/compatibility.md)
- [更新日志](https://github.com/ArtalkJS/Artalk/blob/master/CHANGELOG.md)
- [i18n 多语言贡献指南](../guide/frontend/i18n.md#贡献翻译)
- [贡献者契约行为准则](https://github.com/ArtalkJS/Artalk/blob/master/CODE_OF_CONDUCT.md)
::: tip
Artalk 正处于积极维护阶段,请注意 API 版本兼容性。升级可能有突破性变更参考 [更新日志](https://github.com/ArtalkJS/Artalk/blob/master/CHANGELOG.md)。
:::
+130
View File
@@ -0,0 +1,130 @@
# 插件开发
## 使用 Vite 开发
我们提供了 Vite 的集成插件,使用 Vite 开发能够开箱即用地构建 Artalk 插件,简化 Vite 配置。
参考文档:[@artalk/plugin-kit](https://github.com/ArtalkJS/Artalk/blob/master/ui/plugin-kit/README.md)。
同时,我们提供了一个模版代码仓库,你可以直接 fork 来开发插件:[artalk-plugin-sample](https://github.com/ArtalkJS/artalk-plugin-sample)。
通过 Vite 结合前端生态,你可以任选你喜欢的技术栈,如 Vue、React、Svelte、SolidJS 等框架开发 Artalk 插件。
## `Artalk.use`
使用 `Artalk.use` 来扩展 Artalk。
```js
import Artalk from 'artalk'
Artalk.use((ctx) => {
ctx.on('list-loaded', () => {
console.log('评论列表加载完毕')
ctx.getCommentNodes().forEach((node) => {
node.getEl().style.background = 'red'
})
})
})
Artalk.use((ctx) => {
let el = null
ctx.on('mounted', () => {
el = document.createElement('div')
document.body.appendChild(el)
console.log('Artalk 实例被挂载')
})
ctx.on('unmounted', () => {
el.remove()
console.log('Artalk 实例被销毁')
})
})
const artalk = Artalk.init({ ... })
```
请注意:
- `Artalk.use` 必须在 `Artalk.init` 之前调用才生效。
- 请勿依赖插件的加载顺序,请监听事件来执行插件逻辑。
- 当所有的插件加载完毕后,会触发 `created` 事件。
- 当插件和配置加载完毕后,会触发 `mounted` 事件。
- 当 Artalk 实例被销毁时,会触发 `unmounted` 事件。
- 当配置发生变化时,会触发 `updated` 事件。
在 use 函数中,你可以通过 `ctx` 来访问 Artalk 的 Context 对象。
### 插件可配置选项
在 TypeScript 中,你可以通过 `ArtalkPlugin<T>` 来定义一个带选项的插件类型。
```ts
export interface DemoPluginOptions {
foo?: string
}
export const ArtalkDemoPlugin: ArtalkPlugin<DemoPluginOptions> = (ctx, options = {}) => {
console.log(options.foo)
}
```
在执行 `Artalk.use` 时,传入选项:
```ts
import { ArtalkDemoPlugin } from 'artalk-plugin-demo'
Artalk.use(ArtalkDemoPlugin, { foo: 'bar' })
```
## ContextAPI
Context 对象包含了 Artalk 的上下文信息。
| 成员 | 说明 |
| --------------------- | -------------------- |
| `ctx.getEl` | 获取容器元素 |
| `ctx.getConf` | 获取配置 |
| `ctx.updateConf` | 更新配置 |
| `ctx.watchConf` | 监听配置 |
| `ctx.setDarkMode` | 设置夜间模式 |
| `ctx.getApi` | 获取 API 客户端对象 |
| -- | -- |
| `ctx.fetch` | 获取评论数据 |
| `ctx.reload` | 重载评论列表 |
| `ctx.getComments` | 获取所有评论数据对象 |
| `ctx.getCommentNodes` | 获取所有评论节点对象 |
| -- | -- |
| `ctx.on` | 添加事件监听 |
| `ctx.off` | 解除事件监听 |
| `ctx.trigger` | 触发事件 |
| -- | -- |
| `ctx.get` | 获取依赖 |
| `ctx.inject` | 注入依赖 |
::: warning
Context API 目前仍不稳定,开发可能会有变动,升级请关注 CHANGELOG。
:::
参考:[@artalk/src/types/context.ts](https://github.com/ArtalkJS/Artalk/blob/master/ui/artalk/src/types/context.ts)
Artalk 包含完整的 TypeScript 类型定义,你可以通过编辑器的自动补全来查看 API。
## 示例插件
以下为 Artalk 官方维护的外置插件列表:
| 插件 | 说明 |
| -------------------------------------------------------------------------------------------- | -------------- |
| [artalk-plugin-sample](https://github.com/ArtalkJS/artalk-plugin-sample) | 示例插件 |
| [@artalk/plugin-katex](https://github.com/ArtalkJS/Artalk/tree/master/ui/plugin-katex) | LaTeX 公式插件 |
| [@artalk/plugin-auth](https://github.com/ArtalkJS/Artalk/tree/master/ui/plugin-auth) | Auth 插件 (SolidJS) |
| [@artalk/plugin-lightbox](https://github.com/ArtalkJS/Artalk/tree/master/ui/plugin-lightbox) | 图片灯箱基础插件 |
同时 Artalk 内部也有很多插件的实现,你可以参考源码来开发插件:
[@ArtalkJS/Artalk - src/plugins](https://github.com/ArtalkJS/Artalk/tree/master/ui/artalk/src/plugins)
## 后端插件开发
【TODO】
+7
View File
@@ -0,0 +1,7 @@
# 插件开发
本页面内容已移动至 <https://artalk.js.org/develop/plugin.html>。
<script setup lang="ts">
if (!import.meta.env.SSR) window.location = 'https://artalk.js.org/develop/plugin.html';
</script>
+32
View File
@@ -0,0 +1,32 @@
---
layout: home
title: Artalk
titleTemplate: A Self-hosted Comment System
hero:
name: Artalk
text: A Self-hosted Comment System
tagline: Elevate your online conversations with a comment system that embodies the trifecta of lightness, security, and refinement.
actions:
- theme: brand
text: Get Started
link: /guide/intro
- theme: alt
text: View on GitHub
link: https://github.com/ArtalkJS/Artalk
features:
- icon: 🍃
title: Lightweight
details: Lightweight and responsive to every interaction
- icon: 🔒
title: Safety
details: Everything is under control as the data is completely self-hosted
- icon: 🐳
title: Turbo
details: Easy to deploy, quick to set up commenting interface
- icon: 🍱
title: Flexible
details: Use Golang to interpret the excellence of multiple platforms
---
+7
View File
@@ -0,0 +1,7 @@
# 🥬 关于我们
## ~~开发团队有人想自我介绍一下~~
[@qwqcode](https://github.com/qwqcode):🥬 + 🦜
The Artalk. Made with <span style="color: red;">♥️</span>.
+403
View File
@@ -0,0 +1,403 @@
# 多元推送
Artalk 支持通过多元推送功能以多种方式发送管理员通知。
支持 **Telegram**、**飞书**、**钉钉**、**Bark**、**Slack**、**LINE**,并且多种方式可以同时启用。
你可以在 [控制中心](/guide/frontend/sidebar.md#设置) 的设置界面修改此配置,也可以通过 [配置文件](/guide/backend/config.md#多元推送-admin-notify) 或 [环境变量](/guide/env.md#多元推送) 进行配置。
## 配置文件
完整的 `admin_notify` 配置如下:
::: details 点击显示
```yaml
# 多元推送
admin_notify:
# 通知模版
notify_tpl: default
noise_mode: false
# 邮件通知管理员
email:
enabled: true # 当使用其他推送方式时,可以关闭管理员邮件通知
mail_subject: '[{{site_name}}] 您的文章「{{page_title}}」有新回复'
mail_tpl: ''
# Telegram
telegram:
enabled: false
api_token: ''
receivers:
- 7777777
# 飞书
lark:
enabled: false
webhook_url: ''
# 钉钉
ding_talk:
enabled: false
token: ''
secret: ''
# Bark
bark:
enabled: false
server: http://day.app/xxxxxxx/
# Slack
slack:
enabled: false
oauth_token: ''
receivers:
- CHANNEL_ID
# LINE
line:
enabled: false
channel_secret: ''
channel_access_token: ''
receivers:
- USER_ID_1
- GROUP_ID_1
# WebHook
webhook:
enabled: false
url: ''
```
:::
## 邮件通知
通过邮件的方式向管理员发送消息通知。
```yaml
admin_notify:
enabled: true # 当使用其他推送方式时,可以关闭管理员邮件通知
mail_subject: '[{{site_name}}] 您的文章「{{page_title}}」有新回复'
mail_tpl: ''
```
当使用其他推送方式时,可以关闭管理员邮件通知。
在这之前,你需要配置全局邮件发送功能:[参考此处](./email.md)。
### 管理员邮件模板
- 配置项 `mail_subject` 为发送给管理员的邮件标题。
- 配置项 `mail_tpl` 为发送给管理员的邮件选用特定的[邮件模板](./email.md#邮件模板)(填写邮件模板文件路径)。
(当该项留空时,将继承 `email.mail_tpl` 配置项)
## Telegram
```yaml
admin_notify:
# Telegram
telegram:
enabled: true
api_token: ''
receivers:
- 7777777
```
- `api_token`:TG Bot 的 API Token。
- `receivers`:消息接受者的数字 ID,可设置多个。
### 创建 TG Bot
搜索 `@BotFather` 回复 `/newbot` 并按提示创建新的 TG 机器人。
![](/images/notify/tg-1.png)
标红的文字就是你之后需要在 Artalk 配置中填入的 `api_token`。
配置中的 `receivers` 填入需要接受消息的账号数字 ID,可以搜索机器人 `@RawDataBot` 获取如图:
![](/images/notify/tg-2.png)
详情可参考:[Bots: An introduction for developers - Telegram](https://core.telegram.org/bots)
::: tip
鉴于复杂的网络环境,如需使用代理,请在 Artalk 启动之前配置环境变量,例如:
```sh
export https_proxy=http://127.0.0.1:7890
```
:::
## 飞书
```yaml
admin_notify:
# 飞书
lark:
enabled: true
webhook_url: ''
```
- `webhook_url`:填入创建群组机器人时得到的 WebHook 地址。
### 创建群组机器人
点击顶部的加号,创建一个新的群组:
![](/images/notify/lark-1.png)
找到右侧的「群设置」-「群机器人」- 点击「添加机器人」- 选择「自定义机器人」并按照提示创建。
<img src="/images/notify/lark-2.png" width="700px">
复制如上图的 WebHook 地址,并修改 Artalk 的 `webhook_url` 配置即可。
<img src="/images/notify/lark-3.png" width="400px">
可参考:[飞书帮助中心文档](https://www.feishu.cn/hc/zh-CN/articles/360024984973)
## 钉钉
```yaml
admin_notify:
# 钉钉
ding_talk:
enabled: true
token: ''
secret: ''
```
可参考:[钉钉开放文档](https://open.dingtalk.com/document/robots/custom-robot-access)
## Bark
```yaml
admin_notify:
# Bark
bark:
enabled: true
server: http://day.app/xxxxxxx/
```
[Bark](https://github.com/Finb/Bark) 是一款开源的 iOS App,并且[支持自托管](https://github.com/Finb/bark-server),你能使用 Bark 轻松地推送消息给你的 iOS 设备。
你可以在 App Store 搜索下载,并获得需要填入 Artalk 的 `server` 配置项:
<img src="/images/notify/bark.png" width="700px">
## Slack
```yaml
admin_notify:
# Slack
slack:
enabled: true
oauth_token: ''
receivers:
- CHANNEL_ID
```
## LINE
```yaml
admin_notify:
# LINE
line:
enabled: true
channel_secret: ''
channel_access_token: ''
receivers:
- USER_ID_1
- GROUP_ID_1
```
## 通知模版
```yaml
admin_notify:
notify_tpl: default
```
配置项 `admin_notify.notify_tpl` 可设置为自定义通知模版「文件路径」,默认的通知模版为:
```
@{{reply_nick}}:
{{reply_content}}
{{link_to_reply}}
```
可用变量和邮件模板相同,可参考:[邮件模版](./email.md#邮件模板)
## 待审评论仍然发送通知 `notify_pending`
```yaml
admin_notify:
notify_pending: false
```
`notify_pending` 默认为关闭状态,当该项设置为 `false` 时,待审评论不会发送通知。你可以在控制中心查看所有待审核的评论。
## 嘈杂模式 `noise_mode`
```yaml
admin_notify:
noise_mode: false
```
`noise_mode` 默认为关闭状态,当该项设置为 `false` 时,站内仅向管理员回复的消息会发送通知,例如「普通用户 A」回复「普通用户 B」,这两个用户之间的通讯不会通知管理员。
注:当 `moderator.pending_default` 为 `true` 时,noise_mode 为始终开启状态。
## WebHook 回调
开启 WebHook 后,创建新评论将以 **POST** 方式携带 `application/json` 类型的 Body 数据请求设定的 WebHook 地址。
你可以编写自己的 Server 端代码,处理来自 Artalk 的请求。
**Artalk 配置文件**
```yaml
admin_notify:
webhook:
enabled: true
url: http://localhost:8080/
```
**Body 数据内容**
`application/json` 类型
| Key | 描述 | 类型 | 备注 |
| ---------------- | -------------- | ------ | --------------------------------------- |
| `notify_subject` | 通知标题 | String | 对应 admin_notify.notify_subject 配置项 |
| `notify_body` | 通知内容 | String | 根据 admin_notify.notify_tpl 模版渲染 |
| `comment` | 评论内容 | Object | 新创建的评论数据对象 |
| `parent_comment` | 评论回复的目标 | Object | 如果是根节点评论值为 null |
**Body 数据样本**
```js
{
"notify_subject": "",
"notify_body": "@测试用户:\n\n测试内容\n\nhttps://127.0.0.1/index.html?atk_comment=1057",
"comment": {
"id": 1057,
"content": "测试内容",
"user_id": 226,
"nick": "测试用户",
"email_encrypted": "654236c1e78i4c09a17c4869c9d43910",
"link": "https://qwqaq.com",
"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_4_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36",
"date": "2022-05-23 17:00:23",
"is_collapsed": false,
"is_pending": false,
"is_pinned": false,
"is_allow_reply": false,
"rid": 0,
"badge_name": "",
"badge_color": "",
"visible": true,
"vote_up": 0,
"vote_down": 0,
"page_key": "/index.html",
"page_url": "https://127.0.0.1/index.html",
"site_name": "ArtalkDocs"
},
"parent_comment": null
}
```
**Node.js express 处理示例**
```js
const express = require('express')
const app = express()
app.use(express.json()) // Use JSON middleware
app.post('/', (request, response) => {
console.log(request.body)
const notifySubject = request.body.notify_subject
const notifyBody = request.body.notify_body
console.log(notifySubject, notifyBody)
response.send(request.body)
})
app.listen(8080)
```
**Node.js http 处理示例**
```js
const http = require('http')
const requestListener = (req, res) => {
// receive json request
let body = ''
req.on('data', (data) => {
body += data
})
req.on('end', () => {
let json = ''
try {
json = JSON.parse(body)
} catch {}
// do something with json
console.log(json)
res.end()
})
res.writeHead(200)
res.end('Hello, World!')
}
const server = http.createServer(requestListener)
server.listen(8080)
```
**PHP Laravel 处理示例**
```php
Route::get('/', function (Request $request) {
$data = $request->json()->all();
$notify_subject = $data["notify_subject"];
$notify_body = $data["notify_body"];
});
```
**Golang net/http 处理示例**
```go
package main
import (
"encoding/json"
"log"
"net/http"
)
type ArtalkNotify struct {
NotifySubject string `json:"notify_subject"`
NotifyBody string `json:"notify_body"`
Comment interface{} `json:"comment"`
ParentComment interface{} `json:"parent_comment"`
}
func webhookHandler(rw http.ResponseWriter, req *http.Request) {
decoder := json.NewDecoder(req.Body)
var notify ArtalkNotify
err := decoder.Decode(&notify)
if err != nil {
panic(err)
}
log.Println(notify.NotifyBody)
}
func main() {
http.HandleFunc("/webhook", webhookHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
```
+7
View File
@@ -0,0 +1,7 @@
# 后端构建
本页面内容已移动至 <https://artalk.js.org/develop/contributing.html>。
<script setup lang="ts">
if (!import.meta.env.SSR) window.location = 'https://artalk.js.org/develop/contributing.html';
</script>
+159
View File
@@ -0,0 +1,159 @@
# 验证码
Artalk 内置图片验证码功能,你可以配置操作频率限制,当超过限度时激活验证码。
此外,你也可以接入各种验证服务提供商,获得多样化的验证功能。
目前 Artalk 支持:Turnstile、reCAPTCHA、hCaptcha、极验。
你可以在 [控制中心](/guide/frontend/sidebar.md#设置) 的设置界面修改此配置,也可以通过 [配置文件](/guide/backend/config.md#验证码-captcha) 或 [环境变量](/guide/env.md#验证码) 进行配置。
## 配置文件
完整的 `captcha` 配置如下:
```yaml
# 验证码
captcha:
enabled: true # 总开关
always: false # 总是需要验证码
captcha_type: image # 验证码类型
action_limit: 3 # 激活验证码所需操作次数
action_reset: 60 # 重置操作计数器超时 (单位:s, 设为 -1 不重置)
# Turnstile
# (https://www.cloudflare.com/products/turnstile/)
turnstile:
site_key: ''
secret_key: ''
# reCaptcha
# (https://www.google.com/recaptcha/about/)
recaptcha:
site_key: ''
secret_key: ''
# hCaptcha (https://www.hcaptcha.com/)
hcaptcha:
site_key: ''
secret_key: ''
# Geetest 极验 (https://www.geetest.com)
geetest:
captcha_id: ''
captcha_key: ''
```
- **always**:当该项为 `true` 时,总是需要输入验证码。
- **captcha_type**:验证码类型,可选:`image`、`turnstile`、`recaptcha`、`hcaptcha`、`geetest`。
- **action_limit**:激活评论所需的操作次数。
- **action_reset**:当时间超过该值时会重置操作计数器,单位为秒,设为 `-1` 将永不重置。
注:当 `always` 开启时,`action_limit` 和 `action_reset` 配置将失效。
## 配置举例
### 例 1
在 60s 时间范围内,当操作次数超过 3 次,将一直被要求输入验证码:
```yaml
captcha:
action_limit: 3
action_reset: 60
```
在 60s 后将自动重置计数器,即重新获得 3 次不用输入验证码的机会。
### 例 2
无论多少时间范围内,这个 IP 地址操作次数只要超过 5 次时,将一直被要求输入验证码:
```yaml
captcha:
action_limit: 5
action_reset: -1
```
### 例 3
总是要求输入验证码,无论这个 IP 操作多少次:
```yaml
captcha:
always: true
```
## 操作的定义
一个 IP 地址的一次「评论、投票、图片上传、密码验证」都算作一次「操作」。
## Turnstile
[Turnstile](https://www.cloudflare.com/zh-cn/products/turnstile/) 是 Cloudflare 推出的无感验证服务,可在 CF 后台申请获得 `site_key` 和 `secret_key`,之后在 Artalk 控制中心设置页填入 Key 并将 `captcha_type` 修改为 `turnstile` 即可。
图示:
<img src="../../images/captcha/cf-turnstile-1.png" width="400px">
<img src="../../images/captcha/cf-turnstile-2.png" width="400px">
对应配置文件如下:
```yaml
captcha:
# 省略其他配置...
captcha_type: turnstile
turnstile:
site_key: ''
secret_key: ''
```
## reCAPTCHA
[reCAPTCHA](https://developers.google.com/recaptcha) 是 Google 推出的验证服务,Artalk 支持接入 reCAPTCHA v3。可在谷歌开发者后台申请获得 `site_key` 和 `secret_key`,之后在 Artalk 控制中心设置页填入 Key 并将 `captcha_type` 修改为 `recaptcha` 即可。
对应配置文件如下:
```yaml
captcha:
# 省略其他配置...
captcha_type: recaptcha
recaptcha:
site_key: ''
secret_key: ''
```
注:国内访问 Google API 也许需要配置系统代理。
reCAPTCHA 官方提供了用于测试的 Keys:[可见此处](https://developers.google.com/recaptcha/docs/faq?hl=en#id-like-to-run-automated-tests-with-recaptcha.-what-should-i-do)。
## hCaptcha
[hCaptcha](https://www.hcaptcha.com/) 是一个验证服务,可在其官网申请获得 `site_key` 和 `secret_key`,之后在 Artalk 控制中心设置页填入 Key 并将 `captcha_type` 修改为 `hcaptcha` 即可。
对应配置文件如下:
```yaml
captcha:
# 省略其他配置...
captcha_type: hcaptcha
hcaptcha:
site_key: ''
secret_key: ''
```
hCaptcha 官方提供了用于测试的 Keys:[可见此处](https://docs.hcaptcha.com/#integration-testing-test-keys)。
## Geetest 极验
Artalk 支持接入 [Geetest 极验](https://www.geetest.com/adaptive-captcha) 第四代行为验。
首先在 Geetest 官网注册账号申请获得 `captcha_id` 和 `captcha_key`,然后在 Artalk 控制中心修改配置,并将 `captcha_type` 修改为 `geetest` 即可。
对应配置文件如下:
```yaml
captcha:
# 省略其他配置...
captcha_type: geetest
geetest:
captcha_id: ''
captcha_key: ''
```
+360
View File
@@ -0,0 +1,360 @@
# 配置文件
## 轻松配置
推荐在侧边栏 “[控制中心](/guide/frontend/sidebar.md)” 通过图形界面修改配置,无需手动编辑配置文件。
## 环境变量
可通过环境变量配置,参考文档:[环境变量](../env.md)。
## 指定配置文件路径
Artalk 默认以工作目录下的 `artalk.yml` 作为配置文件,可使用参数 `-c` 来指定具体文件:
```bash
artalk -c ./conf.yml
```
## 获取模版配置文件
可参考一份「完整的配置文件」:[artalk.example.zh-CN.yml](https://github.com/ArtalkJS/Artalk/blob/master/conf/artalk.example.zh-CN.yml)
### 使用 gen 命令生成配置文件
Artalk 提供 `gen` 命令,你可以快速生成一份新的配置文件:
```bash
artalk gen conf -lang zh-CN ./artalk.yml
```
### 命令行下载配置文件
```bash
wget -O artalk.yml https://raw.githubusercontent.com/ArtalkJS/Artalk/master/conf/artalk.example.zh-CN.yml
```
## 加密密钥 `app_key`
在 Artalk 启动之前,你需要配置一个 `app_key` 用于对网站内容进行安全加密:
```yaml
app_key: <任意的字符>
```
## 语言 `locale`
设置 Artalk 的语言。遵循 Unicode BCP 47 规范,该项默认为 "zh-CN" (简体中文)。
```yml
locale: zh-CN
```
详情参考:[多语言](../frontend/i18n.md)
## 数据库 `db`
Artalk 支持连接多种数据库,支持 SQLite、MySQL、PostgreSQL、SQL Server 配置如下:
#### SQLite
SQLite 是轻型数据库,使用单个文件存储数据,无需额外运行程序,尤其适合小型站点,例如个人博客。
```yaml
db:
type: sqlite
file: ./data/artalk.db
```
#### MySQL / PostgreSQL / SQL Server
修改 `type` 为你的数据库类型:
```yaml
db:
type: mysql # sqlite, mysql, pgsql, mssql
name: artalk # 数据库名
host: localhost # 地址
port: 3306 # 端口
user: root # 账号
password: '' # 密码
charset: utf8mb4 # 编码格式
table_prefix: '' # 表前缀 (例如:"atk_")
ssl: false # 启用 SSL
prepare_stmt: true # 预编译语句
```
数据表将在 Artalk 启动时自动完成创建,无需额外操作。
#### 数据库连接字符串 (DSN)
如有需要,你还可以手动配置 `db.dsn` 来指定数据库连接字符串,例如:
```yaml
db:
type: mysql
dsn: mysql://myuser:mypassword@localhost:3306/mydatabase?tls=skip-verify
```
更多内容参考:[@go-sql-driver/mysql:README.md](https://github.com/go-sql-driver/mysql)
## 服务器 `http`
```yaml
http:
# 请求体大小限制 (单位:MB)
body_limit: 100
# 代理标头名 (当使用 CDN 时填写 `X-Forwarded-For` 获取用户真实 IP)
proxy_header: ""
```
## 管理员 `admin_users`
你需要配置管理员账户,这样才能通过「[控制中心](../frontend/sidebar.md)」对站点内容进行管理。
Artalk 支持多站点,你可以创建多个管理员账户,为其分配站点,让你的朋友们共用同一个后端程序。
详情参考:[管理员 × 多站点](/guide/backend/multi-site.md)
## 可信域名 `trusted_domains`
```yaml
trusted_domains:
- https://前端使用域名A.com
- https://前端使用域名B.com
```
仅允许列表中的域名访问后端 API,限制来自列表外的域名跨域请求。
:::tip
你需要将「前端页面」的 URL 地址加入可信域名列表中,
若非默认 80/443 端口需额外附带端口号,例如:`https://example.com:8080`
:::
在侧边栏 [控制中心](../frontend/sidebar.md#控制中心) 的「站点」选项卡 - 选择站点「修改 URL」,填入站点 URL 也具有相同的设置效果;添加多个 URL 可使用 `,` 英文逗号分隔,修改后请手动重启 Artalk。
默认站点地址 `ATK_SITE_URL` 配置项也会被自动加入可信域名列表。
另外,你也可以在启动时通过环境变量 `ATK_TRUSTED_DOMAINS` 来配置可信域名,例如:
```bash
ATK_TRUSTED_DOMAINS="https://a.com https://b.org" artalk server
```
请注意,环境变量将覆盖配置文件中的设置。
技术细节:`trusted_domains` 配置通过控制 HTTP 响应标头 `Access-Control-Allow-Origin` 来对跨域请求进行限制 (参考:[W3C Cross-Origin Resource Sharing](https://fetch.spec.whatwg.org/#http-cors-protocol) / [OWASP 安全备忘单](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html)).
## 默认站点 `site_default`
如果你觉得大概是不会用到 Artalk 的多站点功能,可以直接将该项配置为你的站点名,例如:
```yaml
site_default: Artalk 官网
```
然后在前端直接使用这个站点名:
```js
Artalk.init({ site: 'Artalk 官网' })
```
这样,你就无需在侧边栏的[控制中心](../frontend/sidebar.md#控制中心)手动创建站点。
## 界面配置 `frontend`
在 Artalk 的配置文件 `artalk.yml` 可以配置 `frontend` 字段来控制前端界面,例如:
```yaml
frontend:
placeholder: 键入内容...
noComment: 「此时无声胜有声」
sendBtn: 发送评论
emoticons: 'https://raw.githubusercontent.com/ArtalkJS/Emoticons/master/grps/default.json'
# ----- 此处省略 -------
# 与前端配置项名称保持一致
```
一份完整的后端 `frontend` 字段配置文件可供参考:[artalk.example.zh-CN.yml](https://github.com/ArtalkJS/Artalk/blob/master/conf/artalk.example.zh-CN.yml)
## 邮件通知 `email`
配置邮件通知,让回复通过邮件的形式通知目标用户,你可以自定义邮件发送者名称、标题、模版等。
详情参考:[后端 · 邮件通知](/guide/backend/email.md)
## 多元推送 `admin_notify`
你可以配置多种消息发送方式,例如飞书、Telegram 等,当收到新的评论时通知管理员。
详情参考:[后端 · 多元推送](/guide/backend/admin_notify.md)
## 评论审核 `moderator`
配置评论审核来自动拦截垃圾评论。
详情参考:[后端 · 评论审核](/guide/backend/moderator.md)
## 验证码 `captcha`
支持图片、滑动验证码,通过验证码对请求频率进行限制。
详情参考:[后端 · 验证码](/guide/backend/captcha.md)
## 高速缓存 `cache`
为节省内存资源占用,缓存默认关闭。如果你对网站性能有较高要求,请手动开启。你还可以连接外部缓存服务器,支持 Redis 和 Memcache。
```yaml
cache:
enabled: true # 启用缓存 (默认关闭)
type: builtin # 支持 redis, memcache, builtin (自带缓存)
expires: 30 # 缓存过期时间 (单位:分钟)
warm_up: false # 程序启动时预热缓存
server: '' # 连接缓存服务器 (例如:"localhost:6379")
```
- **warm_up**:缓存预热功能。设置为 `true`,在 Artalk 启动时会立刻对数据库内容进行全面缓存,如果你的评论数据较多,多达上万条,启动时间可能会延长。
- **type**:缓存类型,默认为 `builtin`。可选:`redis`, `memcache`, `builtin`。
注:如果在 Artalk 程序外部修改数据库内容,需要刷新 Artalk 缓存才能更新。
---
Redis 身份认证、数据库配置:
```yaml
# 缓存
cache:
# 省略其他配置项...
redis:
network: tcp # 连接方式 (tcp 或 unix)
username: '' # 用户名
password: '' # 密码
db: 0 # 使用零号数据库
```
<!-- 技术细节:[Artalk 缓存机制 时序图.png](/images/artalk/artalk-cache.png) -->
<!-- ![](/images/artalk/artalk-cache.png) -->
## 监听地址 `host`
Artalk 的默认 HTTP 端口为 23366,你可以在配置文件中指定:
```yaml
host: '0.0.0.0'
port: 23366
```
配置 `host` 监听地址为 `0.0.0.0` 将 Artalk 服务暴露到全网可访问范围,
如果你只想让 Artalk 仅本地能够访问,可将 `host` 配置为 `127.0.0.1`。
命令行下启动 Artalk 时,可以携带 `--host` 和 `--port` 参数分别对地址和端口进行指定,例如:
```bash
artalk server --host 127.0.0.1 --port 8080
```
## 加密传输 `ssl`
```yaml
ssl:
enabled: true
cert_path: ''
key_path: ''
```
你可以配置该项,让 HTTP 升级为 HTTPS,通过 SSL 协议加密传输数据。
- `cert_path`:SSL 证书公钥文件路径。
- `key_path`:SSL 证书私钥文件路径。
你也可以直接反向代理 Artalk 本地服务器,然后在例如 Nginx 启用 HTTPS。
## 时区配置 `timezone`
```yaml
timezone: Asia/Shanghai
```
该值填写你所在地时区,对应 IANA 数据库时区名,参考:[Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) / [RFC-6557](https://www.rfc-editor.org/rfc/rfc6557.html)。
```
UTC+08:00 Asia/Shanghai
UTC+09:00 Asia/Tokyo
UTC-07:00 America/Los_Angeles
UTC-04:00 America/New_York
```
## 登录超时 `login_timeout`
该值设定管理员账户登录 JWT 令牌的有效期,单位:秒。
例如,3 天有效:
```yaml
login_timeout: 259200
```
## 日志配置 `log`
打开日志后,系统错误等信息将被记录到设定的文件中。
```yaml
log:
enabled: true # 总开关
filename: ./data/artalk.log # 日志文件路径
```
日志为 JSON 格式,可以通过使用 Linux 的 `tail` 命令结合 `jq` 工具查看:
```bash
tail -f ./data/artalk.log | jq
```
如果你是 Grafana 用户,可以结合 Loki 和 Promtail 来实现日志的收集和查询。
## 调试模式 `debug`
将 `debug` 配置为 `true` 启用调试模式。
```yaml
debug: true
```
## 工作目录 `-w` 参数
Artalk 在不指定工作目录的情况下,会使用「程序启动时的目录」作为工作目录。
```bash
pwd # 显示当前目录路径
```
使用参数 `-w` 来指定工作目录,它通常是一个「绝对路径」,例如:
```bash
artalk -w /root/artalk -c ./conf.yml
```
注:`-c` 的相对路径会基于 `-w` 的路径,Artalk 此时会读取 `/root/artalk/conf.yml` 作为配置文件。
其次,在「配置文件中」使用的「相对路径」,也会基于「工作目录」。
例如 `conf.yml` 中有这样的配置:
```yaml
test_file: ./data/artalk.log
```
将读取 `/root/artalk/data/artalk.log`。
::: tip
配置文件相关代码:[/internal/config/config.go](https://github.com/ArtalkJS/Artalk/blob/master/internal/config/config.go)
前往:[前端配置](/guide/frontend/config.md)
:::
+144
View File
@@ -0,0 +1,144 @@
# 守护进程
## Systemd
前提条件:
- Artalk 二进制文件,可在 [GitHub Release](https://github.com/ArtalkJS/Artalk/releases) 下载
- `systemctl --version` 232 或更新的版本
- `sudo` 管理员权限
移动 Artalk 到 `$PATH`,例如:
```bash
sudo mv artalk /usr/bin/
```
测试是否有效:
```bash
artalk version
```
创建名为 artalk 的用户组:
```bash
sudo groupadd --system artalk
```
创建一个名为 artalk 的用户,并且拥有一个可写的 home 目录:
```bash
sudo useradd --system \
--gid artalk \
--create-home \
--home-dir /var/lib/artalk \
--shell /usr/sbin/nologin \
--comment "Artalk server" \
artalk
```
如果你有 Artalk 的配置文件,请确保刚刚创建的 artalk 用户有权限可以读取。
创建服务文件:
```bash
sudo vim /etc/systemd/system/artalk.service
```
```ini
[Unit]
Description=Artalk
Documentation=https://artalk.js.org
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=simple
User=artalk
Group=artalk
ExecStart=/usr/bin/artalk server -w /var/lib/artalk -c /etc/artalk/artalk.yml
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
```
请仔细检查 `ExecStart` 和 `ExecReload`。 确保二进制文件的位置和程序启动参数是正确的
例如:更改 `-c` 参数的路径来指定配置文件,`-w` 参数可以更改工作目录。
请注意配置文件中的所有相对路径都是基于工作目录,例如配置文件中的 `./data/` 文件夹,如果启动参数 `-w /var/lib/artalk`,将读取 `/var/lib/artalk/data/` 目录。请确保该目录中的文件对于创建的 `artalk` 账户有权限可读写。
保存服务文件后,你可以设置自动启动服务:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now artalk
```
验证服务是否正常运行:
```bash
systemctl status artalk
```
一些常用的命令:
- 启动服务:`systemctl start artalk`
- 停止服务:`systemctl stop artalk`
- 查看状态:`systemctl status artalk`
- 查看日志:`journalctl -u artalk --no-pager | less +G`
## Tmux
tmux 将创建一个持续的命令行会话,在 SSH 或 tty 断开后保持在后台。
Note: 服务器关闭或重启后,tmux 会话将被清除,需要手动重新运行程序。
1. 创建会话 `tmux new -s artalk`
2. 运行程序 `./artalk server`
恢复接入会话:`tmux attach -t artalk`
查看所有会话:`tmux ls`
## Supervisor
以宝塔面板举例:打开「软件商店」,搜索并安装「Supervisor管理器」:
![](/images/baota-supervisor/0.png)
安装后,打开插件,点击「添加守护程序」:
![](/images/baota-supervisor/1.png)
> - 启动用户:`root` 或其他
> - 运行目录:点击右侧图标,选择 Artalk 所在目录
> - 启动命令:`./artalk server`
## Docker
更新 Docker 容器的 [Restart 策略](https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy) 以达到进程守护效果。
```bash
docker update --restart=unless-stopped artalk
```
## Docker Compose
在 `docker-compose.yml` 文件给服务添加 `restart: unless-stopped` 策略:
```diff
version: '3'
services:
artalk:
+ restart: unless-stopped
```
+7
View File
@@ -0,0 +1,7 @@
# 数据
本页面内容已移动至 <https://artalk.js.org/guide/transfer.html>。
<script setup lang="ts">
if (!import.meta.env.SSR) window.location = 'https://artalk.js.org/guide/transfer.html';
</script>
+101
View File
@@ -0,0 +1,101 @@
# Docker
Artalk 提供后端程序的 Docker 镜像,以便加速部署流程,提供一个良好的部署体验。
[Docker Hub](https://hub.docker.com/r/artalk/artalk-go) 镜像版本随代码仓库的 [Releases](https://github.com/ArtalkJS/Artalk/releases) 保持同步。
## 镜像拉取
```bash
docker pull artalk/artalk-go
```
## 容器创建
:::tip
推荐使用 Docker Compose,可参考 [程序部署](/guide/deploy) 页面的步骤。
:::
## 生成配置文件
```bash
docker run -it -v $(pwd)/data:/data --rm artalk/artalk-go gen config data/artalk.yml
```
## 重启
修改配置文件后,需要重启才能生效。
```bash
# Docker Compose
docker-compose restart
# Docker
docker restart artalk
```
## 停止
```bash
# Docker Compose
docker-compose stop
# Docker
docker stop artalk
```
## 升级
删除现有容器,拉取最新镜像,然后重新创建容器即可。
### Docker Compose
```bash
docker-compose down
docker-compose pull
docker-compose up -d
```
### Docker
```bash
docker stop artalk
docker rm artalk
docker pull artalk/artalk-go
```
::: tip
突破性变动请注意查看版本更新日志中的提示:[CHANGELOG.md](https://github.com/ArtalkJS/Artalk/blob/master/CHANGELOG.md)
:::
## 测试版本
Nightly 镜像为测试版本,每日更新,通过代码仓库最新代码自动构建。
```bash
docker pull artalk/artalk-go:nightly
```
## 历史版本
镜像会随代码仓库 tags 自动构建发布,您可拉取不同版本号的镜像。
```bash
docker pull artalk/artalk-go:版本号
```
## 进入容器
```bash
# Docker Compose
docker-compose exec artalk bash
# Docker
docker exec -it artalk bash
```
## 多平台兼容性
Docker 镜像暂仅提供 x86、arm64 的镜像构建,如需更多平台架构版本,请下载 [二进制构建部署](/guide/deploy.md#普通方式部署)。
+325
View File
@@ -0,0 +1,325 @@
# 邮件通知
Artalk 支持通过 SMTP 协议、阿里云邮件推送、调用系统 Sendmail 命令等方式向用户发送邮件通知。
你可以在 [控制中心](/guide/frontend/sidebar.md#设置) 的设置界面修改此配置,也可以通过 [配置文件](/guide/backend/config.md#邮件通知-email) 或 [环境变量](/guide/env.md#邮件通知) 进行配置。
## 配置文件
完整的 `email` 配置如下:
```yaml
# 邮件通知
email:
enabled: false # 总开关
send_type: smtp # 发送方式 [smtp, ali_dm, sendmail]
send_name: '{{reply_nick}}' # 发信人昵称
send_addr: example@qq.com # 发信人地址
mail_subject: '[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复'
mail_tpl: default # 邮件模板文件
smtp:
host: smtp.qq.com
port: 587
username: example@qq.com
password: ''
ali_dm: # https://help.aliyun.com/document_detail/29444.html
access_key_id: '' # 阿里云颁发给用户的访问服务所用的密钥 ID
access_key_secret: '' # 用于加密的密钥
account_name: example@example.com # 管理控制台中配置的发信地址
```
### 选择发件方式
配置项 `enabled` 启用邮件,`send_type` 用于选择发送方式,可选:`smtp`, `ali_dm`, `sendmail`。
```yaml
email:
enabled: true
send_type: smtp # 发送方式
# 省略其他配置...
smtp:
# SMTP 配置...
ali_dm:
# 阿里云推送配置...
```
### SMTP 配置
```yaml
# 邮件通知
email:
enabled: true
send_type: smtp # 选择 smtp
smtp:
host: smtp.qq.com
port: 587
username: example@qq.com
password: ''
```
### 阿里云推送配置
```yaml
email:
enabled: true
send_type: ali_dm # 选择 ali_dm
ali_dm:
access_key_id: '' # 阿里云颁发给用户的访问服务所用的密钥 ID
access_key_secret: '' # 用于加密的密钥
account_name: example@example.com # 管理控制台中配置的发信地址
```
可参考:[阿里云官方文档](https://help.aliyun.com/document_detail/29444.html)
## 评论回复
邮件中会有一个评论回复按钮,该链接指向前端给定的页面 PageKey,若你提供的 `pageKey` 配置项为页面的「相对路径」,你需要在「[控制中心](../frontend/sidebar.md#控制中心)」-「站点」为你的站点设置一个 URL:
<img src="/images/sidebar/site_url.png" width="400px">
## 邮件模板
### 模板变量
你可以在 `mail_subject` 和 `mail_subject_to_admin` 以及邮件模板文件中使用模板变量:
```yaml
email:
# 省略其他配置...
mail_subject: '[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复'
mail_subject_to_admin: '[{{site_name}}] 您的文章 "{{page_title}}" 有新回复'
mail_tpl: default # 邮件模板文件
```
变量是 “Mustache” 的语法,`双大括号` + `变量名` 的形式即可输出一个变量:
**基本内容变量**
```yaml
{{content}} # 评论内容
{{link_to_reply}} # 回复链接
{{nick}} # 评论者昵称
{{page_title}} # 页面标题
{{page_url}} # 页面 PageKey (URL)
{{reply_content}} # 回复对象的内容
{{reply_nick}} # 回复对象的昵称f
{{site_name}} # 站点名
{{site_url}} # 站点 URL
```
::: details 查看其他变量
```yaml
# 评论创建者
{{comment.badge_color}}
{{comment.badge_name}}
{{comment.content}}
{{comment.content_raw}}
{{comment.date}}
{{comment.datetime}}
{{comment.email}}
{{comment.email_encrypted}}
{{comment.id}}
{{comment.is_allow_reply}}
{{comment.is_collapsed}}
{{comment.is_pending}}
{{comment.link}}
{{comment.nick}}
{{comment.page.admin_only}}
{{comment.page.id}}
{{comment.page.key}}
{{comment.page.site_name}}
{{comment.page.title}}
{{comment.page.url}}
{{comment.page.vote_down}}
{{comment.page.vote_up}}
{{comment.page_key}}
{{comment.page_title}}
{{comment.rid}}
{{comment.site.first_url}}
{{comment.site.id}}
{{comment.site.name}}
{{comment.site.urls.0}}
{{comment.site.urls_raw}}
{{comment.site_name}}
{{comment.time}}
{{comment.ua}}
{{comment.visible}}
{{comment.vote_down}}
{{comment.vote_up}}
# 父评论(评论创建者回复的评论)
{{parent_comment.badge_color}}
{{parent_comment.badge_name}}
{{parent_comment.content}}
{{parent_comment.content_raw}}
{{parent_comment.date}}
{{parent_comment.datetime}}
{{parent_comment.email}}
{{parent_comment.email_encrypted}}
{{parent_comment.id}}
{{parent_comment.is_allow_reply}}
{{parent_comment.is_collapsed}}
{{parent_comment.is_pending}}
{{parent_comment.link}}
{{parent_comment.nick}}
{{parent_comment.page.admin_only}}
{{parent_comment.page.id}}
{{parent_comment.page.key}}
{{parent_comment.page.site_name}}
{{parent_comment.page.title}}
{{parent_comment.page.url}}
{{parent_comment.page.vote_down}}
{{parent_comment.page.vote_up}}
{{parent_comment.page_key}}
{{parent_comment.page_title}}
{{parent_comment.rid}}
{{parent_comment.site.first_url}}
{{parent_comment.site.id}}
{{parent_comment.site.name}}
{{parent_comment.site.urls}}
{{parent_comment.site.urls_raw}}
{{parent_comment.site_name}}
{{parent_comment.time}}
{{parent_comment.ua}}
{{parent_comment.visible}}
{{parent_comment.vote_down}}
{{parent_comment.vote_up}}
```
:::
::: details 查看数据样例
```json
{
"content": "<p>测试内容</p>\n",
"link_to_reply": "https://artalk.js.org/?atk_comment=8100&atk_notify_key=44a9b2f08312565fba47c716df9d177f",
"nick": "用户名",
"page_title": "Artalk",
"page_url": "https://artalk.js.org/",
"reply_content": "<p>回复者内容</p>\n",
"reply_nick": "回复者",
"site_name": "ArtalkDemo",
"site_url": "http://localhost:3000/",
"comment.badge_color": "",
"comment.badge_name": "",
"comment.content": "<p>回复者内容</p>\n",
"comment.content_raw": "回复者内容",
"comment.date": "2021-11-22",
"comment.datetime": "2021-11-22 22:22:42",
"comment.email": "replyer@example.com",
"comment.email_encrypted": "249898bd50e0febc5799485cf10b345a",
"comment.id": 8100,
"comment.is_allow_reply": true,
"comment.is_collapsed": false,
"comment.is_pending": false,
"comment.link": "",
"comment.nick": "回复者",
"comment.page.admin_only": false,
"comment.page.id": 75,
"comment.page.key": "https://artalk.js.org/",
"comment.page.site_name": "ArtalkDemo",
"comment.page.title": "Artalk",
"comment.page.url": "https://artalk.js.org/",
"comment.page.vote_down": 0,
"comment.page.vote_up": 0,
"comment.page_key": "https://artalk.js.org/",
"comment.page_title": "Artalk",
"comment.rid": 8099,
"comment.site.first_url": "http://localhost:3000/",
"comment.site.id": 2,
"comment.site.name": "ArtalkDemo",
"comment.site.urls.0": "http://localhost:3000/",
"comment.site.urls_raw": "http://localhost:3000/",
"comment.site_name": "ArtalkDemo",
"comment.time": "22:22:42",
"comment.ua": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
"comment.visible": false,
"comment.vote_down": 0,
"comment.vote_up": 0,
"parent_comment.badge_color": "",
"parent_comment.badge_name": "",
"parent_comment.content": "<p>测试内容</p>\n",
"parent_comment.content_raw": "测试内容",
"parent_comment.date": "2021-11-22",
"parent_comment.datetime": "2021-11-22 22:21:17",
"parent_comment.email": "test@example.com",
"parent_comment.email_encrypted": "55502f40dc8b7c769880b10874abc9d0",
"parent_comment.id": 8099,
"parent_comment.is_allow_reply": true,
"parent_comment.is_collapsed": false,
"parent_comment.is_pending": false,
"parent_comment.link": "https://qwqaq.com",
"parent_comment.nick": "用户名",
"parent_comment.page.admin_only": false,
"parent_comment.page.id": 75,
"parent_comment.page.key": "https://artalk.js.org/",
"parent_comment.page.site_name": "ArtalkDemo",
"parent_comment.page.title": "Artalk",
"parent_comment.page.url": "https://artalk.js.org/",
"parent_comment.page.vote_down": 0,
"parent_comment.page.vote_up": 0,
"parent_comment.page_key": "https://artalk.js.org/",
"parent_comment.page_title": "Artalk",
"parent_comment.rid": 0,
"parent_comment.site.first_url": "http://localhost:3000/",
"parent_comment.site.id": 2,
"parent_comment.site.name": "ArtalkDemo",
"parent_comment.site.urls.0": "http://localhost:3000/",
"parent_comment.site.urls_raw": "http://localhost:3000/",
"parent_comment.site_name": "ArtalkDemo",
"parent_comment.time": "22:21:17",
"parent_comment.ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36",
"parent_comment.visible": false,
"parent_comment.vote_down": 0,
"parent_comment.vote_up": 0
}
```
:::
### 自定义模板
你可以将 `mail_tpl` 设置为一个「具体的文件路径」,使用外部的自定义邮件模板。
例如,将 `mail_tpl` 配置为 `"/root/Artalk/data/mail_tpl/your_email_template.html"`
```yaml
email:
mail_tpl: /root/Artalk/data/mail_tpl/your_email_template.html
# 其他配置省略...
```
那么,在这个路径应该有一个文件:
```html
<div>
<p>Hi, {{nick}}:</p>
<p>您在 “{{page_title}}” 收到了回复:</p>
<div>
<div>@{{reply_nick}}:</div>
<div>{{reply_content}}</div>
</div>
<p><a href="{{link_to_reply}}" target="_blank">回复消息 »</a></p>
</div>
```
Artalk 内置许多预设的邮件模板,例如 `mail_tpl: "default"` 使用的就是:[@ArtalkJS/Artalk:/internal/template/email_tpl/default.html](https://github.com/ArtalkJS/Artalk/blob/master/internal/template/email_tpl/default.html)
## 发向管理员的邮件
邮件通知目标为管理员和普通用户,你可通过如下配置,为发向管理员的邮件设定不同的标题:
```yaml
admin_notify:
enabled: true
mail_subject: '[{{site_name}}] 您的文章「{{page_title}}」有新回复'
```
注:旧版 `email.mail_subject_to_admin` 配置项已弃用,请使用以上替代。
不局限于邮件,Artalk 支持多种方式向管理员发送通知,参考:[多元推送](./admin_notify.md#邮件通知)。
+7
View File
@@ -0,0 +1,7 @@
# 如何配置界面
本页面内容已移动至 <https://artalk.js.org/guide/frontend/config.html>。
<script setup lang="ts">
if (!import.meta.env.SSR) window.location = 'https://artalk.js.org/guide/frontend/config.html';
</script>
+114
View File
@@ -0,0 +1,114 @@
# 图片上传
Artalk 提供图片上传功能,支持限制图片大小、上传频率等,你还能结合 UpGit 将图片上传到图床。
你可以在 [控制中心](/guide/frontend/sidebar.md#设置) 的设置界面修改此配置,也可以通过 [配置文件](/guide/backend/config.md#图片上传-img_upload) 或 [环境变量](/guide/env.md#图片上传) 进行配置。
## 配置文件
完整的 `img_upload` 配置如下:
```yaml
# 图片上传
img_upload:
enabled: true # 总开关
path: ./data/artalk-img/ # 图片存放路径
max_size: 5 # 图片大小限制 (单位:MB)
public_path: null # 指定图片链接基础路径 (默认为 "/static/images/")
# 使用 upgit 将图片上传到 GitHub 或图床
upgit:
enabled: false # 启用 upgit
exec: upgit -c <upgit配置文件路径> -t /artalk-img
del_local: true # 上传后删除本地的图片
```
## 使用 Upgit 上传到图床
[UpGit](https://github.com/pluveto/upgit) 支持将图片上传到 Github、Gitee、腾讯云 COS、七牛云、又拍云、SM.MS 等图床或代码仓库。
首先,根据 [README.md](https://github.com/pluveto/upgit) 的说明,下载 UpGit 并完成你需要上传的目标图床的配置。
然后,将 UpGit 加入系统的环境变量中,在 `~/.bashrc` 加入:
```bash
export PATH=$PATH:/path/to/upgit
```
(或者直接移入 `/usr/bin`)
最后,在 Artalk 的 `img_upload.upgit` 字段填入 UpGit 启动参数:
```yaml
upgit:
enabled: true # 启用 upgit
exec: upgit -c <upgit配置文件路径> -t /artalk-img
del_local: true # 上传后删除本地的图片
```
::: warning 更新注意
从 `v2.8.4` 版本开始,为了增强安全性,Artalk 不再允许指定 UpGit 的可执行文件路径,请将其加入系统的环境变量中。:)
:::
### Docker 挂载 UpGit
如果你使用 Docker 部署 Artalk,可以将 UpGit 可执行文件挂载到容器中:
```bash
docker run -d --name artalk -v /path/to/upgit:/usr/bin/upgit -v /path/to/artalk:/app/data -p 8080:23366 artalk
```
## 上传频率限制
频率限制跟随 `captcha` 验证码配置,当超出限制将弹出验证码。
可参考:[后端 · 验证码](/guide/backend/captcha.md)
## path
`img_upload.path` 为上传的图片文件「本地存放目录」路径,该目录会被 Artalk 映射到可访问的:
```
http://<后端地址>/static/images/
```
## public_path
`img.public_path` 为空的默认值为:`/static/images/`
当该项为「相对路径」时,例如:`/static/images/` 前端上传图片得到的 HTML 标签将为:
```html
<img src="http://<后端地址>/static/images/1.png" />
```
注:这里的 `<后端地址>` 是前端 `conf.server` 配置。
当该项为「完整 URL 路径」时,例如:`https://cdn.github.com/img/` 时,图片标签将为:
```html
<img src="https://cdn.github.com/img/1.png" />
```
提示:这个配置可以结合负载均衡等场景使用。
## 在前端自定义上传 API
前端提供了配置项 `imgUploader`,你可以自定义前端图片上传时请求的 API,例如:
```js
Artalk.init({
imgUploader: async (file) => {
const form = new FormData()
form.set('file', file)
const imgUrl = await fetch('https://api.example.org/upload', {
method: 'POST',
body: form,
})
return imgUrl
},
})
```
参考:[前端配置文档](../frontend/config.md#imguploader)
+7
View File
@@ -0,0 +1,7 @@
# 后端部署
本页面内容已移动至 <https://artalk.js.org/guide/deploy.html>。
<script setup lang="ts">
if (!import.meta.env.SSR) window.location = 'https://artalk.js.org/guide/deploy.html';
</script>
+118
View File
@@ -0,0 +1,118 @@
# 评论审核
Artalk 支持多种评论过滤方式以拦截垃圾评论,支持通过 Akismet、腾讯云内容安全、阿里云内容安全 等在线 API 实现垃圾评论识别和拦截,也可通过本地离线关键词词库过滤评论,结合[验证码](./captcha.md)功能进一步提高评论审核强度,让垃圾评论没有容身之地。
你可以在 [控制中心](/guide/frontend/sidebar.md#设置) 的设置界面修改此配置,也可以通过 [配置文件](/guide/backend/config.md#评论审核-moderator) 或 [环境变量](/guide/env.md#评论审核) 进行配置。
## 配置文件
完整的 `moderator` 配置如下:
```yaml
# 评论审核
moderator:
pending_default: false # 发表新评论默认为 “待审状态”
api_fail_block: false # 垃圾检测 API 请求错误仍然拦截
# akismet.com 反垃圾
akismet_key: ''
# 腾讯云文本内容安全 (tms)
tencent: # https://cloud.tencent.com/document/product/1124/64508
enabled: false
secret_id: ''
secret_key: ''
region: ap-guangzhou
# 阿里云内容安全
aliyun: # https://help.aliyun.com/document_detail/28417.html
enabled: false
access_key_id: ''
access_key_secret: ''
region: cn-shanghai
# 关键词词库过滤
keywords:
enabled: false
pending: false # 匹配成功设为待审状态
files: # 支持多个词库文件
- './data/词库_1.txt'
file_sep: "\n" # 词库文件内容分割符
replace_to: 'x' # 替换字符
```
## 默认待审模式
开启发表新评论默认为 “待审状态”:
```yaml
moderator:
pending_default: true
```
## Akismet
[Akismet](https://akismet.com/) 是 WordPress 提供的面向全球范围的老牌垃圾拦截 API,通常对一些英文的垃圾评论十分凑效。Akismet 提供了 Personal 免费版本,适用于个人博客站点。
![](/images/akismet/1.png)
你能在 [Akismet 官网](https://akismet.com/) 轻松地申请 `akismet_key`,并填入配置文件中,即可启用 Akismet 垃圾拦截。
![](/images/akismet/2.png)
```yaml
moderator:
akismet_key: your_key
```
## 腾讯云文本内容安全
可参考:[腾讯云文档](https://cloud.tencent.com/document/product/1124/64508)
开通「文本内容安全」后,在「访问管理」-「API 密钥管理」新增具有权限的 Secret,然后填入配置:
```yaml
moderator:
tencent:
enabled: true
secret_id: ''
secret_key: ''
region: ap-guangzhou
```
## 阿里云内容安全
可参考:[阿里云文档](https://help.aliyun.com/document_detail/28417.html)
开通「阿里云内容安全」后,阿里云后台创建 Access Key 并填入配置:
```yaml
moderator:
aliyun:
enabled: true
access_key_id: ''
access_key_secret: ''
region: cn-shanghai
```
## 关键词词库过滤
如果你不想依赖于远程 API,可以在本地配置导入词库文件,让 Artalk 根据词语来检测垃圾评论:
```yaml
moderator:
keywords:
enabled: true
pending: false # 匹配成功设为待审状态
files: # 支持多个词库文件
- ./data/词库_1.txt
file_sep: "\n" # 词库文件内容分割符
replace_to: 'x' # 替换字符
```
- **pending**:当成功匹配时,是否将评论设为待审核状态。
- **files**:词库文件。允许多个文件,Artalk 启动时会合并词库。
- **file_sep**:词库文件内容分割符。例如:文件中每行一个词语,该项配置 `\n`。
- **replace_to**:替换字符。例如:该项设置为 `x`,你可以将 `pending` 设置为 `false`,评论自动过审,但匹配到的词语会被替换为 `x`,例如 `fxxk`、`xxxx`。
注:`replace_to` 不建议使用 `*` 星号,应为它和 Markdown 的加粗语法冲突。
## 使用验证码
你可以开启 Artalk 的验证码功能,支持图片和滑动验证码,[参考此处](./captcha.md)。
+88
View File
@@ -0,0 +1,88 @@
# 管理员 × 多站点
Artalk 支持多站点,管理员可以创建多个站点,并对不同站点的评论、页面进行集中管理。
## 创建管理员
执行命令根据命令行提示快速创建管理员。
```sh
./artalk admin
```
如果使用 Docker 可以执行以下命令:
```sh
docker exec -it artalk artalk admin
```
之后可使用管理员账户登录控制中心,在用户管理页面的图形界面可创建更多账户,无需手动编辑配置文件。
## 站点的创建和管理
你可以在侧边栏「[控制中心](../frontend/sidebar.md#控制中心)」创建多个站点,管理站点和快速切换站点。
## 管理员配置
你可以设置多个管理员账户,当输入框输入匹配管理员用户名和邮箱时,将弹出密码验证提示框,
并且只有管理员才能访问「[控制中心](../frontend/sidebar.md#控制中心)」,在前端对评论内容进行管理操作。
(可选操作)通过配置文件添加管理员:
```yaml
admin_users:
- name: admin
email: admin@example.com
password: (bcrypt)$2y$10$ti4vZYIrxVN8rLcYXVgXCO.GJND0dyI49r7IoF3xqIx8bBRmIBZRm
badge_name: 管理员
badge_color: '#0083FF'
- name: admin2
email: admin2@example.com
password: (bcrypt)$2y$10$ti4vZYIrxVN8rLcYXVgXCO.GJND0dyI49r7IoF3xqIx8bBRmIBZRm
badge_name: 小管理员
badge_color: '#0083FF'
```
每项配置的解释:
- **name** & **email**:用户名和邮箱,**不区分大小写**。
- **password**:用户密码。
支持 bcrypt 和 md5 加密,例如填写:`"(md5)50c21190c6e4e5418c6a90d2b5031119"`。
**建议使用更安全的 bcrypt 加密算法**,在 Linux 环境下,你可以使用 [htpasswd 命令](https://httpd.apache.org/docs/2.4/programs/htpasswd.html) 来生成密文:
```bash
unset HISTFILE # 临时禁用 history 防止密码在历史记录中出现
htpasswd -bnBC 10 "" "your_password" | tr -d ':'
```
然后配置填写:`"(bcrypt)$2y$10$ti4vZYIrxVN8rLcY..."`,以 `(bcrypt)` 开头。
命令解释参考:[Compute bcrypt hash from command line](https://unix.stackexchange.com/questions/307994/compute-bcrypt-hash-from-command-line#answer-419855)
- **badge_name**:用户显示的头衔徽标文字。
- **badge_color**:用户显示的头衔徽标背景颜色。
::: tip
可以通过环境变量配置管理员账户,参考:[环境变量配置](/guide/env.md)
:::
### 控制管理员接收邮件通知
当页面有新的评论时,默认配置是邮件会发送给全部管理员,但你可以配置 `receive_email` 强制禁用它。
这对于设定了多个邮箱,但又不希望某些邮箱收到评论邮件的情况很有帮助。
- **receive_email**:设置为 `false` 系统将不会发送邮件通知给该用户。
注:禁止后该管理员用户仍可以收到来自他人的 @AT 回复,只是当用户对页面进行评论时 (创建根评论时) 不发送邮件通知。
```yaml
admin_users:
- name: admin
receive_email: false # ← 强制不接收邮件
```
Loaded 100 of 938 files, more files were not shown because too many files have changed in this diff. Show more