mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-07-02 03:41:37 +00:00
Compare commits
601 Commits
v0.5.8
...
ginger/oidc
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c1ca272de | |||
| a5ee1fb009 | |||
| f57485b8b7 | |||
| c3e156e78d | |||
| 30b15bd7be | |||
| c61473e8ee | |||
| 96c597138b | |||
| 586fb2102a | |||
| 5dead6621e | |||
| 67f5c3e595 | |||
| 51bb90250f | |||
| a9668f30a3 | |||
| 076046171a | |||
| c55db6f9bc | |||
| 870eeffe93 | |||
| 9db5d1646d | |||
| 3069194ffe | |||
| 8fe1715019 | |||
| 9a91dce600 | |||
| eee4ef50d2 | |||
| 62e0b53f52 | |||
| 5fa3d5f6c8 | |||
| 9b80a99aa7 | |||
| bd525c100f | |||
| e6225f3265 | |||
| 54c94ca9ad | |||
| 017d4b3894 | |||
| 3b3eaf8744 | |||
| 0a634907f2 | |||
| 2f2848728f | |||
| 19a83c6891 | |||
| 2bfd678c71 | |||
| e936d18324 | |||
| 90797fa3cd | |||
| 5eea8fe880 | |||
| 12491dcc26 | |||
| 2eff454787 | |||
| e5dc5bedfc | |||
| 496ca52987 | |||
| 72f4c3cc53 | |||
| 6a8a114197 | |||
| 549864a052 | |||
| 52026bb0f1 | |||
| aed8e7d769 | |||
| 32fb6f247a | |||
| 90e14abecb | |||
| 6ced2511e4 | |||
| 93407ade03 | |||
| 6742d9237a | |||
| a32c7d0d9a | |||
| 761a6a53d0 | |||
| c56c035c15 | |||
| c804bf5780 | |||
| b87afeef80 | |||
| d0c7a62ce7 | |||
| 47582d1922 | |||
| 36a30f16b1 | |||
| 52ec6bc6da | |||
| 74788dcb19 | |||
| b35b72c34a | |||
| c1fc76040a | |||
| d1449d6575 | |||
| 9fdeb61c1a | |||
| 7c7d6762e2 | |||
| eda46d63a8 | |||
| 9fc9063c83 | |||
| 430347fc66 | |||
| 9df5c68d3c | |||
| 3ca068c985 | |||
| 138ec05cf2 | |||
| c7e5c8df22 | |||
| 91afbd122f | |||
| daaf09cb26 | |||
| e8d6fa565e | |||
| 47af5d3a39 | |||
| 63b5fd04be | |||
| d59a5c63f9 | |||
| 16aaeae21c | |||
| e60310eacc | |||
| 7b98ae54b5 | |||
| d67d6ca895 | |||
| 86d9e9e6a9 | |||
| b37480d6b2 | |||
| 0d806a2038 | |||
| 19700a081e | |||
| ed1b175fa4 | |||
| a91fc7041a | |||
| 18c59e036f | |||
| df3f646c92 | |||
| fb6e5d2838 | |||
| 33be65a865 | |||
| 975ec24167 | |||
| e8378e86fd | |||
| 57366ac90a | |||
| 9f8a716dc1 | |||
| 27367bac18 | |||
| 5199cde870 | |||
| b6bc7dfc16 | |||
| 945ea5a78a | |||
| d719fe2048 | |||
| 458e0b53ac | |||
| 2d65d47498 | |||
| e4922814b9 | |||
| 064028689c | |||
| 124241238e | |||
| 967e2cc54f | |||
| 6fdeadc356 | |||
| 478560daae | |||
| 0310b4b2c5 | |||
| 3eb4257ae8 | |||
| f1d3db0ea3 | |||
| e7b302955f | |||
| 85122c62cd | |||
| ba0ffee7cf | |||
| 86e1101b40 | |||
| fdcb7e3957 | |||
| c54e56a73e | |||
| fed9a599d9 | |||
| 0bb97a53c5 | |||
| 9b76c9a085 | |||
| 6f20b7bc3f | |||
| 580d9b0318 | |||
| ae572ec108 | |||
| b1c5b3d000 | |||
| 0c9230f35e | |||
| 77dab8fd20 | |||
| 10b5ca8e3a | |||
| f9eed42cb7 | |||
| 19f4c24c00 | |||
| 0a162b7bc4 | |||
| 0d1b130127 | |||
| 5e0e82e7e8 | |||
| 4bf0816bcc | |||
| ecbe035b36 | |||
| 4d30ee5d33 | |||
| 4844c6ae3e | |||
| 6603798d60 | |||
| 199f6eb67b | |||
| aa2f506996 | |||
| a3994fe1a3 | |||
| 6312ff8088 | |||
| 17cff1fb36 | |||
| aff6315ae1 | |||
| 574d3e9164 | |||
| 21e93f8feb | |||
| 4b2f032ae6 | |||
| 8a495a7d7f | |||
| cee51d5717 | |||
| 0483d3e155 | |||
| 2a4b9f9323 | |||
| 63a1a3d9ab | |||
| f19f5c71a5 | |||
| b009ffd31c | |||
| b6baf66399 | |||
| 6dac46e1ad | |||
| 4d40e20fdd | |||
| 3b6858e936 | |||
| 3b455218f5 | |||
| de24fcbb8c | |||
| 2adb9a7941 | |||
| d81f4df61c | |||
| 6b259d15ee | |||
| eeef60d540 | |||
| a01035e63a | |||
| 52c1544e6f | |||
| ed38212391 | |||
| 86fe98c90d | |||
| 4078062331 | |||
| 40935cf96a | |||
| 182c5a120e | |||
| 8e71ed7b63 | |||
| 7ca00e4ab9 | |||
| b8ca06029f | |||
| 2efe8f2ec0 | |||
| d1aa911739 | |||
| 4673282ca1 | |||
| 0c03195aec | |||
| 439bc2784d | |||
| 689a1ce59b | |||
| c141503ccb | |||
| bcadecdc3b | |||
| ab3be337cb | |||
| aa1281a9e0 | |||
| 115a2e802e | |||
| 968328d788 | |||
| f1cde5f323 | |||
| 832ee8650b | |||
| c0666a1793 | |||
| ddb4ef539f | |||
| 3faedc4581 | |||
| a3544353ba | |||
| b0612397d3 | |||
| 31737e127e | |||
| 486dcd208c | |||
| a945a4b2ad | |||
| c28ea44e11 | |||
| 3e4d6b2565 | |||
| 29ce21cd2e | |||
| d461c6977a | |||
| 5a0d6461d1 | |||
| 2ec7394785 | |||
| 8a5708b9f9 | |||
| cd46070bd3 | |||
| 9930e549a0 | |||
| 36ed20cb04 | |||
| 3907589b6c | |||
| 2a598af888 | |||
| f34f84832b | |||
| 0efa6ed1f2 | |||
| 2bf5876778 | |||
| 31982e84de | |||
| 970958652a | |||
| c94a395bf0 | |||
| 43adff926f | |||
| 04fce56381 | |||
| 4df2097e6c | |||
| 8b85b04d10 | |||
| 9e0bcd3be8 | |||
| 9509080e0d | |||
| 61066bb0c6 | |||
| 573d5bc50e | |||
| 162e6eb92f | |||
| cef4ebe38e | |||
| 316a0b7d58 | |||
| 2bcc56704b | |||
| 7f64de9727 | |||
| aea03f2f99 | |||
| 8edf9552b8 | |||
| d5f69c8a31 | |||
| 9ea9b0e04c | |||
| e8db01fc8d | |||
| f80e1e89a5 | |||
| b9dca84acf | |||
| e3ec1066c4 | |||
| 1445a8d446 | |||
| 9547c438d6 | |||
| 51d0e615f5 | |||
| eeb937416c | |||
| 0d5aa7ede1 | |||
| ba9dc27773 | |||
| abf5a155ba | |||
| 4696cbb751 | |||
| ebea06b687 | |||
| 62b58e1a6a | |||
| 1ba90deeba | |||
| 71ed283141 | |||
| a7ae7b2e75 | |||
| 0d45ae7e21 | |||
| 61e121ad5c | |||
| 31960beb75 | |||
| bdd9b6b50c | |||
| 216033cf20 | |||
| 95ddb1bbe5 | |||
| 1ad4ca0f67 | |||
| 95790d8152 | |||
| 02c61b3840 | |||
| 6ee501ac69 | |||
| 252ebb4642 | |||
| 0fb95df7a5 | |||
| a72eda19f1 | |||
| 4fc808114f | |||
| e3a9549824 | |||
| 073c033ab8 | |||
| 6e42be95bc | |||
| 1a77f57af5 | |||
| d427df0238 | |||
| f9f3ebe571 | |||
| 5969c1ae94 | |||
| 523016a42b | |||
| 7c42f6075b | |||
| bc37f7fc5b | |||
| 0932c929c3 | |||
| 8f4e95b4b9 | |||
| e84d1f02af | |||
| 772a326ac1 | |||
| 6276a632cc | |||
| bb48bd50bb | |||
| 3fb7586875 | |||
| e8cfde49ae | |||
| 7af4b392b3 | |||
| 2bdc498f18 | |||
| 9dfd143cc6 | |||
| 721ebbf340 | |||
| 0a5d136a32 | |||
| 0ece17b6a0 | |||
| 7d945bbd5d | |||
| 42039b2090 | |||
| dd7ca6b12e | |||
| b1c6be012a | |||
| 835308628e | |||
| c1486f425e | |||
| c80896dcb0 | |||
| 77b12692bb | |||
| 57237e831a | |||
| d62c48ebf7 | |||
| e2e85b962a | |||
| 788697d563 | |||
| 64ecd762be | |||
| 5cb0db6f31 | |||
| 58e41d48c7 | |||
| 67466b015b | |||
| 0ea68f27a2 | |||
| a3e57dbab4 | |||
| 7ece15bb1a | |||
| 336b32dead | |||
| 1faa09b6ce | |||
| d7a51c7107 | |||
| 30c9d6d2df | |||
| 74841b6711 | |||
| dabbdc7517 | |||
| 793d399477 | |||
| 15d69aefbb | |||
| 77b1652f4a | |||
| 5f9594363d | |||
| 5cba4b126f | |||
| d8a7f7c7ca | |||
| d3fca86dec | |||
| 5f88abf341 | |||
| 416814094c | |||
| 5b8799e71f | |||
| cc5349ee57 | |||
| 7b68572b2e | |||
| 057eb9f644 | |||
| 253603edbc | |||
| b771b9d160 | |||
| eb829c2951 | |||
| d32b39181a | |||
| 72b99a1f84 | |||
| ae37f218a2 | |||
| 40cecca103 | |||
| 2a80a82f74 | |||
| fbf4eac2dc | |||
| 4784010702 | |||
| 1c88854a54 | |||
| e0fe71c708 | |||
| 0f0dcb4f58 | |||
| 367c42ad28 | |||
| c8e0f7ebd3 | |||
| fdc9aec534 | |||
| 5f9cc83b18 | |||
| 47051af392 | |||
| c1a6e649da | |||
| 1d172be503 | |||
| f01e119890 | |||
| 4d27a935d6 | |||
| 512a96f832 | |||
| 6715f63acc | |||
| 3764faeefc | |||
| 5d4b7bfea3 | |||
| 4df08779e3 | |||
| 6b835a327d | |||
| 7dd61cd560 | |||
| d9535eccf1 | |||
| a97f91e079 | |||
| f0401b4fc7 | |||
| cda64b880a | |||
| 1f6cab9e2e | |||
| afa80576f4 | |||
| 5a63eb729c | |||
| 27da50136e | |||
| db724b67ff | |||
| 14a0d2f538 | |||
| 3b9932e09c | |||
| 02409c06b8 | |||
| bb51db0d7d | |||
| 834f2caffe | |||
| 202786c46b | |||
| 035bfea93c | |||
| 185f8c42dc | |||
| d5fc81d39e | |||
| 1cd0228d87 | |||
| 4968d4c8b7 | |||
| bb6ec1f352 | |||
| 14602e730e | |||
| cdaca69f3a | |||
| 9c1d5b3e95 | |||
| 3987331c3b | |||
| cb3ebcf24e | |||
| 2d4bf1b35f | |||
| 388cbeb60e | |||
| b4e104925d | |||
| 14c1d37b47 | |||
| 1bba4fd252 | |||
| 8af0662a18 | |||
| 2804278e9b | |||
| 7c36bd54f5 | |||
| 8e9c7c1a3b | |||
| 8fe8438f5d | |||
| a7d4f3537b | |||
| 18789f9aea | |||
| 2f50f1fc2a | |||
| 669efe092f | |||
| 820485da57 | |||
| 466c98677c | |||
| 4d9cfc0afe | |||
| ba2c123e82 | |||
| 384ddc89d1 | |||
| a023d2d306 | |||
| 61b080d1ef | |||
| 00d7d4a54f | |||
| c4a35e0f4d | |||
| 86cb9b331a | |||
| 277f85f0b0 | |||
| 497ec44c94 | |||
| 7c837cc694 | |||
| 98fb766bc2 | |||
| 6f83925a4f | |||
| e349dd284f | |||
| c57fe66d8d | |||
| ff28fd0927 | |||
| 7307f2dc80 | |||
| 6f56b665e7 | |||
| 7018ce4180 | |||
| 10dd8bebfe | |||
| 1658b3bf6c | |||
| 088fa3e725 | |||
| 4694186c97 | |||
| a5c61d5137 | |||
| 39a882c4a1 | |||
| f091d3a732 | |||
| ebf9a08cd1 | |||
| 4fef0a7ff2 | |||
| 2f37b446bc | |||
| 6185841b6a | |||
| 3e0d4b066e | |||
| 0d2eeed567 | |||
| b296720540 | |||
| d600aed8db | |||
| 9724953b5e | |||
| 1605176956 | |||
| 2b0aedf5fd | |||
| c78c431703 | |||
| 49b48b857d | |||
| bf1e42b225 | |||
| ec76a234db | |||
| 091514e9f9 | |||
| 789ad499f7 | |||
| 1e6eaa4337 | |||
| de97900b07 | |||
| cb68a3d0ae | |||
| d3852abe51 | |||
| 15845b1c55 | |||
| f7d558baa6 | |||
| edd80b2600 | |||
| 03eab32c27 | |||
| 636de8a708 | |||
| e212c91ebf | |||
| 83f3314f08 | |||
| 8c2cf67783 | |||
| 7436e2f4e1 | |||
| 9ba406761b | |||
| 97f49d6357 | |||
| 1a49bc6f87 | |||
| 833216256b | |||
| 5fa3087401 | |||
| e95c0bd53f | |||
| 52d1ed24a9 | |||
| 4c1638e495 | |||
| 3f69cf8ed7 | |||
| 560a615c29 | |||
| 2e19310a87 | |||
| 81c5c6b2bc | |||
| 73d8462ace | |||
| 8b5fda1fb5 | |||
| 6f9b4a989e | |||
| fe0d83d447 | |||
| 37dccdbeb0 | |||
| 1060adc670 | |||
| d963b89a07 | |||
| 680c972b44 | |||
| 88b59eb053 | |||
| 4a99de0d28 | |||
| 0e1f0683c6 | |||
| cec4abc7cd | |||
| e6cae5b8ed | |||
| 02ccf64d2e | |||
| 4d4d875231 | |||
| cdf05b9a8b | |||
| 9491be928d | |||
| 049babc7ca | |||
| 7b99757337 | |||
| d09de005e3 | |||
| e34fd76dc0 | |||
| 72dfe579ec | |||
| cfae9a34f4 | |||
| 0a4808ea79 | |||
| a9a18fc5f0 | |||
| c1434c7935 | |||
| 2e98ba3ed8 | |||
| 551cf48642 | |||
| d256a1c1fa | |||
| 5578144da9 | |||
| 5309a064e8 | |||
| 56d35b4e39 | |||
| 7375d1cad4 | |||
| 80baf948ae | |||
| ed37696cef | |||
| 0a04c60f31 | |||
| e44ac230a6 | |||
| 57c4567380 | |||
| a8a8e1ea51 | |||
| 02f69a7160 | |||
| f68205a341 | |||
| 9899632b8b | |||
| a0524a9566 | |||
| e70004c98f | |||
| e185f56f3a | |||
| 5058b7979a | |||
| 7f06a61242 | |||
| 54fefb421b | |||
| 9d39321deb | |||
| c64a4a71bc | |||
| 385b4b10d1 | |||
| c12dd20431 | |||
| 3ad7c3b30d | |||
| 7a58074a0d | |||
| 0c7abd792d | |||
| 0f64e6b49c | |||
| e7a1c71a25 | |||
| cd3b97ea26 | |||
| 845b731f8c | |||
| 97d2388717 | |||
| 962a4aedc6 | |||
| 0eee63f7a1 | |||
| eba38c2fa0 | |||
| 338cdc2a75 | |||
| 2dacb8e071 | |||
| 398f73b690 | |||
| 78d9c29a05 | |||
| 0406f755c2 | |||
| 1827888f09 | |||
| 8871b1f74b | |||
| c7489fd008 | |||
| 7f5f4df64e | |||
| 15d87c00bf | |||
| 7cae42634e | |||
| bd94ec4033 | |||
| db7d378a2e | |||
| 39b2e461be | |||
| ca358438ee | |||
| 4282d60181 | |||
| 10dbea72e8 | |||
| aa7c2ea1ad | |||
| 698d959407 | |||
| 4c831c3531 | |||
| 4dfdce303f | |||
| 8d8c310a64 | |||
| e50e24e22d | |||
| a215b63077 | |||
| 1d39210a0c | |||
| 360e0dada8 | |||
| cbf24a9483 | |||
| 6cb3f909c9 | |||
| b7c9ef89f0 | |||
| 64f7791ddb | |||
| 836047b54e | |||
| 256f8f679d | |||
| 154cda35f3 | |||
| 1bf6d2a117 | |||
| 69d33931fa | |||
| 83902a584b | |||
| bcff259875 | |||
| 496ca80393 | |||
| 34b992fc40 | |||
| 1ea9330df8 | |||
| 267e1c5d65 | |||
| 36285e7784 | |||
| 53ab20d1cd | |||
| 96adf034e6 | |||
| a75bf32a34 | |||
| c89ecd7b63 | |||
| 7f30f8419b | |||
| 0a81f4d629 | |||
| 4e456249ac | |||
| 01e403f05f | |||
| a2f6141f4b | |||
| 97a01a1500 | |||
| bf9c9716eb | |||
| 471eb54c66 | |||
| 755006c66d | |||
| ccd6072f2d | |||
| 24f7e1d658 | |||
| d62eeda130 | |||
| 3e1f97487f | |||
| a4e64383b7 | |||
| 204bc1367e | |||
| 1cc9dbf2a4 | |||
| 2cf28baf03 | |||
| f3fb218652 | |||
| 0924b7d27e | |||
| 8575f191a0 | |||
| fe7cfd96e7 | |||
| 8b0e86a05d | |||
| 8b8fef998c | |||
| decd6083a0 | |||
| 06184d8c9f | |||
| 7c20e22b75 | |||
| 3f862b58cb | |||
| 046a6356f3 | |||
| 3af0240ff5 | |||
| 5dcfff51cf |
@@ -44,7 +44,7 @@ runs:
|
||||
|
||||
- name: Login to builtin registry
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
|
||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4
|
||||
with:
|
||||
registry: ${{ env.BUILTIN_REGISTRY }}
|
||||
username: ${{ inputs.registry_user }}
|
||||
@@ -52,7 +52,7 @@ runs:
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
with:
|
||||
# Use persistent BuildKit if BUILDKIT_ENDPOINT is set (e.g. tcp://buildkit:8125)
|
||||
driver: ${{ env.BUILDKIT_ENDPOINT != '' && 'remote' || 'docker-container' }}
|
||||
@@ -61,7 +61,7 @@ runs:
|
||||
- name: Extract metadata (tags) for Docker
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
id: meta
|
||||
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6
|
||||
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6
|
||||
with:
|
||||
flavor: |
|
||||
latest=auto
|
||||
|
||||
@@ -67,7 +67,7 @@ runs:
|
||||
uses: ./.forgejo/actions/rust-toolchain
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
||||
with:
|
||||
# Use persistent BuildKit if BUILDKIT_ENDPOINT is set (e.g. tcp://buildkit:8125)
|
||||
driver: ${{ env.BUILDKIT_ENDPOINT != '' && 'remote' || 'docker-container' }}
|
||||
@@ -75,11 +75,11 @@ runs:
|
||||
|
||||
- name: Set up QEMU
|
||||
if: ${{ env.BUILDKIT_ENDPOINT == '' }}
|
||||
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4
|
||||
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4
|
||||
|
||||
- name: Login to builtin registry
|
||||
if: ${{ env.BUILTIN_REGISTRY_ENABLED == 'true' }}
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
|
||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4
|
||||
with:
|
||||
registry: ${{ env.BUILTIN_REGISTRY }}
|
||||
username: ${{ inputs.registry_user }}
|
||||
@@ -87,7 +87,7 @@ runs:
|
||||
|
||||
- name: Extract metadata (labels, annotations) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6
|
||||
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6
|
||||
with:
|
||||
images: ${{ inputs.images }}
|
||||
# default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509
|
||||
|
||||
@@ -33,7 +33,7 @@ runs:
|
||||
echo "version=$(rustup --version)" >> $GITHUB_OUTPUT
|
||||
- name: Cache rustup toolchains
|
||||
if: steps.rustup-version.outputs.version == ''
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.rustup
|
||||
|
||||
@@ -17,7 +17,7 @@ inputs:
|
||||
llvm-version:
|
||||
description: 'LLVM version to install'
|
||||
required: false
|
||||
default: '20'
|
||||
default: '21'
|
||||
|
||||
outputs:
|
||||
llvm-version:
|
||||
@@ -57,7 +57,7 @@ runs:
|
||||
|
||||
- name: Check for LLVM cache
|
||||
id: cache
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
/usr/bin/clang-*
|
||||
|
||||
@@ -65,7 +65,7 @@ runs:
|
||||
|
||||
- name: Cache toolchain binaries
|
||||
id: toolchain-cache
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
.cargo/bin
|
||||
@@ -76,7 +76,7 @@ runs:
|
||||
|
||||
- name: Cache Cargo registry and git
|
||||
id: registry-cache
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
.cargo/registry/index
|
||||
|
||||
@@ -31,7 +31,7 @@ runs:
|
||||
|
||||
- name: Restore binary cache
|
||||
id: binary-cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
/usr/share/rust/.cargo/bin
|
||||
@@ -71,13 +71,13 @@ runs:
|
||||
|
||||
- name: Install timelord-cli and git-warp-time
|
||||
if: steps.check-binaries.outputs.need-install == 'true'
|
||||
uses: https://github.com/taiki-e/install-action@74e87cbfa15a59692b158178d8905a61bf6fca95 # v2
|
||||
uses: https://github.com/taiki-e/install-action@9bcaee1dcae34154180f412e2fa69355a7cda9f6 # v2
|
||||
with:
|
||||
tool: git-warp-time,timelord-cli@3.0.1
|
||||
|
||||
- name: Save binary cache
|
||||
if: steps.check-binaries.outputs.need-install == 'true'
|
||||
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
/usr/share/rust/.cargo/bin
|
||||
@@ -87,7 +87,7 @@ runs:
|
||||
|
||||
- name: Restore timelord cache with fallbacks
|
||||
id: timelord-restore
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: ${{ env.TIMELORD_CACHE_PATH }}
|
||||
key: ${{ env.TIMELORD_KEY }}
|
||||
@@ -114,7 +114,7 @@ runs:
|
||||
timelord sync --source-dir ${{ env.TIMELORD_PATH }} --cache-dir ${{ env.TIMELORD_CACHE_PATH }}
|
||||
|
||||
- name: Save updated timelord cache immediately
|
||||
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: ${{ env.TIMELORD_CACHE_PATH }}
|
||||
key: ${{ env.TIMELORD_KEY }}
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
- [ ] I have [tested my contribution][c1t] (or proof-read it for documentation-only changes)
|
||||
myself, if applicable. This includes ensuring code compiles.
|
||||
- [ ] My commit messages follow the [commit message format][c1cm] and are descriptive.
|
||||
- [ ] I have written a [news fragment][n1] for this PR, if applicable<!--(can be done after hitting open!)-->.
|
||||
|
||||
<!--
|
||||
Notes on these requirements:
|
||||
@@ -79,4 +78,3 @@
|
||||
[c1pc]: https://forgejo.ellis.link/continuwuation/continuwuity/src/branch/main/CONTRIBUTING.md#pre-commit-checks
|
||||
[c1t]: https://forgejo.ellis.link/continuwuation/continuwuity/src/branch/main/CONTRIBUTING.md#running-tests-locally
|
||||
[c1cm]: https://forgejo.ellis.link/continuwuation/continuwuity/src/branch/main/CONTRIBUTING.md#commit-messages
|
||||
[n1]: https://towncrier.readthedocs.io/en/stable/tutorial.html#creating-news-fragments
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
const labelsToAdd = new Set();
|
||||
|
||||
for (const file of fileNames) {
|
||||
if (file.startsWith('docs/') || file.startsWith('theme/') || file.endsWith('.md') || file == 'rspress.config.ts') {
|
||||
if (file.startsWith('docs/') || file.startsWith('theme/') || (file.endsWith('.md') && !file.startsWith('changelog.d/')) || file == 'rspress.config.ts') {
|
||||
labelsToAdd.add('Documentation');
|
||||
}
|
||||
if (file.startsWith('.forgejo/')) {
|
||||
|
||||
@@ -10,7 +10,7 @@ on:
|
||||
- "v*.*.*"
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '30 0 * * *'
|
||||
- cron: '30 0 * * 1'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -41,26 +41,15 @@ jobs:
|
||||
# else
|
||||
# echo "No workaround needed for llvm-project#153385"
|
||||
# fi
|
||||
- name: Pick compatible clang version
|
||||
id: clang-version
|
||||
run: |
|
||||
# both latest need to use clang-23, but oldstable and previous can just use clang
|
||||
if [[ "${{ matrix.container }}" == "ubuntu-latest" ]]; then
|
||||
echo "Using clang-23 package for ${{ matrix.container }}"
|
||||
echo "version=clang-23" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Using default clang package for ${{ matrix.container }}"
|
||||
echo "version=clang" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Checkout repository with full history
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.ref_name }}
|
||||
|
||||
- name: Cache Cargo registry
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
@@ -93,10 +82,10 @@ jobs:
|
||||
# VERSION is the package version, COMPONENT is used in
|
||||
# apt's repository config like a git repo branch
|
||||
VERSION=$BASE_VERSION
|
||||
if [[ ${{ forge.ref_name }} =~ ^v+[0-9]\.+[0-9]\.+[0-9]$ ]]; then
|
||||
if [[ ${{ forge.ref_name }} =~ ^v+[0-9]+\.+[0-9]+\.+[0-9]+$ ]]; then
|
||||
# Use the "stable" component for tagged semver releases
|
||||
COMPONENT="stable"
|
||||
elif [[ ${{ forge.ref }} =~ ^refs/tags/^v+[0-9]\.+[0-9]\.+[0-9] ]]; then
|
||||
elif [[ ${{ forge.ref_name }} =~ ^v+[0-9]+\.+[0-9]+\.+[0-9]+ ]]; then
|
||||
# Use the "unstable" component for tagged semver pre-releases
|
||||
COMPONENT="unstable"
|
||||
else
|
||||
@@ -130,7 +119,7 @@ jobs:
|
||||
run: |
|
||||
apt-get update -y
|
||||
# Build dependencies for rocksdb
|
||||
apt-get install -y liburing-dev ${{ steps.clang-version.outputs.version }}
|
||||
apt-get install -y liburing-dev clang
|
||||
|
||||
- name: Run cargo-deb
|
||||
id: cargo-deb
|
||||
|
||||
@@ -16,7 +16,7 @@ on:
|
||||
# - '.forgejo/workflows/build-fedora.yml'
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '30 0 * * *'
|
||||
- cron: '30 0 * * 2'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -30,14 +30,14 @@ jobs:
|
||||
echo "Fedora version: $VERSION"
|
||||
|
||||
- name: Checkout repository with full history
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.ref_name }}
|
||||
|
||||
|
||||
- name: Cache DNF packages
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
/var/cache/dnf
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
dnf-fedora${{ steps.fedora.outputs.version }}-
|
||||
|
||||
- name: Cache Cargo registry
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
cargo-fedora${{ steps.fedora.outputs.version }}-
|
||||
|
||||
- name: Cache Rust build dependencies
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/rpmbuild/BUILD/*/target/release/deps
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
RELEASE_SUFFIX=""
|
||||
TAG_NAME="${{ github.ref_name }}"
|
||||
# Extract version from tag (remove v prefix if present)
|
||||
TAG_VERSION=$(echo "$TAG_NAME" | sed 's/^v//')
|
||||
TAG_VERSION=$(echo "$TAG_NAME" | sed 's/^v//' | tr '-' '~')
|
||||
|
||||
# Create spec file with tag version
|
||||
sed -e "s/^Version:.*$/Version: $TAG_VERSION/" \
|
||||
@@ -270,9 +270,13 @@ jobs:
|
||||
|
||||
# Determine the group based on ref type and branch
|
||||
if [[ "${{ github.ref }}" == "refs/tags/"* ]]; then
|
||||
GROUP="stable"
|
||||
# For tags, extract the tag name for version info
|
||||
TAG_NAME="${{ github.ref_name }}"
|
||||
if [[ "$TAG_NAME" == *"-"* ]]; then
|
||||
GROUP="unstable"
|
||||
else
|
||||
GROUP="stable"
|
||||
fi
|
||||
elif [ "${{ github.ref_name }}" = "main" ]; then
|
||||
GROUP="dev"
|
||||
else
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
name: Build / Static via Nix
|
||||
|
||||
concurrency:
|
||||
group: "build-nix-${{ forge.ref }}"
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '30 0 * * 3'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: "Build ${{ matrix.filename }} Binary"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- package: default-static-x86_64
|
||||
filename: conduwuit-linux-static-amd64
|
||||
- package: default-static-aarch64
|
||||
filename: conduwuit-linux-static-arm64
|
||||
|
||||
- package: max-perf-static-aarch64
|
||||
filename: conduwuit-linux-static-arm64-maxperf
|
||||
- package: max-perf-haswell-static-x86_64
|
||||
filename: conduwuit-haswell-linux-static-amd64-maxperf
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
|
||||
|
||||
- name: Install Lix
|
||||
uses: https://github.com/samueldr/lix-gha-installer-action@a0fee77b2a98bb7c5c0ed7ae6d6ad4903dbdad0d
|
||||
with:
|
||||
extra_nix_config: experimental-features = nix-command flakes flake-self-attrs
|
||||
|
||||
- name: Build static binary
|
||||
run: |
|
||||
nix build .#${{ matrix.package }}
|
||||
install -D result/bin/conduwuit /tmp/binaries/${{ matrix.filename }}
|
||||
|
||||
- name: Upload binary artifact
|
||||
uses: forgejo/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.filename }}
|
||||
path: /tmp/binaries/${{ matrix.filename }}
|
||||
|
||||
release-binaries:
|
||||
name: "Release Binaries"
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
permissions:
|
||||
contents: write
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- name: Download binary artifacts
|
||||
uses: forgejo/download-artifact@v4
|
||||
with:
|
||||
pattern: conduwuit*
|
||||
path: binaries
|
||||
merge-multiple: true
|
||||
- name: Create Release and Upload
|
||||
uses: https://github.com/softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3
|
||||
with:
|
||||
draft: true
|
||||
files: binaries/*
|
||||
@@ -14,23 +14,19 @@ jobs:
|
||||
name: Check changelog is added
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
sparse-checkout: .
|
||||
|
||||
- name: Check for changelog entry
|
||||
id: check_files
|
||||
run: |
|
||||
git fetch origin ${GITHUB_BASE_REF}
|
||||
AUTH=$(echo -n "x-access-token:${{ secrets.GITHUB_TOKEN }}" | base64 -w 0)
|
||||
git config --global http.${{ github.server_url }}/.extraheader "Authorization: basic $AUTH"
|
||||
git clone "${{ github.event.repository.clone_url }}" repo.git --bare
|
||||
|
||||
git -C repo.git fetch origin pull/${{ github.event.pull_request.number }}/head
|
||||
|
||||
# Check for Added (A) or Modified (M) files in changelog.d
|
||||
CHANGELOG_CHANGES=$(git diff --name-status origin/${GITHUB_BASE_REF}...HEAD -- changelog.d/)
|
||||
CHANGELOG_CHANGES=$(git -C repo.git diff --name-status ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} -- changelog.d/)
|
||||
|
||||
SRC_CHANGES=$(git diff --name-status origin/${GITHUB_BASE_REF}...HEAD -- src/)
|
||||
SRC_CHANGES=$(git -C repo.git diff --name-status ${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }} -- src/)
|
||||
|
||||
echo "Changes in changelog.d/:"
|
||||
echo "$CHANGELOG_CHANGES"
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Sync repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
node-version: 22
|
||||
|
||||
- name: Cache npm dependencies
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: continuwuity-rspress-${{ steps.runner-env.outputs.slug }}-${{ steps.runner-env.outputs.arch }}-node-${{ steps.runner-env.outputs.node_version }}-${{ hashFiles('package-lock.json') }}
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
|
||||
- name: Deploy to Cloudflare Pages (Production)
|
||||
if: github.ref == 'refs/heads/main' && vars.CLOUDFLARE_PROJECT_NAME != ''
|
||||
uses: https://github.com/cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3
|
||||
uses: https://github.com/cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4
|
||||
with:
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
|
||||
- name: Deploy to Cloudflare Pages (Preview)
|
||||
if: github.ref != 'refs/heads/main' && vars.CLOUDFLARE_PROJECT_NAME != ''
|
||||
uses: https://github.com/cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3
|
||||
uses: https://github.com/cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4
|
||||
with:
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
|
||||
@@ -121,7 +121,7 @@ jobs:
|
||||
- name: 🚀 Deploy to Cloudflare Pages
|
||||
if: vars.CLOUDFLARE_PROJECT_NAME != ''
|
||||
id: deploy
|
||||
uses: https://github.com/cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3
|
||||
uses: https://github.com/cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4
|
||||
with:
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
DOCKER_MIRROR_TOKEN: ${{ secrets.DOCKER_MIRROR_TOKEN }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
# repositories: continuwuity
|
||||
|
||||
- name: Install regsync
|
||||
uses: https://github.com/regclient/actions/regsync-installer@f3c6d87835906c175eb6ccfc18b348b69bb447e7 # main
|
||||
uses: https://github.com/regclient/actions/regsync-installer@9a2d4216180dbb3e2dccfa60d2dd4afd98e42ec5 # main
|
||||
|
||||
- name: Check what images need mirroring
|
||||
run: |
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -48,12 +48,12 @@ jobs:
|
||||
rust: ${{ steps.filter.outputs.rust }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check for file changes
|
||||
uses: https://github.com/dorny/paths-filter@v4
|
||||
uses: https://github.com/dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Prepare Docker build environment
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push Docker image by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
with:
|
||||
context: .
|
||||
file: "docker/Dockerfile"
|
||||
@@ -100,7 +100,7 @@ jobs:
|
||||
needs: build-release
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Create multi-platform manifest
|
||||
@@ -133,7 +133,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Prepare max-perf Docker build environment
|
||||
@@ -149,7 +149,7 @@ jobs:
|
||||
registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push max-perf Docker image by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7
|
||||
with:
|
||||
context: .
|
||||
file: "docker/Dockerfile"
|
||||
@@ -187,7 +187,7 @@ jobs:
|
||||
needs: build-maxperf
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Create max-perf manifest
|
||||
@@ -199,6 +199,28 @@ jobs:
|
||||
registry_user: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }}
|
||||
registry_password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}
|
||||
|
||||
release-binaries:
|
||||
name: "Release Binaries"
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build-release
|
||||
- build-maxperf
|
||||
permissions:
|
||||
contents: write
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- name: Download binary artifacts
|
||||
uses: forgejo/download-artifact@v4
|
||||
with:
|
||||
pattern: conduwuit*
|
||||
path: binaries
|
||||
merge-multiple: true
|
||||
- name: Create Release and Upload
|
||||
uses: https://github.com/softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3
|
||||
with:
|
||||
draft: true
|
||||
files: binaries/*
|
||||
|
||||
mirror_images:
|
||||
name: "Mirror Images"
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -43,11 +43,11 @@ jobs:
|
||||
name: Renovate
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/renovatebot/renovate:43.140.0@sha256:61303c28b10a491c559529fb6f41745850e4755a43a54c04c3ae6848d6eaf5cc
|
||||
image: ghcr.io/renovatebot/renovate:43.246.1@sha256:5965c08f8ca5baff8dc9bf3a32c44ca71fef843ad94880e9696d46e1d722b0fa
|
||||
options: --tmpfs /tmp:exec
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
show-progress: false
|
||||
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
run: /usr/local/renovate/node -e 'console.log(`node heap limit = ${require("v8").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'
|
||||
|
||||
- name: Restore renovate repo cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
/tmp/renovate/cache/renovate/repository
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
renovate-repo-cache-
|
||||
|
||||
- name: Restore renovate package cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
/tmp/renovate/cache/renovate/renovate-cache-sqlite
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
renovate-package-cache-
|
||||
|
||||
- name: Restore renovate OSV cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
/tmp/osv
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
|
||||
- name: Save renovate package cache
|
||||
if: always()
|
||||
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
/tmp/renovate/cache/renovate/renovate-cache-sqlite
|
||||
@@ -125,7 +125,7 @@ jobs:
|
||||
|
||||
- name: Save renovate OSV cache
|
||||
if: always()
|
||||
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
/tmp/osv
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
update-flake-hashes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
||||
with:
|
||||
persist-credentials: true
|
||||
token: ${{ secrets.FORGEJO_TOKEN }}
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
- name: Get new toolchain hash
|
||||
run: |
|
||||
# Set the current sha256 to an empty hash to make `nix build` calculate a new one
|
||||
awk '/fromToolchainFile *\{/{found=1; print; next} found && /sha256 =/{sub(/sha256 = .*/, "sha256 = lib.fakeSha256;"); found=0} 1' nix/rust.nix > temp.nix
|
||||
awk '/fromToolchainName *\{/{found=1; print; next} found && /sha256 =/{sub(/sha256 = .*/, "sha256 = lib.fakeSha256;"); found=0} 1' nix/rust.nix > temp.nix
|
||||
mv temp.nix nix/rust.nix
|
||||
|
||||
# Build continuwuity and filter for the new hash
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
sed -i "s|lib.fakeSha256|\"$new_hash\"|" nix/rust.nix
|
||||
|
||||
echo "New hash:"
|
||||
awk -F'"' '/fromToolchainFile/{found=1; next} found && /sha256 =/{print $2; found=0}' nix/rust.nix
|
||||
awk -F'"' '/fromToolchainName/{found=1; next} found && /sha256 =/{print $2; found=0}' nix/rust.nix
|
||||
echo "Expected new hash:"
|
||||
cat new_toolchain_hash.txt
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
github: [JadedBlueEyes, nexy7574, gingershaped]
|
||||
github: [JadedBlueEyes, timedoutuk, gingershaped]
|
||||
custom:
|
||||
- https://timedout.uk/donate.html
|
||||
- https://jade.ellis.link/sponsors
|
||||
|
||||
@@ -24,7 +24,7 @@ repos:
|
||||
- id: check-added-large-files
|
||||
|
||||
- repo: https://github.com/crate-ci/typos
|
||||
rev: v1.45.1
|
||||
rev: v1.47.2
|
||||
hooks:
|
||||
- id: typos
|
||||
- id: typos
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
Contributors are expected to follow the [Continuwuity Community Guidelines](continuwuity.org/community/guidelines).
|
||||
Contributors are expected to follow the [Continuwuity Community Guidelines](https://continuwuity.org/community/guidelines).
|
||||
|
||||
+3
-3
@@ -137,9 +137,9 @@ ### Commit Messages
|
||||
|
||||
Examples:
|
||||
```
|
||||
feat: add user authentication
|
||||
fix(database): resolve connection pooling issue
|
||||
docs: update installation instructions
|
||||
feat: Add user authentication
|
||||
fix(database): Resolve connection pooling issue
|
||||
docs: Update installation instructions
|
||||
```
|
||||
|
||||
The project uses the `committed` hook to validate commit messages in pre-commit. This ensures all commits follow the conventional format.
|
||||
|
||||
Generated
+1229
-1126
File diff suppressed because it is too large
Load Diff
+55
-56
@@ -12,7 +12,7 @@ license = "Apache-2.0"
|
||||
# See also `rust-toolchain.toml`
|
||||
readme = "README.md"
|
||||
repository = "https://forgejo.ellis.link/continuwuation/continuwuity"
|
||||
version = "0.5.8"
|
||||
version = "26.6.0-alpha.1"
|
||||
|
||||
[workspace.metadata.crane]
|
||||
name = "conduwuit"
|
||||
@@ -39,10 +39,13 @@ features = ["ffi", "std", "union"]
|
||||
version = "1.1.0"
|
||||
|
||||
[workspace.dependencies.ctor]
|
||||
version = "0.10.0"
|
||||
version = "1.0.6"
|
||||
|
||||
[workspace.dependencies.dtor]
|
||||
version = "1.0.0"
|
||||
|
||||
[workspace.dependencies.cargo_toml]
|
||||
version = "0.22"
|
||||
version = "1.0"
|
||||
default-features = false
|
||||
features = ["features"]
|
||||
|
||||
@@ -68,7 +71,7 @@ default-features = false
|
||||
version = "0.1.3"
|
||||
|
||||
[workspace.dependencies.rand]
|
||||
version = "0.10.0"
|
||||
version = "0.10.1"
|
||||
|
||||
# Used for the http request / response body type for Ruma endpoints used with reqwest
|
||||
[workspace.dependencies.bytes]
|
||||
@@ -121,7 +124,7 @@ default-features = false
|
||||
features = ["util"]
|
||||
|
||||
[workspace.dependencies.tower-http]
|
||||
version = "0.6.8"
|
||||
version = "0.7.0"
|
||||
default-features = false
|
||||
features = [
|
||||
"add-extension",
|
||||
@@ -161,7 +164,7 @@ features = ["raw_value"]
|
||||
|
||||
# Used for appservice registration files
|
||||
[workspace.dependencies.serde-saphyr]
|
||||
version = "0.0.24"
|
||||
version = "0.0.28"
|
||||
|
||||
# Used to load forbidden room/user regex from config
|
||||
[workspace.dependencies.serde_regex]
|
||||
@@ -177,7 +180,7 @@ version = "0.5.3"
|
||||
features = ["alloc", "rand"]
|
||||
default-features = false
|
||||
|
||||
# Used to generate thumbnails for images & blurhashes
|
||||
# Used to generate thumbnails for images
|
||||
[workspace.dependencies.image]
|
||||
version = "0.25.5"
|
||||
default-features = false
|
||||
@@ -188,14 +191,6 @@ features = [
|
||||
"webp",
|
||||
]
|
||||
|
||||
[workspace.dependencies.blurhash]
|
||||
version = "0.2.3"
|
||||
default-features = false
|
||||
features = [
|
||||
"fast-linear-to-srgb",
|
||||
"image",
|
||||
]
|
||||
|
||||
# logging
|
||||
[workspace.dependencies.log]
|
||||
version = "0.4.27"
|
||||
@@ -301,7 +296,7 @@ default-features = false
|
||||
features = ["env", "toml"]
|
||||
|
||||
[workspace.dependencies.hickory-resolver]
|
||||
version = "0.25.2"
|
||||
version = "0.26.0"
|
||||
default-features = false
|
||||
features = [
|
||||
"serde",
|
||||
@@ -321,7 +316,7 @@ default-features = false
|
||||
|
||||
# Used to make working with iterators easier, was already a transitive depdendency
|
||||
[workspace.dependencies.itertools]
|
||||
version = "0.14.0"
|
||||
version = "0.15.0"
|
||||
|
||||
# to parse user-friendly time durations in admin commands
|
||||
#TODO: overlaps chrono?
|
||||
@@ -342,56 +337,55 @@ version = "0.1.88"
|
||||
[workspace.dependencies.lru-cache]
|
||||
version = "0.1.2"
|
||||
|
||||
[workspace.dependencies.assign]
|
||||
version = "1.1.1"
|
||||
|
||||
# Used for matrix spec type definitions and helpers
|
||||
[workspace.dependencies.ruma]
|
||||
git = "https://forgejo.ellis.link/continuwuation/ruwuma"
|
||||
#branch = "conduwuit-changes"
|
||||
rev = "d00b51a8669b21689c4eb47fb81f3a8b27c3e371"
|
||||
# version = "0.14.1"
|
||||
git = "https://github.com/ruma/ruma.git"
|
||||
rev = "3ecd80b92794d2d93f657a7b3db62d4be237526b"
|
||||
features = [
|
||||
"compat",
|
||||
"rand",
|
||||
"appservice-api-c",
|
||||
"client-api",
|
||||
"federation-api",
|
||||
"markdown",
|
||||
"push-gateway-api-c",
|
||||
"unstable-exhaustive-types",
|
||||
"state-res",
|
||||
"rand",
|
||||
"markdown",
|
||||
"ring-compat",
|
||||
"compat-upload-signatures",
|
||||
"identifiers-validation",
|
||||
"unstable-unspecified",
|
||||
"unstable-msc2448",
|
||||
"compat-optional-txn-pdus",
|
||||
"compat-get-3pids",
|
||||
"unstable-msc2666",
|
||||
"unstable-msc2867",
|
||||
"unstable-msc2870",
|
||||
"unstable-msc3026",
|
||||
"unstable-msc3061",
|
||||
"unstable-msc3814",
|
||||
"unstable-msc3245",
|
||||
"unstable-msc3266",
|
||||
"unstable-msc3381", # polls
|
||||
"unstable-msc3489", # beacon / live location
|
||||
"unstable-msc3575",
|
||||
"unstable-msc3930", # polls push rules
|
||||
"unstable-msc3381",
|
||||
"unstable-msc3489",
|
||||
"unstable-msc3930",
|
||||
"unstable-msc4075",
|
||||
"unstable-msc4095",
|
||||
"unstable-msc4121",
|
||||
"unstable-msc4125",
|
||||
"unstable-msc4155",
|
||||
"unstable-msc4186",
|
||||
"unstable-msc4203", # sending to-device events to appservices
|
||||
"unstable-msc4210", # remove legacy mentions
|
||||
"unstable-msc4195",
|
||||
"unstable-msc4203",
|
||||
"unstable-msc4310",
|
||||
"unstable-msc4380",
|
||||
"unstable-msc4143",
|
||||
"unstable-msc4293",
|
||||
"unstable-msc4406",
|
||||
"unstable-msc4439",
|
||||
"unstable-msc4466",
|
||||
"unstable-extensible-events",
|
||||
"unstable-pdu",
|
||||
"unstable-msc4155",
|
||||
"unstable-msc4143", # livekit well_known response
|
||||
"unstable-msc4284",
|
||||
"unstable-msc4439", # pgp_key in .well_known/matrix/support
|
||||
]
|
||||
|
||||
[workspace.dependencies.rust-rocksdb]
|
||||
git = "https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1"
|
||||
rev = "31fb8f772c7afcdc0061ab6a40cfa3a1be2fccd9"
|
||||
rev = "0a25ff92f7c09b55eec496b9c192c7d5136ab2b8"
|
||||
default-features = false
|
||||
features = [
|
||||
"multi-threaded-cf",
|
||||
@@ -409,29 +403,32 @@ default-features = false
|
||||
version = "0.11.0"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.openidconnect]
|
||||
version = "4.0.1"
|
||||
|
||||
# optional opentelemetry, performance measurements, flamegraphs, etc for performance measurements and monitoring
|
||||
[workspace.dependencies.opentelemetry]
|
||||
version = "0.31.0"
|
||||
version = "0.32.0"
|
||||
|
||||
[workspace.dependencies.tracing-flame]
|
||||
version = "0.2.0"
|
||||
|
||||
[workspace.dependencies.tracing-opentelemetry]
|
||||
version = "0.32.0"
|
||||
version = "0.33.0"
|
||||
|
||||
[workspace.dependencies.opentelemetry_sdk]
|
||||
version = "0.31.0"
|
||||
version = "0.32.0"
|
||||
features = ["rt-tokio"]
|
||||
|
||||
[workspace.dependencies.opentelemetry-otlp]
|
||||
version = "0.31.0"
|
||||
version = "0.32.0"
|
||||
features = ["http", "grpc-tonic", "trace", "logs", "metrics"]
|
||||
|
||||
|
||||
|
||||
# optional sentry metrics for crash/panic reporting
|
||||
[workspace.dependencies.sentry]
|
||||
version = "0.47.0"
|
||||
version = "0.48.0"
|
||||
default-features = false
|
||||
features = [
|
||||
"backtrace",
|
||||
@@ -446,9 +443,9 @@ features = [
|
||||
]
|
||||
|
||||
[workspace.dependencies.sentry-tracing]
|
||||
version = "0.47.0"
|
||||
version = "0.48.0"
|
||||
[workspace.dependencies.sentry-tower]
|
||||
version = "0.47.0"
|
||||
version = "0.48.0"
|
||||
|
||||
# jemalloc usage
|
||||
[workspace.dependencies.tikv-jemalloc-sys]
|
||||
@@ -541,22 +538,17 @@ version = "2.1.1"
|
||||
features = ["std"]
|
||||
|
||||
[workspace.dependencies.minicbor-serde]
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
features = ["std"]
|
||||
|
||||
[workspace.dependencies.maplit]
|
||||
version = "1.0.2"
|
||||
|
||||
[workspace.dependencies.ldap3]
|
||||
version = "0.12.0"
|
||||
default-features = false
|
||||
features = ["sync", "tls-rustls", "rustls-provider"]
|
||||
|
||||
[workspace.dependencies.yansi]
|
||||
version = "1.0.1"
|
||||
|
||||
[workspace.dependencies.askama]
|
||||
version = "0.15.0"
|
||||
version = "0.16.0"
|
||||
|
||||
[workspace.dependencies.lettre]
|
||||
version = "0.11.19"
|
||||
@@ -571,6 +563,9 @@ features = ["std"]
|
||||
[workspace.dependencies.nonzero_ext]
|
||||
version = "0.3.0"
|
||||
|
||||
[workspace.dependencies.serde_urlencoded]
|
||||
version = "0.7.1"
|
||||
|
||||
#
|
||||
# Patches
|
||||
#
|
||||
@@ -658,6 +653,10 @@ default-features = false
|
||||
package = "conduwuit"
|
||||
path = "src/main"
|
||||
|
||||
[workspace.dependencies.ruminuwuity]
|
||||
package = "ruminuwuity"
|
||||
path = "src/ruminuwuity"
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Release profiles
|
||||
|
||||
@@ -23,6 +23,7 @@ ### Responsible Disclosure
|
||||
1. **Contact members of the team directly** over E2EE private message.
|
||||
- [@jade:ellis.link](https://matrix.to/#/@jade:ellis.link)
|
||||
- [@nex:nexy7574.co.uk](https://matrix.to/#/@nex:nexy7574.co.uk)
|
||||
- [@ginger:gingershaped.computer](https://matrix.to/#/@ginger:gingershaped.computer)
|
||||
2. **Email the security team** at [security@continuwuity.org](mailto:security@continuwuity.org). This is not E2EE, so don't include sensitive details.
|
||||
3. **Do not disclose the vulnerability publicly** until it has been addressed
|
||||
4. **Provide detailed information** about the vulnerability, including:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Appservice device management as outlined in MSC4190 (part of Matrix 1.17) is now fully supported. Contributed by @ginger.
|
||||
@@ -0,0 +1 @@
|
||||
The invite recipient's membership event is now included in invite stripped state, which should fix flaky invite display in some clients. Contributed by @ginger
|
||||
@@ -0,0 +1 @@
|
||||
Switched from Continuwuity's fork of Ruma back to upstream Ruma. Contributed by @ginger.
|
||||
@@ -0,0 +1 @@
|
||||
Users may now be forbidden from deactivating their own accounts with the new `allow_deactivation` config option. Contributed by @ginger.
|
||||
@@ -0,0 +1 @@
|
||||
Added support for Matrix 1.16's `state_after` feature, allowing clients which understand it to sync room state changes more reliably. Contributed by @ginger.
|
||||
@@ -0,0 +1 @@
|
||||
Added support for authenticating clients using the new OAuth 2.0 login API. Contributed by @ginger.
|
||||
@@ -0,0 +1 @@
|
||||
Added support for MSC4466, which allows clients to customize how changes to a user's global profile are propagated. Contributed by @ginger.
|
||||
@@ -0,0 +1 @@
|
||||
Devices which set their presence as "offline" will no longer be considered for presence updates. Contributed by @timedout.
|
||||
@@ -0,0 +1 @@
|
||||
Removed support for guest user registration, a little-used and deprecated approach to room previews.
|
||||
@@ -0,0 +1 @@
|
||||
The deprecated `well_known.rtc_focus_server_urls` config option has been removed. MatrixRTC foci should be configured using the `matrix_rtc.foci` config option.
|
||||
@@ -0,0 +1 @@
|
||||
The version of Debian that the Docker-based build process uses has been upgraded from Bookworm to Trixie, meaning that standalone binaries now have a minimum glibc of 2.41, and can no longer be used on distro versions from before 2025-01-30
|
||||
@@ -0,0 +1 @@
|
||||
Support for server-side blurhashing (part of MSC2448) has been removed.
|
||||
@@ -0,0 +1 @@
|
||||
Updated [MSC4284: Policy Servers](https://github.com/matrix-org/matrix-spec-proposals/pull/4284) implementation to support the newly stabilised proposal. Contributed by @nex.
|
||||
@@ -0,0 +1 @@
|
||||
Add performance tuning documentation. Contributed by @stratself.
|
||||
@@ -0,0 +1 @@
|
||||
Added config option for default room ACLs. Contributed by @eve.
|
||||
@@ -0,0 +1 @@
|
||||
Removed support for LDAP.
|
||||
@@ -0,0 +1 @@
|
||||
Clarified in the config that `max_request_size` affects federated media as well.
|
||||
@@ -0,0 +1 @@
|
||||
Added support for fallback encryption keys.
|
||||
@@ -0,0 +1 @@
|
||||
Fixed a bug that caused the server to drop events during processing if several events for the same room were sent in a singular transaction. Contributed by @nex.
|
||||
@@ -0,0 +1 @@
|
||||
Add `!admin users reject-all-invites` to clean invite spam
|
||||
@@ -0,0 +1 @@
|
||||
fix `!admin query account-data account-data-get` not returning the content
|
||||
@@ -0,0 +1,9 @@
|
||||
Implemented event rejection, which should resolve and prevent future netsplits of the kinds observed
|
||||
within some Continuwuity rooms.
|
||||
Also resolved several bugs related to both soft-failing events, and event backfilling, which should
|
||||
improve state resolution stability.
|
||||
The `!admin debug get-pdu` command was updated to disambiguate event acceptance status, and
|
||||
`!admin debug show-auth-chain` was added to visually display event auth chains, which may assist
|
||||
developers in debugging strangely complex events.
|
||||
|
||||
Contributed by @nex.
|
||||
@@ -0,0 +1 @@
|
||||
Fixed an issue where Continuwuity would only advertise support for the unstable endpoint for Mutual Rooms (MSC2666), despite only supporting the stable endpoint. Contributed by @Henry-Hiles (QuadRadical)
|
||||
@@ -0,0 +1 @@
|
||||
Added example configuration using caddy-docker-proxy in the livekit setup section of the docs. Contributed by @Cease
|
||||
@@ -0,0 +1 @@
|
||||
Fixed admin commands being ignored when they had leading whitespace before admin commands. Contributed by @kitvonsnookerz.
|
||||
@@ -0,0 +1 @@
|
||||
Fixed several bugs in the `POST /_matrix/client/v3/rooms/{roomId}/upgrade` endpoint. Contributed by @nex.
|
||||
@@ -0,0 +1 @@
|
||||
Added full support for [MSC4168: Update `m.space.*` state on room upgrade](https://github.com/matrix-org/matrix-spec-proposals/pull/4168). Contributed by @nex.
|
||||
@@ -0,0 +1,2 @@
|
||||
Improved the performance and reliability of fetching missing events, improving network partition recovery. Contributed
|
||||
by @nex.
|
||||
@@ -0,0 +1 @@
|
||||
Remove support for MSC4373, as the MSC is now closed. Contributed by @vel.
|
||||
@@ -0,0 +1 @@
|
||||
Added static builds using Nix, allowing for Continuwuity on musl. During this, we also introduced a `max-perf-haswell` package, separating it from `max-perf`, so you may want to swap to this if you are on NixOS. Contributed by @Henry-Hiles (QuadRadical).
|
||||
@@ -0,0 +1 @@
|
||||
Added support for MSC4380 invite blocking, which has become part of the Matrix specification in v1.18. Contributed by @nex.
|
||||
@@ -0,0 +1 @@
|
||||
Added `!admin debug get-state-at` command
|
||||
@@ -0,0 +1 @@
|
||||
Added support for linking an external identity provider with OIDC. Contributed by @ginger.
|
||||
@@ -0,0 +1 @@
|
||||
Adjusted legacy sync logic to no longer use the `roomsynctoken_shortstatehash` database column. Once this change has been confirmed to be stable and reliable, a future update will remove it entirely, significantly decreasing database sizes. Contributed by @ginger.
|
||||
@@ -7,7 +7,6 @@
|
||||
[global]
|
||||
address = "0.0.0.0"
|
||||
allow_device_name_federation = true
|
||||
allow_guest_registration = true
|
||||
allow_public_room_directory_over_federation = true
|
||||
allow_registration = true
|
||||
database_path = "/database"
|
||||
@@ -32,7 +31,6 @@ rocksdb_log_level = "info"
|
||||
rocksdb_max_log_files = 1
|
||||
rocksdb_recovery_mode = 0
|
||||
rocksdb_paranoid_file_checks = true
|
||||
log_guest_registrations = false
|
||||
allow_legacy_media = true
|
||||
startup_netburst = true
|
||||
startup_netburst_keep = -1
|
||||
|
||||
+178
-185
@@ -291,12 +291,13 @@
|
||||
#ip_lookup_strategy = 5
|
||||
|
||||
# Max request size for file uploads in bytes. Defaults to 20MB.
|
||||
# Also limits incoming federated media.
|
||||
#
|
||||
#max_request_size = 20971520
|
||||
|
||||
# This item is undocumented. Please contribute documentation for it.
|
||||
#
|
||||
#max_fetch_prev_events = 192
|
||||
#max_fetch_prev_events = 1024
|
||||
|
||||
# How many incoming federation transactions the server is willing to be
|
||||
# processing at any given time before it becomes overloaded and starts
|
||||
@@ -371,21 +372,18 @@
|
||||
#
|
||||
#federation_timeout = 60
|
||||
|
||||
# MSC4284 Policy server request timeout (seconds). Generally policy
|
||||
# Policy server request timeout (seconds). Generally policy
|
||||
# servers should respond near instantly, however may slow down under
|
||||
# load. If a policy server doesn't respond in a short amount of time, the
|
||||
# room it is configured in may become unusable if this limit is set too
|
||||
# high. 10 seconds is a good default, however dropping this to 3-5 seconds
|
||||
# can be acceptable.
|
||||
# high. 30 seconds is a good default, however lower values may be
|
||||
# acceptable if temporary send failures are an okay trade-off.
|
||||
#
|
||||
# Please be aware that policy requests are *NOT* currently re-tried, so if
|
||||
# a spam check request fails, the event will be assumed to be not spam,
|
||||
# which in some cases may result in spam being sent to or received from
|
||||
# the room that would typically be prevented.
|
||||
#
|
||||
# About policy servers: https://matrix.org/blog/2025/04/introducing-policy-servers/
|
||||
# (Stabilized in Matrix v1.18)
|
||||
#
|
||||
#policy_server_request_timeout = 10
|
||||
#policy_server_request_timeout = 30
|
||||
|
||||
# Federation client idle connection pool timeout (seconds).
|
||||
#
|
||||
@@ -523,17 +521,15 @@
|
||||
#
|
||||
#recaptcha_private_site_key =
|
||||
|
||||
# Policy documents, such as terms and conditions or a privacy policy,
|
||||
# which users must agree to when registering an account.
|
||||
# Controls whether users are allowed to deactivate their own accounts
|
||||
# through the account management panel or their Matrix clients. Server
|
||||
# admins can always deactivate users using the relevant admin commands.
|
||||
#
|
||||
# Example:
|
||||
# ```ignore
|
||||
# [global.registration_terms.privacy_policy]
|
||||
# en = { name = "Privacy Policy", url = "https://homeserver.example/en/privacy_policy.html" }
|
||||
# es = { name = "Política de Privacidad", url = "https://homeserver.example/es/privacy_policy.html" }
|
||||
# ```
|
||||
# Note that, in some jurisdictions, you may be legally required to honor
|
||||
# users who request to deactivate their accounts if you set this option
|
||||
# to `false`.
|
||||
#
|
||||
#registration_terms = {}
|
||||
#allow_deactivation = true
|
||||
|
||||
# Controls whether encrypted rooms and events are allowed.
|
||||
#
|
||||
@@ -573,18 +569,6 @@
|
||||
#
|
||||
#allow_public_room_directory_over_federation = false
|
||||
|
||||
# Allow guests/unauthenticated users to access TURN credentials.
|
||||
#
|
||||
# This is the equivalent of Synapse's `turn_allow_guests` config option.
|
||||
# This allows any unauthenticated user to call the endpoint
|
||||
# `/_matrix/client/v3/voip/turnServer`.
|
||||
#
|
||||
# It is unlikely you need to enable this as all major clients support
|
||||
# authentication for this endpoint and prevents misuse of your TURN server
|
||||
# from potential bots.
|
||||
#
|
||||
#turn_allow_guests = false
|
||||
|
||||
# Set this to true to lock down your server's public room directory and
|
||||
# only allow admins to publish rooms to the room directory. Unpublishing
|
||||
# is still allowed by all users with this enabled.
|
||||
@@ -635,6 +619,38 @@
|
||||
#
|
||||
#default_room_version = "12"
|
||||
|
||||
# A default allow value for the Access Control List when creating a room.
|
||||
#
|
||||
# If a list is provided, new rooms will be created with
|
||||
# a m.room.server_acl event. Only servers which match one of the patterns
|
||||
# in the list will be permitted to participate in the room.
|
||||
#
|
||||
# ACLs in existing rooms will not be updated automatically. This is not
|
||||
# a substitute for moderation bots.
|
||||
#
|
||||
#default_room_acl_allow =
|
||||
|
||||
# A default deny value for the Access Control List when creating a room.
|
||||
#
|
||||
# If a list is provided, new rooms will be created with
|
||||
# a m.room.server_acl event. Servers which match one of the patterns
|
||||
# in the list will be NOT permitted to participate in the room.
|
||||
#
|
||||
# This config cannot be used if the default_room_acl_allow config is used.
|
||||
#
|
||||
# ACLs in existing rooms will not be updated automatically. This is not
|
||||
# a substitute for moderation bots.
|
||||
#
|
||||
#default_room_acl_deny =
|
||||
|
||||
# The number of forward extremities to tolerate in a room before
|
||||
# attempting to manually squash them with a "dummy event". Setting this
|
||||
# above 20 will hinder its efficacy, and setting it below 5 will cause
|
||||
# more dummy events to be sent than necessary (which increases federation
|
||||
# traffic).
|
||||
#
|
||||
#dummy_event_threshold = 10
|
||||
|
||||
# Enable OpenTelemetry OTLP tracing export. This replaces the deprecated
|
||||
# Jaeger exporter. Traces will be sent via OTLP to a collector (such as
|
||||
# Jaeger) that supports the OpenTelemetry Protocol.
|
||||
@@ -1282,21 +1298,6 @@
|
||||
#
|
||||
#brotli_compression = false
|
||||
|
||||
# Set to true to allow user type "guest" registrations. Some clients like
|
||||
# Element attempt to register guest users automatically.
|
||||
#
|
||||
#allow_guest_registration = false
|
||||
|
||||
# Set to true to log guest registrations in the admin room. Note that
|
||||
# these may be noisy or unnecessary if you're a public homeserver.
|
||||
#
|
||||
#log_guest_registrations = false
|
||||
|
||||
# Set to true to allow guest registrations/users to auto join any rooms
|
||||
# specified in `auto_join_rooms`.
|
||||
#
|
||||
#allow_guests_auto_join_rooms = false
|
||||
|
||||
# Enable the legacy unauthenticated Matrix media repository endpoints.
|
||||
# These endpoints consist of:
|
||||
# - /_matrix/media/*/config
|
||||
@@ -1433,6 +1434,11 @@
|
||||
#
|
||||
#send_messages_from_ignored_users_to_client = false
|
||||
|
||||
# Send "org.matrix.dummy_event" events to the client. This is a debugging
|
||||
# option.
|
||||
#
|
||||
#send_dummy_events_to_clients = false
|
||||
|
||||
# Vector list of IPv4 and IPv6 CIDR ranges / subnets *in quotes* that you
|
||||
# do not want continuwuity to send outbound requests to. Defaults to
|
||||
# RFC1918, unroutable, loopback, multicast, and testnet addresses for
|
||||
@@ -1596,19 +1602,6 @@
|
||||
#
|
||||
#block_non_admin_invites = false
|
||||
|
||||
# Enable or disable making requests to MSC4284 Policy Servers.
|
||||
# It is recommended you keep this enabled unless you experience frequent
|
||||
# connectivity issues, such as in a restricted networking environment.
|
||||
#
|
||||
#enable_msc4284_policy_servers = true
|
||||
|
||||
# Enable running locally generated events through configured MSC4284
|
||||
# policy servers. You may wish to disable this if your server is
|
||||
# single-user for a slight speed benefit in some rooms, but otherwise
|
||||
# should leave it enabled.
|
||||
#
|
||||
#policy_server_check_own_events = true
|
||||
|
||||
# Allow admins to enter commands in rooms other than "#admins" (admin
|
||||
# room) by prefixing your message with "\!admin" or "\\!admin" followed up
|
||||
# a normal continuwuity admin command. The reply will be publicly visible
|
||||
@@ -1875,6 +1868,11 @@
|
||||
#
|
||||
#support_page =
|
||||
|
||||
# The ed25519 public key for the policy server available at this server's
|
||||
# name. Must be unpadded base64.
|
||||
#
|
||||
#policy_server_public_key =
|
||||
|
||||
# Role string for server support contacts, to be served as part of the
|
||||
# MSC1929 server support endpoint at /.well-known/matrix/support.
|
||||
#
|
||||
@@ -1900,34 +1898,6 @@
|
||||
#
|
||||
#support_pgp_key =
|
||||
|
||||
# **DEPRECATED**: Use `[global.matrix_rtc].foci` instead.
|
||||
#
|
||||
# A list of MatrixRTC foci URLs which will be served as part of the
|
||||
# MSC4143 client endpoint at /.well-known/matrix/client.
|
||||
#
|
||||
# This option is deprecated and will be removed in a future release.
|
||||
# Please migrate to the new `[global.matrix_rtc]` config section.
|
||||
#
|
||||
#rtc_focus_server_urls = []
|
||||
|
||||
[global.blurhashing]
|
||||
|
||||
# blurhashing x component, 4 is recommended by https://blurha.sh/
|
||||
#
|
||||
#components_x = 4
|
||||
|
||||
# blurhashing y component, 3 is recommended by https://blurha.sh/
|
||||
#
|
||||
#components_y = 3
|
||||
|
||||
# Max raw size that the server will blurhash, this is the size of the
|
||||
# image after converting it to raw data, it should be higher than the
|
||||
# upload limit but not too high. The higher it is the higher the
|
||||
# potential load will be for clients requesting blurhashes. The default
|
||||
# is 33.55MB. Setting it to 0 disables blurhashing.
|
||||
#
|
||||
#blurhash_max_raw_size = 33554432
|
||||
|
||||
[global.matrix_rtc]
|
||||
|
||||
# A list of MatrixRTC foci (transports) which will be served via the
|
||||
@@ -1945,102 +1915,6 @@
|
||||
#
|
||||
#foci = []
|
||||
|
||||
[global.ldap]
|
||||
|
||||
# Whether to enable LDAP login.
|
||||
#
|
||||
# example: "true"
|
||||
#
|
||||
#enable = false
|
||||
|
||||
# Whether to force LDAP authentication or authorize classical password
|
||||
# login.
|
||||
#
|
||||
# example: "true"
|
||||
#
|
||||
#ldap_only = false
|
||||
|
||||
# URI of the LDAP server.
|
||||
#
|
||||
# example: "ldap://ldap.example.com:389"
|
||||
#
|
||||
#uri = ""
|
||||
|
||||
# StartTLS for LDAP connections.
|
||||
#
|
||||
#use_starttls = false
|
||||
|
||||
# Skip TLS certificate verification, possibly dangerous.
|
||||
#
|
||||
#disable_tls_verification = false
|
||||
|
||||
# Root of the searches.
|
||||
#
|
||||
# example: "ou=users,dc=example,dc=org"
|
||||
#
|
||||
#base_dn = ""
|
||||
|
||||
# Bind DN if anonymous search is not enabled.
|
||||
#
|
||||
# You can use the variable `{username}` that will be replaced by the
|
||||
# entered username. In such case, the password used to bind will be the
|
||||
# one provided for the login and not the one given by
|
||||
# `bind_password_file`. Beware: automatically granting admin rights will
|
||||
# not work if you use this direct bind instead of a LDAP search.
|
||||
#
|
||||
# example: "cn=ldap-reader,dc=example,dc=org" or
|
||||
# "cn={username},ou=users,dc=example,dc=org"
|
||||
#
|
||||
#bind_dn = ""
|
||||
|
||||
# Path to a file on the system that contains the password for the
|
||||
# `bind_dn`.
|
||||
#
|
||||
# The server must be able to access the file, and it must not be empty.
|
||||
#
|
||||
#bind_password_file = ""
|
||||
|
||||
# Search filter to limit user searches.
|
||||
#
|
||||
# You can use the variable `{username}` that will be replaced by the
|
||||
# entered username for more complex filters.
|
||||
#
|
||||
# example: "(&(objectClass=person)(memberOf=matrix))"
|
||||
#
|
||||
#filter = "(objectClass=*)"
|
||||
|
||||
# Attribute to use to uniquely identify the user.
|
||||
#
|
||||
# example: "uid" or "cn"
|
||||
#
|
||||
#uid_attribute = "uid"
|
||||
|
||||
# Attribute containing the display name of the user.
|
||||
#
|
||||
# example: "givenName" or "sn"
|
||||
#
|
||||
#name_attribute = "givenName"
|
||||
|
||||
# Root of the searches for admin users.
|
||||
#
|
||||
# Defaults to `base_dn` if empty.
|
||||
#
|
||||
# example: "ou=admins,dc=example,dc=org"
|
||||
#
|
||||
#admin_base_dn = ""
|
||||
|
||||
# The LDAP search filter to find administrative users for continuwuity.
|
||||
#
|
||||
# If left blank, administrative state must be configured manually for each
|
||||
# user.
|
||||
#
|
||||
# You can use the variable `{username}` that will be replaced by the
|
||||
# entered username for more complex filters.
|
||||
#
|
||||
# example: "(objectClass=conduwuitAdmin)" or "(uid={username})"
|
||||
#
|
||||
#admin_filter = ""
|
||||
|
||||
#[global.antispam]
|
||||
|
||||
#[global.antispam.meowlnir]
|
||||
@@ -2109,8 +1983,10 @@
|
||||
#
|
||||
#sender =
|
||||
|
||||
# Whether to require that users provide an email address when they
|
||||
# register.
|
||||
# Whether to allow public registration with an email address.
|
||||
#
|
||||
# Note that, if this option is enabled, anyone will be able to register an
|
||||
# account with just an email address.
|
||||
#
|
||||
# If either this option or `require_email_for_token_registration` are set,
|
||||
# users will not be allowed to remove their email address.
|
||||
@@ -2118,6 +1994,123 @@
|
||||
#require_email_for_registration = false
|
||||
|
||||
# Whether to require that users who register with a registration token
|
||||
# provide an email address.
|
||||
# provide an email address. This option is independent of
|
||||
# `require_email_for_registration`.
|
||||
#
|
||||
#require_email_for_token_registration = false
|
||||
|
||||
#[global.registration_terms]
|
||||
|
||||
# The language code to provide to clients along with the policy documents.
|
||||
#
|
||||
#language = "en"
|
||||
|
||||
# Policy documents, such as terms and conditions or a privacy policy,
|
||||
# which users must agree to when registering an account.
|
||||
#
|
||||
# Example:
|
||||
# ```ignore
|
||||
# [global.registration_terms.documents]
|
||||
# privacy_policy = { name = "Privacy Policy", url = "https://homeserver.example/en/privacy_policy.html" }
|
||||
# ```
|
||||
#
|
||||
#documents =
|
||||
|
||||
#[global.oauth]
|
||||
|
||||
# The compatibility mode to use for OAuth.
|
||||
#
|
||||
# - "disabled": OAuth will be unavailable. Users will only be able to log
|
||||
# in using legacy authentication.
|
||||
# - "hybrid": OAuth and legacy authentication will both be available. Some
|
||||
# clients may only use one or the other.
|
||||
# - "exclusive": Only OAuth will be available. Clients which require
|
||||
# legacy authentication will be unable to log in.
|
||||
#
|
||||
#compatibility_mode = "hybrid"
|
||||
|
||||
#[global.oauth.oidc]
|
||||
# Uncommenting this section will enable Continuwuity's support for
|
||||
# authenticating users using an OpenID Connect-compatible identity provider.
|
||||
# This is referred to as "delegated authentication".
|
||||
#
|
||||
# IMPORTANT NOTE: When delegated authentication is active, Continuwuity will behave as if
|
||||
# the `global.oauth.compatibility_mode` setting is set to `exclusive`.
|
||||
# Matrix clients which do not support OAuth login (also referred to as "next-gen auth") will NOT be able
|
||||
# to log in while delegated authentication is active.
|
||||
|
||||
|
||||
# The OIDC issuer URL. Continuwuity will use OpenID Connect Discovery to
|
||||
# automatically fetch the identity provider's metadata from this URL.
|
||||
# Generally you should set this to the base domain your identity provider
|
||||
# runs on.
|
||||
#
|
||||
#discovery_url =
|
||||
|
||||
# The OAuth client ID for Continuwuity to use when communicating with the
|
||||
# identity provider.
|
||||
#
|
||||
#client_id =
|
||||
|
||||
# The OAuth client secret for Continuwuity to use when communicating with
|
||||
# the identity provider.
|
||||
#
|
||||
#client_secret =
|
||||
|
||||
# Additional scopes Continuwuity should request from the IDP. This may be
|
||||
# necessary to access certain claims. Continuwuity always requests the
|
||||
# `openid` scope.
|
||||
#
|
||||
#additional_scopes = []
|
||||
|
||||
# Whether the user should be prompted to choose a localpart
|
||||
# when signing in for the first time. If this is `false`, Continuwuity
|
||||
# will attempt to use the value of the `preferred_username_claim`
|
||||
# (see below) as the user's localpart. Authentication will
|
||||
# fail if this claim is missing or is not a valid localpart.
|
||||
#
|
||||
#prompt_for_localpart = true
|
||||
|
||||
# The claim to use for the user's localpart, if `prompt_for_localpart` is
|
||||
# false.
|
||||
#
|
||||
#preferred_username_claim = "preferred_username"
|
||||
|
||||
# The claim which will be used to set the user's email address,
|
||||
# either on initial registration or on every login depending on
|
||||
# the value of `profile_key_import_mode`. Continuwuity assumes that
|
||||
# the IDP has taken care of verifying that the user controls the email
|
||||
# address it provides.
|
||||
#
|
||||
# This option does nothing if SMTP is not configured.
|
||||
#
|
||||
# If this option is set, and `profile_key_import_mode` is `on_login`,
|
||||
# users will not be able to change their email addresses themselves.
|
||||
#
|
||||
#email_claim = "email"
|
||||
|
||||
# Defines how claims returned from the IDP should be mapped to a user's
|
||||
# profile data. The profile field named in each key will be set from the
|
||||
# claim named in the corresponding value when the user first registers,
|
||||
# and possibly on subsequent logins as well, depending on the value of
|
||||
# `profile_key_import_mode` (see below).
|
||||
#
|
||||
# Per-room overrides to the user's display name or avatar will be
|
||||
# preserved by the import process.
|
||||
#
|
||||
# SECURITY NOTE: If the `avatar_url` field is set, Continuwuity will
|
||||
# perform a HTTP GET to the URL in the mapped claim and use the returned
|
||||
# file as the user's profile picture. Make sure your users are not able
|
||||
# to set the value of the mapped claim to an arbitrary URL.
|
||||
#
|
||||
#profile_key_map = { displayname = "name" }
|
||||
|
||||
# When profile keys should be imported from the IDP's claims.
|
||||
#
|
||||
# - "on_registration": Listed keys will be imported once, when the user
|
||||
# logs in for the first time and their shadow account is created.
|
||||
# - "on_login": Listed keys will be imported every time the user logs in.
|
||||
# Additionally, users will not be able to manually edit any listed keys
|
||||
# through their Matrix client.
|
||||
#
|
||||
#profile_key_import_mode = "on_registration"
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
ARG RUST_VERSION=1
|
||||
ARG DEBIAN_VERSION=bookworm
|
||||
ARG DEBIAN_VERSION=trixie
|
||||
|
||||
FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx
|
||||
FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-slim-${DEBIAN_VERSION} AS base
|
||||
@@ -10,7 +10,7 @@ RUN rm -f /etc/apt/apt.conf.d/docker-clean
|
||||
|
||||
# Match Rustc version as close as possible
|
||||
# rustc -vV
|
||||
ARG LLVM_VERSION=21
|
||||
ARG LLVM_VERSION=22
|
||||
# ENV RUSTUP_TOOLCHAIN=${RUST_VERSION}
|
||||
|
||||
# Install repo tools
|
||||
@@ -22,7 +22,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
apt-get update && apt-get install -y \
|
||||
pkg-config make jq \
|
||||
wget curl git software-properties-common \
|
||||
wget curl git lsb-release gpg \
|
||||
file
|
||||
# golang cmake
|
||||
|
||||
@@ -50,7 +50,7 @@ EOF
|
||||
|
||||
# Developer tool versions
|
||||
# renovate: datasource=github-releases depName=cargo-bins/cargo-binstall
|
||||
ENV BINSTALL_VERSION=1.18.1
|
||||
ENV BINSTALL_VERSION=1.20.1
|
||||
# renovate: datasource=github-releases depName=psastras/sbom-rs
|
||||
ENV CARGO_SBOM_VERSION=0.9.1
|
||||
# renovate: datasource=crate depName=lddtree
|
||||
|
||||
@@ -18,7 +18,7 @@ RUN --mount=type=cache,target=/etc/apk/cache apk add \
|
||||
|
||||
# Developer tool versions
|
||||
# renovate: datasource=github-releases depName=cargo-bins/cargo-binstall
|
||||
ENV BINSTALL_VERSION=1.18.1
|
||||
ENV BINSTALL_VERSION=1.20.1
|
||||
# renovate: datasource=github-releases depName=psastras/sbom-rs
|
||||
ENV CARGO_SBOM_VERSION=0.9.1
|
||||
# renovate: datasource=crate depName=lddtree
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
"type": "file",
|
||||
"name": "dns",
|
||||
"label": "DNS tuning (recommended)"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"name": "performance",
|
||||
"label": "Performance tuning"
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
@@ -156,9 +156,11 @@ ### Serving well-known files manually
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Check with the [Matrix Connectivity Tester][federation-tester] to see that it's working.
|
||||
Check that other servers can connect to you.
|
||||
Here are some tools that can help identify federation issues:
|
||||
|
||||
[federation-tester]: https://federationtester.mtrnord.blog/
|
||||
- [Matrix Connectivity Tester](https://federationtester.mtrnord.blog/)
|
||||
- [Matrix Federation Tester](https://federationtester.matrix.org/)
|
||||
|
||||
### Cannot log in with web clients
|
||||
|
||||
|
||||
+13
-9
@@ -74,13 +74,11 @@ ## Unbound
|
||||
|
||||
- Increase `discard-timeout` to something like `4800` to wait longer for upstream resolvers, as recursion can take a long time to respond to some domains. Continuwuity default to `dns_timeout = 10` seconds, so dropping requests early would lead to unnecessary retries and/or failures.
|
||||
|
||||
### Using a forwarder (optional)
|
||||
### Recursion versus forwarding
|
||||
|
||||
Unbound by default employs **recursive resolution** and contacts many servers around the world. If this is not performant enough, consider forwarding your queries to public resolvers to benefit from their CDNs and get faster responses.
|
||||
Unbound by default employs **recursive resolution** and contacts many servers around the world. While this allows updated and authoritative answers and are generally viable for most users, sometimes these recursive queries can be too slow to fully resolve. As an alternative, you can consider **forwarding** your queries to public resolvers, and benefit from faster responses from their CDNs.
|
||||
|
||||
However, most popular upstreams (such as Google DNS or Quad9) employ IP ratelimiting, so a generous cache is still needed to avoid making too many queries.
|
||||
|
||||
DNS-over-TLS forwarders may also be used should you need on-the-wire encryption, but TLS overhead causes some speed penalties.
|
||||
Do note that most popular upstreams (such as Google DNS or Quad9) employ IP ratelimiting, so a generous cache is still needed to avoid making too many queries.
|
||||
|
||||
If you want to use forwarders, configure it as follows:
|
||||
|
||||
@@ -99,6 +97,8 @@ # Use cloudflare public resolvers as an example
|
||||
# forward-addr: 2606:4700:4700::1111@53
|
||||
|
||||
# alternatively, use DNS-over-TLS for forwarders.
|
||||
# this will encrypt traffic between you and the forwarder,
|
||||
# but takes more time due to TLS overhead.
|
||||
# forward-zone:
|
||||
# name: "."
|
||||
# forward-tls-upstream: yes
|
||||
@@ -133,9 +133,11 @@ ### dnsmasq
|
||||
|
||||
[arch-linux-dnsmasq]: https://wiki.archlinux.org/title/Dnsmasq
|
||||
|
||||
### Technitium
|
||||
### Technitium DNS
|
||||
|
||||
[Technitium][technitium] supports recursion as well as a myriad of forwarding protocols, allows saving cache to disk natively, and does work well with Continuwuity. Its default configurations however ratelimits single-IP requests by a lot, and hence must be changed. You may consult this [community guide][technitium-continuwuity] for more details on setting up a dedicated Technitium for Continuwuity.
|
||||
[Technitium DNS Server][technitium] supports recursion as well as a myriad of forwarding protocols, allows saving cache to disk natively, and does work well with Continuwuity. Its out-of-the-box configs however ratelimits single-IP requests by a lot, and hence must be changed.
|
||||
|
||||
You may consult this [community guide][technitium-continuwuity] for more details on setting up and fine-tuning a dedicated Technitium instance for Continuwuity.
|
||||
|
||||
[technitium]: https://github.com/TechnitiumSoftware/DnsServer
|
||||
[technitium-continuwuity]: https://muoi.me/~stratself/articles/technitium-continuwuity/
|
||||
@@ -150,11 +152,13 @@ ## Testing
|
||||
|
||||
## Further steps
|
||||
|
||||
- (Recommended) Set **`dns_cache_entries = 0`** inside Continuwuity and fully rely on the more performant external resolver.
|
||||
It is recommended to set **`dns_cache_entries = 0`** inside Continuwuity to fully rely on the external resolver. While Continuwuity does have an internal cache, it can run into reliability issues if you're federating with many domains.
|
||||
|
||||
Additionally, you can also make the following improvements:
|
||||
|
||||
- Consider employing **persistent cache to disk**, so your resolver can still run without hassle after a restart. Unbound, via [Cache DB module][unbound-cachedb], can use Redis as a storage backend for this feature.
|
||||
|
||||
- Consider [enabling **Serve Stale**][unbound-serve-stale] functionality to serve expired data beyond DNS TTLs. Since most Matrix homeservers have static IPs, this should help improve federation with them especially when upstream resolvers have timed out. For dnsproxy, this corresponds to its [optimistic caching options][dnsproxy-usage].
|
||||
- Consider [enabling **Serve Stale**][unbound-serve-stale] functionality to serve expired data beyond DNS TTLs. Since most Matrix homeservers have static IPs, this should still allow federating with them when upstream resolvers have timed out. For dnsproxy, this corresponds to its [optimistic caching options][dnsproxy-usage].
|
||||
|
||||
- If you still experience DNS performance issues, another step could be to **disable DNSSEC** (which is computationally expensive) at a cost of slightly decreased security. On Unbound this is done by commenting out `trust-anchors` config options and removing the `validator` module.
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
# Performance tuning
|
||||
|
||||
Continuwuity's default configs are suited for many typical setups and scales appropriately with the size of your hardware. However, there are many scenarios where additional modifications can be made to better utilize your server resources.
|
||||
|
||||
This page aims to outline various performance tweaks for Continuwuity and their effects. These adjustments are especially helpful for homeservers that join many large federated rooms or have many users, and it will become increasingly necessary as the Matrix network expands. As always, your mileage may vary according to your setup's specifics. If you have further discussions or recommendations, please share them in the community rooms.
|
||||
|
||||
## DNS tuning (recommended)
|
||||
|
||||
Please see the dedicated [DNS tuning guide](./dns.mdx).
|
||||
|
||||
## Cache capacities
|
||||
|
||||
If you have memory to spare, consider increasing the `cache_capacity_modifier` value to a larger number to allow more data to be stored in hot memory. This *significantly* speeds up many intensive operations (such as state resolutions) and decreases CPU usage and disk I/O. Start with a baseline of `cache_capacity_modifier = 2.0` and tune up until you are satisfied with RAM usage.
|
||||
|
||||
On the other hand, if your system doesn't have a lot of RAM, consider decreasing the cache capacity modifier to something smaller than `1.0` to avoid low-memory issues (at the cost of higher load on disk/CPU). This recommendation also works if your system has abnormally little RAM compared to the number of CPU cores (for example, 2GB RAM for 12 cores), as cache capacities scale according to number of available cores.
|
||||
|
||||
## Disabling some features
|
||||
|
||||
You can disable outgoing **typing notifications** and **read markers** to reduce strain on the CPU and network when actively participating in rooms.
|
||||
|
||||
```toml
|
||||
# disables sending read receipts
|
||||
allow_outgoing_read_receipts = false
|
||||
# disables sending typing notifications
|
||||
allow_outgoing_typing = false
|
||||
```
|
||||
|
||||
Outgoing presence updates are also considered very expensive and have been disabled by default (`allow_outgoing_presence = false`). For more savings, you may wish to disable _all_ processing of presence entirely.
|
||||
|
||||
```toml title=continuwuity.toml
|
||||
# disabling presence updates entirely
|
||||
allow_local_presence = false
|
||||
allow_incoming_presence = false
|
||||
allow_outgoing_presence = false
|
||||
```
|
||||
|
||||
## Tuning database compression
|
||||
|
||||
:::warning
|
||||
These steps SHOULD be done **before** starting Continuwuity for the first time. While switching database compression midway through is theoretically possible, this has not been tested extensively in the wild.
|
||||
:::
|
||||
|
||||
### Changing the compression algorithm
|
||||
|
||||
For reduced CPU usage at a tradeoff of increased storage space, consider deploying Continuwuity with the faster and less intensive `lz4` algorithm instead of `zstd` for rocksdb, and disable WAL compression entirely:
|
||||
|
||||
```toml
|
||||
### in continuwuity.toml ###
|
||||
rocksdb_compression_algo = "lz4"
|
||||
rocksdb_wal_compression = "none"
|
||||
```
|
||||
|
||||
This tweak can especially be helpful if you have an older or less performant CPU (e.g. a Raspberry Pi) and disk space to spare.
|
||||
|
||||
### Increasing bottommost layer compression (`zstd` only)
|
||||
|
||||
The bottommost layer of the database usually contains old and read-only data, so it is a suitable place for further compression. In Continuwuity, this is possible by setting `rocksdb_bottommost_compression = true` and tuning `rocksdb_bottommost_compression_level` to a more compact level than the default one used in `rocksdb_compression_level`. This tweak comes at a cost of increased CPU usage, but may prevent your database from growing too large in the long run.
|
||||
|
||||
For those using `zstd` compression, the compression level ranges from 1 to 22. An example like this could apply:
|
||||
|
||||
```toml
|
||||
### in continuwuity.toml ###
|
||||
rocksdb_compression_algo = "zstd"
|
||||
rocksdb_compression_level = 32767 # magic number, translates to level 3 on zstd
|
||||
rocksdb_bottommost_compression = true
|
||||
rocksdb_bottommost_compression_level = 9 # level 9 on zstd
|
||||
```
|
||||
|
||||
For `lz4` users, the default level (`-1`) is already the most compact. You can only further decrease it to favor compression speed over ratio.
|
||||
|
||||
Consult these documents for more information on compression tuning and levels:
|
||||
|
||||
- [Rocksdb compression documentation][rocksdb-compression]
|
||||
- [Rocksdb default compression levels][rocksdb-compression-defaults]
|
||||
- [Zstd manual][zstd-manual]
|
||||
- [Lz4 manual][lz4-manual]
|
||||
|
||||
[rocksdb-compression]: https://github.com/facebook/rocksdb/wiki/Compression
|
||||
[rocksdb-compression-defaults]: https://github.com/facebook/rocksdb/blob/main/include/rocksdb/options.h#L208-L217
|
||||
[zstd-manual]: https://facebook.github.io/zstd/zstd_manual.html
|
||||
[lz4-manual]: https://github.com/lz4/lz4/blob/release/doc/lz4_manual.html
|
||||
|
||||
## Other tweaks
|
||||
|
||||
### Using UNIX sockets
|
||||
|
||||
If your homeserver and reverse proxy live on the same machine, you may wish to expose Continuwuity on a UNIX socket instead of a port. This removes TCP overhead between the two programs.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Example config with Caddy</summary>
|
||||
|
||||
```toml
|
||||
### in continuwuity.toml ###
|
||||
|
||||
# `address` and `port` has to be commented out first
|
||||
#address = ["127.0.0.1", "::1"]
|
||||
#port = 8008
|
||||
unix_socket_path = "/run/continuwuity/continuwuity.sock"
|
||||
```
|
||||
|
||||
```
|
||||
### in your Caddyfile ###
|
||||
https://matrix.example.com {
|
||||
reverse_proxy unix//run/continuwuity/continuwuity.sock
|
||||
|
||||
# alternatively, use the http2-plaintext protocol
|
||||
# reverse_proxy unix+h2c//run/continuwuity/continuwuity.sock
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Tuning your trusted servers
|
||||
|
||||
:::info Vet your trusted servers!
|
||||
Trusted servers are your first point of contact when obtaining public keys from other servers, and they could theoretically impersonate other servers and cause significant harm to your deployment. Please thoroughly verify your trusted servers' credibility before adding them to your configuration.
|
||||
:::
|
||||
|
||||
Trusted servers are queried sequentially in the order they are listed. If you have multiple trusted servers configured, put the faster ones first:
|
||||
|
||||
```toml
|
||||
# Example config, using maintainers' recommended homeservers
|
||||
trusted_servers = ["codestorm.net","starstruck.systems","unredacted.org","matrix.org"]
|
||||
```
|
||||
|
||||
Avoid prioritising `matrix.org` as your primary trusted server, as it tends to be quite slow.
|
||||
|
||||
Some users have also reported that increasing `trusted_server_batch_size` has helped with faster joins for huge rooms. Start with doubling the default to `2048` until you find a suitable value.
|
||||
|
||||
### Enable HTTP/3 on your reverse proxy
|
||||
|
||||
Consider enabling the newer **HTTP/3** protocol for inbound connections to Continuwuity. In Caddy HTTP/3 is allowed by default, but you must expose port :443/**udp** on your firewall.
|
||||
|
||||
HTTP/3 can vastly improve Client-Server connections especially on unstable networks, as it reduces packet losses and latency from TCP head-of-line blocking, includes workarounds for network switching, and reduces connection establishment handshakes. Continuwuity also includes experimental _outbound_ HTTP/3 support in its Docker images, so connections between Continuwuity servers can benefit from this too.
|
||||
+88
-15
@@ -25,9 +25,9 @@ ### 2. Services
|
||||
:::tip Generating the secrets
|
||||
LiveKit provides a utility to generate secure random keys
|
||||
```bash
|
||||
~$ docker run --rm livekit/livekit-server:latest generate-keys
|
||||
API Key: APIUxUnMnSkuFWV
|
||||
API Secret: t93ZVjPeoEdyx7Wbet3kG4L3NGZIZVEFvqe0UuiVc22A
|
||||
docker run --rm livekit/livekit-server:latest generate-keys
|
||||
# API Key: APIUxUnMnSkuFWV
|
||||
# API Secret: t93ZVjPeoEdyx7Wbet3kG4L3NGZIZVEFvqe0UuiVc22A
|
||||
```
|
||||
:::
|
||||
|
||||
@@ -187,6 +187,75 @@ ### 4. Configure your Reverse Proxy
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>Example docker compose file with caddy-docker-proxy labels</summary>
|
||||
```yaml
|
||||
# This setup assumes all containers share the same bridge network
|
||||
services:
|
||||
lk-jwt-service:
|
||||
image: ghcr.io/element-hq/lk-jwt-service:latest
|
||||
container_name: lk-jwt-service
|
||||
# lk-jwt-service environment config here..
|
||||
labels:
|
||||
caddy: livekit.example.com
|
||||
caddy.@lk-jwt-service.path: "/sfu/get* /healthz* /get_token*"
|
||||
caddy.reverse_proxy: "@lk-jwt-service {{upstreams 8081}}"
|
||||
|
||||
|
||||
livekit:
|
||||
image: livekit/livekit-server:latest
|
||||
container_name: livekit
|
||||
command: --config /etc/livekit.yaml
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
caddy: livekit.example.com
|
||||
caddy.reverse_proxy: "{{upstreams 7880}}"
|
||||
volumes:
|
||||
- ./livekit.yaml:/etc/livekit.yaml:ro
|
||||
ports:
|
||||
- "127.0.0.1:7880:7880/tcp"
|
||||
- "7881:7881/tcp"
|
||||
- "50100-50200:50100-50200/udp"
|
||||
|
||||
|
||||
caddy:
|
||||
image: lucaslorentz/caddy-docker-proxy:ci-alpine
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
environment:
|
||||
- CADDY_INGRESS_NETWORKS=caddy
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./data:/data
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
# If you already configured `[global.well_known]` with Continuwuity,
|
||||
# comment out the *_respond labels and add this line
|
||||
# caddy.reverse_proxy: /.well-known/matrix/* homeserver:8008
|
||||
caddy.1_respond: /.well-known/matrix/server {"m.server":"matrix.example.com:443"}
|
||||
caddy.2_respond: /.well-known/matrix/client {"m.server":{"base_url":"https://matrix.example.com"},"m.homeserver":{"base_url":"https://matrix.example.com"},"org.matrix.msc4143.rtc_foci":[{"type":"livekit","livekit_service_url":"https://livekit.example.com"}]}
|
||||
|
||||
# If you are having problems with continuwuity serving headers uncomment
|
||||
# the header section below.
|
||||
|
||||
# caddy: example.com
|
||||
# caddy.0_header: "*"
|
||||
# caddy.0_header.Access-Control-Allow-Origin: "*"
|
||||
# caddy.0_header.Access-Control-Allow-Methods: "GET, POST, OPTIONS"
|
||||
# caddy.0_header.Access-Control-Allow-Headers: "Authorization"
|
||||
# caddy.0_header.Content-Type: "application/json"
|
||||
|
||||
homeserver:
|
||||
image: forgejo.ellis.link/continuwuation/continuwuity:latest
|
||||
restart: unless-stopped
|
||||
# add additional environment, volume, and network config here...
|
||||
labels:
|
||||
caddy: matrix.example.com
|
||||
caddy.reverse_proxy: "{{upstreams 8008}}"
|
||||
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
### 6. Start Everything
|
||||
@@ -262,14 +331,14 @@ # livekit.yaml
|
||||
|
||||
## Testing
|
||||
|
||||
To test that LiveKit is successfully integrated with Continuwuity, you will need to replicate its [Token Exchange Flow](https://github.com/element-hq/lk-jwt-service#%EF%B8%8F-how-it-works--token-exchange-flow).
|
||||
To test that LiveKit is successfully integrated with Continuwuity, you will need to replicate its [Token Exchange Flow](https://github.com/element-hq/lk-jwt-service#%EF%B8%8F-how-it-works--token-exchange-flow). Follow the steps below while checking Docker logs (`docker-compose logs --follow`), in order to help [troubleshooting](#troubleshooting) any issues.
|
||||
|
||||
First, you will need an access token for your current login session. These can be found in your client's settings or obtained via [this website](https://timedout.uk/mxtoken.html).
|
||||
|
||||
Then, using that token, fetch the discovery endpoints for MatrixRTC services
|
||||
Then, using that token, fetch the discovery endpoints for MatrixRTC services:
|
||||
|
||||
```bash
|
||||
curl -X POST -H "Authorization: Bearer <session-access-token>" \
|
||||
curl -H "Authorization: Bearer <session-access-token>" \
|
||||
https://matrix.example.com/_matrix/client/unstable/org.matrix.msc4143/rtc/transports
|
||||
```
|
||||
|
||||
@@ -318,7 +387,7 @@ ## Testing
|
||||
You can then send this payload to the lk-jwt-service:
|
||||
|
||||
```bash
|
||||
~$ curl -X POST -d @payload.json https://livekit.example.com/get_token
|
||||
curl -X POST -d @payload.json https://livekit.example.com/get_token
|
||||
```
|
||||
|
||||
The lk-jwt-service will, after checking against Continuwuity, answer with a `jwt` token to create a LiveKit media room:
|
||||
@@ -331,22 +400,31 @@ ## Testing
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
To debug any issues, you can place a call or redo the Testing instructions, and check the container logs for any specific errors. Use `docker-compose logs --follow` to follow them in real-time.
|
||||
To debug any issues, you can place a call or redo the Testing instructions, and check the container logs for any specific errors. Use `docker-compose logs --follow` to follow these logs in real-time.
|
||||
|
||||
### Common errors in Element Call UI
|
||||
|
||||
- `MISSING_MATRIX_RTC_FOCUS`: LiveKit is missing from Continuwuity's config file
|
||||
- "Waiting for media" popup always showing: a LiveKit URL has been configured in Continuwuity, but your client cannot connect to it for some reason
|
||||
|
||||
For browser-based clients, you can also inspect connections using DevTools' Networking tab, to see which requests are erroring out.
|
||||
|
||||
### Docker loopback networking issues
|
||||
|
||||
Some distros do not allow Docker containers to connect to its host's public IP by default. This would cause `lk-jwt-service` to fail connecting to `livekit` or `continuwuity` on the same host. As a result, you would see connection refused/connection timeouts log entries in the JWT service, even when `LIVEKIT_URL` has been configured correctly.
|
||||
|
||||
You can also test that this is the case by cURLing from a sidecar container:
|
||||
|
||||
```bash
|
||||
docker run --rm --net container:lk-jwt-service docker.io/curlimages/curl https://livekit.example.com
|
||||
# --- some errors ---
|
||||
```
|
||||
|
||||
To alleviate this, you can try one of the following workarounds:
|
||||
|
||||
- Use `network_mode: host` for the `lk-jwt-service` container (instead of the default bridge networking).
|
||||
|
||||
- Add an `extra_hosts` file mapping livekit's (and continuwuity's) domain name to a localhost address:
|
||||
- Add an `extra_hosts` file mapping livekit's (and continuwuity's) domain name to a locally-reachable address:
|
||||
|
||||
```diff
|
||||
# in docker-compose.yaml
|
||||
@@ -360,12 +438,7 @@ ### Docker loopback networking issues
|
||||
|
||||
- (**untested, use at your own risk**) Implement an iptables workaround as shown [here](https://forums.docker.com/t/unable-to-connect-to-host-service-from-inside-docker-container/145749/6).
|
||||
|
||||
After implementing the changes and restarting your compose, you can test whether the connection works by cURLing from a sidecar container:
|
||||
|
||||
```bash
|
||||
~$ docker run --rm --net container:lk-jwt-service docker.io/curlimages/curl https://livekit.example.com
|
||||
OK
|
||||
```
|
||||
After implementing the changes and restarting your compose, `lk-jwt-service` should now connect to your other services. The sidecar container test above should now return an `OK` from LiveKit.
|
||||
|
||||
### Workaround for non-federating servers
|
||||
|
||||
|
||||
@@ -185,13 +185,15 @@ ## Testing
|
||||
|
||||
Test that your setup works by following these [instructions](./generic.mdx#how-do-i-know-it-works)
|
||||
|
||||
Check your container logs using `docker-compose logs --follow` to debug any issues. See the [Troubleshooting](../troubleshooting.mdx) page for common errors and how to fix them.
|
||||
|
||||
## Other deployment methods
|
||||
|
||||
### Docker - Quick Run
|
||||
|
||||
:::note For testing only
|
||||
The instructions below are only meant for a quick demo of Continuwuity.
|
||||
For production deployment, we recommend using [Docker Compose](#docker-compose)
|
||||
:::warning For testing only
|
||||
The instructions below are only meant for a quick demo of Continuwuity with **federation disabled**.
|
||||
For production deployment, we recommend using [Docker Compose](#docker-compose).
|
||||
:::
|
||||
|
||||
Get a working Continuwuity server with an admin user in four steps:
|
||||
@@ -211,7 +213,7 @@ ### Docker - Quick Run
|
||||
-e CONTINUWUITY_SERVER_NAME="example.com" \
|
||||
-e CONTINUWUITY_DATABASE_PATH="/var/lib/continuwuity" \
|
||||
-e CONTINUWUITY_ADDRESS="0.0.0.0" \
|
||||
-e CONTINUWUITY_ALLOW_REGISTRATION="false" \
|
||||
-e CONTINUWUITY_ALLOW_FEDERATION="false" \
|
||||
--name continuwuity \
|
||||
forgejo.ellis.link/continuwuation/continuwuity:latest \
|
||||
/sbin/conduwuit
|
||||
@@ -233,9 +235,9 @@ ### Docker - Quick Run
|
||||
Pick your own username and password!
|
||||
```
|
||||
|
||||
4. Configure your reverse proxy to forward HTTPS traffic to Continuwuity at port 8008. See [Docker Compose](#docker-compose) for examples.
|
||||
4. Configure your reverse proxy to forward HTTPS traffic to Continuwuity at port 8008. See [Docker Compose](#docker-compose) or the [Generic instructions](./generic.mdx#setting-up-the-reverse-proxy) for examples.
|
||||
|
||||
Once configured, log in to your server with any Matrix client, and register for an account with the registration token from step 3. You'll automatically be invited to the admin room where you can [manage your server](../reference/admin).
|
||||
Once configured, log in to your server with any Matrix client, and register for an account with the registration token from step 3. If you did not configure step 4., log in via the `http://<your_server_ip>:8008` address. You will be automatically invited to the admin room where you can [manage your server](../reference/admin).
|
||||
|
||||
### (Optional) Building Custom Images
|
||||
|
||||
@@ -269,4 +271,5 @@ ## Next steps
|
||||
|
||||
- For smooth federation, set up a caching resolver according to the [**DNS tuning guide**](../advanced/dns.mdx) (recommended)
|
||||
- To set up Audio/Video communication, see the [**Calls**](../calls.mdx) page.
|
||||
- Consult the [Maintenance](../maintenance.mdx) page for guidance on maintaining your homeserver.
|
||||
- If you want to set up an appservice, take a look at the [**Appservice Guide**](../appservices.mdx).
|
||||
|
||||
@@ -47,9 +47,15 @@ #### Performance-optimised builds
|
||||
|
||||
### Nix
|
||||
|
||||
Theres a Nix package defined in our flake, available for Linux and MacOS. Add continuwuity as an input to your flake, and use `inputs.continuwuity.packages.${system}.default` to get a working Continuwuity package.
|
||||
If you wish to generate a static binary, you can do so using Nix: `nix build git+https://forgejo.ellis.link/continuwuation/continuwuity#packageName`, where `packageName` is one of:
|
||||
|
||||
If you simply wish to generate a binary using Nix, you can run `nix build git+https://forgejo.ellis.link/continuwuation/continuwuity` to generate a binary in `result/bin/conduwuit`.
|
||||
- `default-static-x86_64`
|
||||
- `default-static-aarch64`
|
||||
- `max-perf-static-x86_64`
|
||||
- `max-perf-haswell-static-x86_64`
|
||||
- `max-perf-static-aarch64`
|
||||
|
||||
`max-perf` takes longer to build, but has more runtime optimizations. Haswell builds are optimized for modern CPUs.
|
||||
|
||||
### Compiling
|
||||
|
||||
@@ -260,7 +266,7 @@ ## Starting Your Server
|
||||
```
|
||||
|
||||
You can then open [a Matrix client][matrix-clients],
|
||||
enter your homeserver address, and try to register with the provided token.
|
||||
enter your homeserver address, and register with the provided token.
|
||||
By default, the first user is the instance's first admin. They will be added
|
||||
to the `#admin:example.com` room and be able to [issue admin commands](../reference/admin/index.md).
|
||||
|
||||
@@ -268,9 +274,13 @@ ## Starting Your Server
|
||||
|
||||
## How do I know it works?
|
||||
|
||||
To check if your server can communicate with other homeservers, use the
|
||||
[Matrix Federation Tester](https://federationtester.mtrnord.blog/). If you can
|
||||
register your account but cannot join federated rooms, check your configuration
|
||||
To check if your server can communicate with other homeservers,
|
||||
use an external testing tool:
|
||||
|
||||
- [Matrix Connectivity Tester](https://federationtester.mtrnord.blog/)
|
||||
- [Matrix Federation Tester](https://federationtester.matrix.org/)
|
||||
|
||||
If you can register your account but cannot join federated rooms, check your configuration
|
||||
and verify that your federation endpoints are opened and forwarded correctly.
|
||||
|
||||
As a quick health check, you can also use these cURL commands:
|
||||
@@ -292,4 +302,5 @@ ## What's next?
|
||||
|
||||
- For smooth federation, set up a caching resolver according to the [**DNS tuning guide**](../advanced/dns.mdx) (recommended)
|
||||
- For Audio/Video call functionality see the [**Calls**](../calls.md) page.
|
||||
- Consult the [Maintenance](../maintenance.mdx) page for guidance on maintaining your homeserver.
|
||||
- If you want to set up an appservice, take a look at the [**Appservice Guide**](../appservices.md).
|
||||
|
||||
@@ -47,9 +47,16 @@ ### Available options
|
||||
- `extraEnvironment`: Extra environment variables to pass to the Continuwuity server
|
||||
- `package`: The Continuwuity package to use, defaults to `pkgs.matrix-continuwuity`
|
||||
- You may want to override this to be from our flake, for faster updates and unstable versions:
|
||||
|
||||
```nix
|
||||
package = inputs.continuwuity.packages.${pkgs.stdenv.hostPlatform.system}.default;
|
||||
package = inputs.continuwuity.packages.${pkgs.stdenv.hostPlatform.system}.packageName;
|
||||
```
|
||||
|
||||
Where `packageName` is one of:
|
||||
- `default`
|
||||
- `max-perf`: Takes longer to build, but has more runtime optimizations
|
||||
- `max-perf-haswell`: Optimized for modern CPUs, don't use if your CPU is not Haswell or later.
|
||||
|
||||
- `admin.enable`: Whether to add the `conduwuit` binary to `PATH` for administration (enabled by default)
|
||||
- `settings`: The Continuwuity configuration
|
||||
|
||||
|
||||
@@ -81,8 +81,6 @@ ## List of forked dependencies
|
||||
All forked dependencies are maintained under the
|
||||
[continuwuation organization on Forgejo](https://forgejo.ellis.link/continuwuation):
|
||||
|
||||
- [ruwuma][continuwuation-ruwuma] - Fork of [ruma/ruma][ruma] with various
|
||||
performance improvements, more features and better client/server interop
|
||||
- [rocksdb][continuwuation-rocksdb] - Fork of [facebook/rocksdb][rocksdb] via
|
||||
[`@zaidoon1`][8] with liburing build fixes and GCC debug build fixes
|
||||
- [jemallocator][continuwuation-jemallocator] - Fork of
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
"message": "Welcome to Continuwuity! Important announcements about the project will appear here."
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"mention_room": false,
|
||||
"date": "2026-04-17",
|
||||
"message": "[v0.5.7](https://forgejo.ellis.link/continuwuation/continuwuity/releases/tag/v0.5.7) is out! Email verification! Terms and Conditions! Deleting notification pushers! So much good stuff. Go grab the release and read the changelog!"
|
||||
"id": 14,
|
||||
"mention_room": true,
|
||||
"date": "2026-06-20",
|
||||
"message": "[v0.5.10](https://forgejo.ellis.link/continuwuation/continuwuity/releases/tag/v0.5.10) has been released. It is a security release, so we suggest you update as soon as possible. Don't forget to also join [our announcements room](https://matrix.to/#/!jIdNjSM5X-V5JVx2h2kAhUZIIQ08GyzPL55NFZAH1vM/%24K1ISNKIqfNiZzsNVCaTt2E7ZtNeP6Dsy6sbz9l3rO0A?via=ellis.link&via=gingershaped.computer&via=matrix.org)."
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,7 +10,13 @@ ## `!admin debug echo`
|
||||
|
||||
## `!admin debug get-auth-chain`
|
||||
|
||||
Get the auth_chain of a PDU
|
||||
Loads the auth_chain of a PDU, reporting how long it took
|
||||
|
||||
## `!admin debug show-auth-chain`
|
||||
|
||||
Walks & displays the auth_chain of a PDU in a mermaid graph format.
|
||||
|
||||
This is useless to basically anyone but developers, and is also probably slow and memory hungry.
|
||||
|
||||
## `!admin debug parse-pdu`
|
||||
|
||||
@@ -44,6 +50,12 @@ ## `!admin debug get-room-state`
|
||||
|
||||
Of course the check is still done on the actual client API.
|
||||
|
||||
## `!admin debug get-state-at`
|
||||
|
||||
Gets all the room state events at the specified event.
|
||||
|
||||
State at event might not be available for some PDUs, such as rejected ones.
|
||||
|
||||
## `!admin debug get-signing-keys`
|
||||
|
||||
Get and display signing keys from local cache or remote server
|
||||
|
||||
@@ -7,13 +7,14 @@ ## Running commands
|
||||
|
||||
* All commands listed here may be used by server administrators in the admin room by sending them as messages.
|
||||
* If the `admin_escape_commands` configuration option is enabled, server administrators may run certain commands in public rooms by prefixing them with a single backslash. These commands will only run on _their_ homeserver, even if they are a member of another homeserver's admin room. Some sensitive commands cannot be used outside the admin room and will return an error.
|
||||
* All commands listed here may be used in the server's console, if it is enabled. Commands entered in the console do not require the `!admin` prefix. If Continuwuity is deployed via Docker, be sure to set the appropriate options detailed in [the Docker deployment guide](../../deploying/docker.mdx#accessing-the-servers-console) to enable access to the server's console.
|
||||
* All commands listed here may be used in the server's console, if it is enabled. Commands entered in the console do not require the `!admin` prefix.
|
||||
|
||||
## Categories
|
||||
|
||||
- [`!admin appservices`](appservices/): Commands for managing appservices
|
||||
- [`!admin users`](users/): Commands for managing local users
|
||||
- [`!admin token`](token/): Commands for managing registration tokens
|
||||
- [`!admin oidc`](oidc/): Commands for managing OIDC
|
||||
- [`!admin rooms`](rooms/): Commands for managing rooms
|
||||
- [`!admin federation`](federation/): Commands for managing federation
|
||||
- [`!admin server`](server/): Commands for managing the server
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<!-- This file is generated by `cargo xtask generate-docs`. Do not edit. -->
|
||||
# `!admin oidc`
|
||||
|
||||
Commands for managing OIDC
|
||||
|
||||
|
||||
## `!admin oidc link`
|
||||
|
||||
Link a user ID to the given subject claim
|
||||
|
||||
## `!admin oidc unlink`
|
||||
|
||||
Unlink the given subject claim from its associated user ID
|
||||
@@ -12,10 +12,6 @@ ## `!admin users reset-password`
|
||||
|
||||
Reset user password
|
||||
|
||||
## `!admin users issue-password-reset-link`
|
||||
|
||||
Issue a self-service password reset link for a user
|
||||
|
||||
## `!admin users get-email`
|
||||
|
||||
Get a user's associated email address
|
||||
@@ -96,6 +92,14 @@ ## `!admin users list-users`
|
||||
|
||||
List local users in the database
|
||||
|
||||
## `!admin users list-invited-rooms`
|
||||
|
||||
Lists all the rooms (local and remote) that the specified user is invited to
|
||||
|
||||
## `!admin users reject-all-invites`
|
||||
|
||||
Manually make a user reject all current invites
|
||||
|
||||
## `!admin users list-joined-rooms`
|
||||
|
||||
Lists all the rooms (local and remote) that the specified user is joined in
|
||||
|
||||
@@ -10,7 +10,7 @@ ## Continuwuity issues
|
||||
|
||||
### Slow joins to rooms
|
||||
|
||||
Some slowness is to be expected if you're the first person on your homserver to join a room (which will
|
||||
Some slowness is to be expected if you're the first person on your homeserver to join a room (which will
|
||||
always be the case for single-user homeservers). In this situation, your homeserver has to verify the signatures of
|
||||
all of the state events sent by other servers before your join. To make this process as fast as possible, make sure you have
|
||||
multiple fast, trusted servers listed in `trusted_servers` in your configuration, and ensure
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ cargo clippy \
|
||||
--locked \
|
||||
--profile test \
|
||||
--no-default-features \
|
||||
--features=console,systemd,element_hacks,direct_tls,perf_measurements,brotli_compression,blurhashing \
|
||||
--features=console,systemd,element_hacks,direct_tls,perf_measurements,brotli_compression \
|
||||
--color=always \
|
||||
-- \
|
||||
-D warnings
|
||||
|
||||
Generated
+24
-24
@@ -3,11 +3,11 @@
|
||||
"advisory-db": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1775907537,
|
||||
"narHash": "sha256-vbeLNgmsx1Z6TwnlDV0dKyeBCcon3UpkV9yLr/yc6HM=",
|
||||
"lastModified": 1781566179,
|
||||
"narHash": "sha256-Tqv8I586fYzWpEW/Smq/JqESFa3DVVzVWsnAMtvhy/I=",
|
||||
"owner": "rustsec",
|
||||
"repo": "advisory-db",
|
||||
"rev": "d99f7b9eb81731bddebf80a355f8be7b2f8b1b28",
|
||||
"rev": "74e084413d979d52d2f93b1d93b1ab7b9ee648f5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -18,11 +18,11 @@
|
||||
},
|
||||
"crane": {
|
||||
"locked": {
|
||||
"lastModified": 1775839657,
|
||||
"narHash": "sha256-SPm9ck7jh3Un9nwPuMGbRU04UroFmOHjLP56T10MOeM=",
|
||||
"lastModified": 1780532242,
|
||||
"narHash": "sha256-D+BsdpxmtUwtqGoY0IXPhHgTlmqgcZKCEo1oMyn7ep0=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "7cf72d978629469c4bd4206b95c402514c1f6000",
|
||||
"rev": "59a82a1222dd3b2080b5cc52a1a2e8d5f1b77f37",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -39,11 +39,11 @@
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775891769,
|
||||
"narHash": "sha256-EOfVlTKw2n8w1uhfh46GS4hEGnQ7oWrIWQfIY6utIkI=",
|
||||
"lastModified": 1781527054,
|
||||
"narHash": "sha256-1fX9ev2Fh5QoKQ41G9dYutjo5j/jywu6tZse5Eb1Ck4=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "6fbc54dde15aee725bdc7aae5e478849685d5f56",
|
||||
"rev": "8c2e51dffefc040a21975da7abf6f252c8c9b783",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -74,11 +74,11 @@
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775087534,
|
||||
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
|
||||
"lastModified": 1778716662,
|
||||
"narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
|
||||
"rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -89,11 +89,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1775710090,
|
||||
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
|
||||
"lastModified": 1781074563,
|
||||
"narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
|
||||
"rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -105,11 +105,11 @@
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1774748309,
|
||||
"narHash": "sha256-+U7gF3qxzwD5TZuANzZPeJTZRHS29OFQgkQ2kiTJBIQ=",
|
||||
"lastModified": 1777168982,
|
||||
"narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "333c4e0545a6da976206c74db8773a1645b5870a",
|
||||
"rev": "f5901329dade4a6ea039af1433fb087bd9c1fe14",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -132,11 +132,11 @@
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1775843361,
|
||||
"narHash": "sha256-j53ZgyDvmYf3Sjh1IPvvTjqa614qUfVQSzj59+MpzkY=",
|
||||
"lastModified": 1781453968,
|
||||
"narHash": "sha256-+V3nK4pCngbmgyVGXY6Kkrlevp4ocPkJJLf2aqwkDNA=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "9eb97ea96d8400e8957ddd56702e962614296583",
|
||||
"rev": "cc272809a173c2c11d0e479d639c811c1eacf049",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -153,11 +153,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775636079,
|
||||
"narHash": "sha256-pc20NRoMdiar8oPQceQT47UUZMBTiMdUuWrYu2obUP0=",
|
||||
"lastModified": 1780220602,
|
||||
"narHash": "sha256-eynAfOmbmxJnkp7YewvCEbShNnnYJ9gLLqkzsYtBPeM=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "790751ff7fd3801feeaf96d7dc416a8d581265ba",
|
||||
"rev": "db947814a175b7ca6ded66e21383d938df01c227",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
pkgs,
|
||||
self',
|
||||
...
|
||||
}:
|
||||
{
|
||||
_module.args.craneLib = (inputs.crane.mkLib pkgs).overrideToolchain (
|
||||
pkgs: self'.packages.stable-toolchain
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
imports = [
|
||||
./rust.nix
|
||||
./crane.nix
|
||||
./packages
|
||||
./devshell.nix
|
||||
./fmt.nix
|
||||
|
||||
+29
-28
@@ -1,7 +1,6 @@
|
||||
{
|
||||
{ inputs, ... }: {
|
||||
perSystem =
|
||||
{
|
||||
craneLib,
|
||||
self',
|
||||
lib,
|
||||
pkgs,
|
||||
@@ -9,34 +8,36 @@
|
||||
}:
|
||||
{
|
||||
# basic nix shell containing all things necessary to build continuwuity in all flavors manually (on x86_64-linux)
|
||||
devShells.default = craneLib.devShell {
|
||||
packages = [
|
||||
self'.packages.rocksdb
|
||||
pkgs.nodejs
|
||||
pkgs.pkg-config
|
||||
]
|
||||
++ lib.optionals pkgs.stdenv.isLinux [
|
||||
pkgs.liburing
|
||||
pkgs.rust-jemalloc-sys-unprefixed
|
||||
];
|
||||
|
||||
env = {
|
||||
LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ];
|
||||
LD_LIBRARY_PATH = lib.makeLibraryPath (
|
||||
[
|
||||
pkgs.stdenv.cc.cc.lib
|
||||
devShells.default =
|
||||
((inputs.crane.mkLib pkgs).overrideToolchain (pkgs: self'.packages.stable-toolchain)).devShell
|
||||
{
|
||||
packages = [
|
||||
self'.packages.rocksdb
|
||||
pkgs.nodejs
|
||||
pkgs.pkg-config
|
||||
]
|
||||
++ lib.optionals pkgs.stdenv.isLinux [
|
||||
pkgs.liburing
|
||||
pkgs.jemalloc
|
||||
]
|
||||
);
|
||||
}
|
||||
// lib.optionalAttrs pkgs.stdenv.isLinux {
|
||||
PKG_CONFIG_PATH = lib.makeSearchPath "lib/pkgconfig" [
|
||||
pkgs.liburing.dev
|
||||
];
|
||||
};
|
||||
};
|
||||
pkgs.rust-jemalloc-sys-unprefixed
|
||||
];
|
||||
|
||||
env = {
|
||||
LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ];
|
||||
LD_LIBRARY_PATH = lib.makeLibraryPath (
|
||||
[
|
||||
pkgs.stdenv.cc.cc.lib
|
||||
]
|
||||
++ lib.optionals pkgs.stdenv.isLinux [
|
||||
pkgs.liburing
|
||||
pkgs.jemalloc
|
||||
]
|
||||
);
|
||||
}
|
||||
// lib.optionalAttrs pkgs.stdenv.isLinux {
|
||||
PKG_CONFIG_PATH = lib.makeSearchPath "lib/pkgconfig" [
|
||||
pkgs.liburing.dev
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
lib,
|
||||
self,
|
||||
stdenv,
|
||||
liburing,
|
||||
rocksdb,
|
||||
craneLib,
|
||||
pkg-config,
|
||||
callPackage,
|
||||
liburing,
|
||||
rustPlatform,
|
||||
cargoExtraArgs ? "",
|
||||
rustflags ? "",
|
||||
rocksdb ? callPackage ./rocksdb.nix { },
|
||||
target_cpu ? null,
|
||||
profile ? "release",
|
||||
}:
|
||||
let
|
||||
@@ -28,18 +28,29 @@ let
|
||||
};
|
||||
|
||||
attrs = {
|
||||
__structuredAttrs = true;
|
||||
strictDeps = true;
|
||||
|
||||
inherit src;
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
rustPlatform.bindgenHook
|
||||
];
|
||||
|
||||
buildInputs = lib.optionals stdenv.hostPlatform.isLinux [ liburing ];
|
||||
|
||||
env = {
|
||||
ROCKSDB_INCLUDE_DIR = "${rocksdb}/include";
|
||||
ROCKSDB_LIB_DIR = "${rocksdb}/lib";
|
||||
CARGO_PROFILE = profile;
|
||||
RUSTFLAGS = rustflags;
|
||||
};
|
||||
}
|
||||
// (lib.optionalAttrs (rocksdb != null) {
|
||||
ROCKSDB_INCLUDE_DIR = "${rocksdb}/include";
|
||||
ROCKSDB_LIB_DIR = "${rocksdb}/lib";
|
||||
})
|
||||
// (lib.optionalAttrs (target_cpu != null) {
|
||||
TARGET_CPU = target_cpu;
|
||||
});
|
||||
};
|
||||
in
|
||||
craneLib.buildPackage (
|
||||
@@ -48,7 +59,7 @@ craneLib.buildPackage (
|
||||
cargoArtifacts = craneLib.buildDepsOnly attrs;
|
||||
|
||||
# Needed to make continuwuity link to rocksdb
|
||||
postFixup = lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||
postFixup = lib.optionalString (stdenv.hostPlatform.isLinux && rocksdb != null) ''
|
||||
old_rpath="$(patchelf --print-rpath $out/bin/conduwuit)"
|
||||
extra_rpath="${
|
||||
lib.makeLibraryPath [
|
||||
@@ -56,7 +67,7 @@ craneLib.buildPackage (
|
||||
]
|
||||
}"
|
||||
|
||||
patchelf --set-rpath "$old_rpath:$extra_rpath" $out/bin/conduwuit
|
||||
patchelf --set-rpath "$old_rpath:$extra_rpath" $out/bin/conduwuit
|
||||
'';
|
||||
|
||||
meta = {
|
||||
|
||||
+75
-19
@@ -1,4 +1,5 @@
|
||||
{
|
||||
inputs,
|
||||
self,
|
||||
...
|
||||
}:
|
||||
@@ -6,29 +7,84 @@
|
||||
perSystem =
|
||||
{
|
||||
self',
|
||||
lib,
|
||||
pkgs,
|
||||
inputs',
|
||||
system,
|
||||
craneLib,
|
||||
mkToolchain,
|
||||
...
|
||||
}:
|
||||
{
|
||||
packages = {
|
||||
rocksdb = pkgs.callPackage ./rocksdb.nix { };
|
||||
default = pkgs.callPackage ./continuwuity.nix {
|
||||
inherit self craneLib;
|
||||
# extra features via `cargoExtraArgs`
|
||||
cargoExtraArgs = "-F http3";
|
||||
# extra RUSTFLAGS via `rustflags`
|
||||
# the stuff below is required for http3
|
||||
rustflags = "--cfg reqwest_unstable";
|
||||
};
|
||||
# users may also override this with other cargo profiles to build for other feature sets
|
||||
#
|
||||
# other examples include:
|
||||
#
|
||||
# - release-high-perf
|
||||
max-perf = self'.packages.default.override {
|
||||
profile = "release-max-perf";
|
||||
};
|
||||
};
|
||||
packages =
|
||||
let
|
||||
mkPackages =
|
||||
pkgs:
|
||||
let
|
||||
fnx = inputs'.fenix.packages;
|
||||
|
||||
isStatic = pkgs.stdenv.hostPlatform.isMusl;
|
||||
|
||||
craneLib = (inputs.crane.mkLib pkgs).overrideToolchain (
|
||||
_:
|
||||
if isStatic then
|
||||
fnx.combine [
|
||||
self'.packages.stable-toolchain
|
||||
(mkToolchain fnx.targets.${pkgs.stdenv.hostPlatform.config}).rust-std
|
||||
]
|
||||
else
|
||||
self'.packages.stable-toolchain
|
||||
);
|
||||
|
||||
default = pkgs.callPackage ./continuwuity.nix {
|
||||
inherit self craneLib;
|
||||
|
||||
liburing = (if isStatic then pkgs.pkgsStatic else pkgs).liburing;
|
||||
rocksdb = if isStatic then null else self'.packages.rocksdb;
|
||||
|
||||
# extra features via `cargoExtraArgs`
|
||||
cargoExtraArgs = "-F http3";
|
||||
# extra RUSTFLAGS via `rustflags`
|
||||
# the stuff below is required for http3
|
||||
rustflags = "--cfg reqwest_unstable";
|
||||
};
|
||||
|
||||
# users may also override this with other cargo profiles to build for other feature sets
|
||||
# for features configuration see `default` package which enables http3 by default
|
||||
|
||||
max-perf = default.override {
|
||||
# compiles slower but with more thorough optimizations
|
||||
profile = "release-max-perf";
|
||||
};
|
||||
|
||||
max-perf-haswell = max-perf.override {
|
||||
# compiles explicitly for haswell arch cpus
|
||||
target_cpu = "haswell";
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit default max-perf max-perf-haswell;
|
||||
};
|
||||
in
|
||||
{
|
||||
rocksdb = pkgs.callPackage ./rocksdb.nix { };
|
||||
}
|
||||
// (mkPackages pkgs)
|
||||
// (lib.mapAttrs' (name: value: lib.nameValuePair "${name}-static-x86_64" value) (
|
||||
mkPackages (
|
||||
import inputs.nixpkgs {
|
||||
localSystem = system;
|
||||
crossSystem = "x86_64-unknown-linux-musl";
|
||||
}
|
||||
)
|
||||
))
|
||||
// (lib.mapAttrs' (name: value: lib.nameValuePair "${name}-static-aarch64" value) (
|
||||
mkPackages (
|
||||
import inputs.nixpkgs {
|
||||
localSystem = system;
|
||||
crossSystem = "aarch64-unknown-linux-musl";
|
||||
}
|
||||
)
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
stdenv,
|
||||
# stdenv,
|
||||
# enableJemalloc ? stdenv.hostPlatform.isLinux,
|
||||
enableJemalloc ? false,
|
||||
rocksdb,
|
||||
fetchFromGitea,
|
||||
rust-jemalloc-sys-unprefixed,
|
||||
@@ -13,16 +15,16 @@
|
||||
#
|
||||
# [1]: https://github.com/tikv/jemallocator/blob/ab0676d77e81268cd09b059260c75b38dbef2d51/jemalloc-sys/src/env.rs#L17
|
||||
jemalloc = rust-jemalloc-sys-unprefixed;
|
||||
enableJemalloc = stdenv.hostPlatform.isLinux;
|
||||
inherit enableJemalloc;
|
||||
}).overrideAttrs
|
||||
({
|
||||
version = "continuwuity-v0.5.0-unstable-2026-03-27";
|
||||
version = "continuwuity-v0.5.0-unstable-2026-05-19";
|
||||
src = fetchFromGitea {
|
||||
domain = "forgejo.ellis.link";
|
||||
owner = "continuwuation";
|
||||
repo = "rocksdb";
|
||||
rev = "463f47afceebfe088f6922420265546bd237f249";
|
||||
hash = "sha256-1ef75IDMs5Hba4VWEyXPJb02JyShy5k4gJfzGDhopRk=";
|
||||
rev = "3756b2b905e13216d8b56bcc783d814e7b073aff";
|
||||
hash = "sha256-rSv4fr2bf9JJwdodgeuPCuceeh7k97KVxrAOC0wyPQY=";
|
||||
};
|
||||
|
||||
# We have this already at https://forgejo.ellis.link/continuwuation/rocksdb/commit/a935c0273e1ba44eacf88ce3685a9b9831486155
|
||||
|
||||
+13
-9
@@ -2,22 +2,26 @@
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
system,
|
||||
lib,
|
||||
inputs',
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
mkToolchain =
|
||||
target:
|
||||
target.fromToolchainName {
|
||||
name = (lib.importTOML "${inputs.self}/rust-toolchain.toml").toolchain.channel;
|
||||
sha256 = "sha256-mvUGEOHYJpn3ikC5hckneuGixaC+yGrkMM/liDIDgoU=";
|
||||
};
|
||||
in
|
||||
{
|
||||
_module.args = { inherit mkToolchain; };
|
||||
|
||||
packages =
|
||||
let
|
||||
fnx = inputs.fenix.packages.${system};
|
||||
|
||||
stable-toolchain = fnx.fromToolchainFile {
|
||||
file = inputs.self + "/rust-toolchain.toml";
|
||||
|
||||
# See also `rust-toolchain.toml`
|
||||
sha256 = "sha256-sqSWJDUxc+zaz1nBWMAJKTAGBuGWP25GCftIOlCEAtA=";
|
||||
};
|
||||
fnx = inputs'.fenix.packages;
|
||||
stable-toolchain = (mkToolchain fnx).toolchain;
|
||||
in
|
||||
{
|
||||
inherit stable-toolchain;
|
||||
|
||||
Generated
+263
-235
@@ -16,26 +16,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz",
|
||||
"integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==",
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.1",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
|
||||
"integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==",
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
|
||||
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
@@ -47,7 +45,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
@@ -109,9 +106,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz",
|
||||
"integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==",
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
|
||||
"integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
@@ -128,14 +125,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rsbuild/core": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-eqxtRlQiFSm/ibCNGiPj8ozsGSNK91NY+GksmPuTCPmWQExGtPqM1V+s13UYeWZS6fYbMRs7NlQKD896e0QkKA==",
|
||||
"version": "2.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-2.0.15.tgz",
|
||||
"integrity": "sha512-O8vmMhZu1YImO6jOqt/K/vlJSvkq7UtSq5YM1DIlcEd9LW8Gf6/dkQ1B2KPI6F+hSMFBnTTTumdcIowSLCw97g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rspack/core": "2.0.0-rc.1",
|
||||
"@swc/helpers": "^0.5.21"
|
||||
"@rspack/core": "~2.0.8",
|
||||
"@swc/helpers": "^0.5.23"
|
||||
},
|
||||
"bin": {
|
||||
"rsbuild": "bin/rsbuild.js"
|
||||
@@ -153,17 +150,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rsbuild/plugin-react": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@rsbuild/plugin-react/-/plugin-react-1.4.6.tgz",
|
||||
"integrity": "sha512-LAT6xHlEyZKA0VjF/ph5d50iyG+WSmBx+7g98HNZUwb94VeeTMZFB8qVptTkbIRMss3BNKOXmHOu71Lhsh9oEw==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@rsbuild/plugin-react/-/plugin-react-2.0.1.tgz",
|
||||
"integrity": "sha512-n5m3VxEm6m3Dv1VkI0WnxsildySJ6M+QjGIzkZDy5UebRCIJ1Q/hlQVyhofBL6C+AcsF9fGjlHQkeiteXJSr3Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rspack/plugin-react-refresh": "^1.6.1",
|
||||
"@rspack/plugin-react-refresh": "2.0.0",
|
||||
"react-refresh": "^0.18.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@rsbuild/core": "^1.0.0 || ^2.0.0-0"
|
||||
"@rsbuild/core": "^2.0.0-0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@rsbuild/core": {
|
||||
@@ -172,28 +169,28 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rspack/binding": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-rhJqtbyiRPOjTAZW0xTZFbOrS5yP5yL1SF0DPE9kvFfzePz30IqjMDMxL0KuhkDZd/M1eUINJyoqd8NTbR9wHw==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-2.0.8.tgz",
|
||||
"integrity": "sha512-3uZ+y8aQxq33ty2srMxg2Nu0XuBI6vVrG50rkDaXqwWqOohfgGUSfFuQK7EnSUNy4aFUQlCG6NHialQHJov0wg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optionalDependencies": {
|
||||
"@rspack/binding-darwin-arm64": "2.0.0-rc.1",
|
||||
"@rspack/binding-darwin-x64": "2.0.0-rc.1",
|
||||
"@rspack/binding-linux-arm64-gnu": "2.0.0-rc.1",
|
||||
"@rspack/binding-linux-arm64-musl": "2.0.0-rc.1",
|
||||
"@rspack/binding-linux-x64-gnu": "2.0.0-rc.1",
|
||||
"@rspack/binding-linux-x64-musl": "2.0.0-rc.1",
|
||||
"@rspack/binding-wasm32-wasi": "2.0.0-rc.1",
|
||||
"@rspack/binding-win32-arm64-msvc": "2.0.0-rc.1",
|
||||
"@rspack/binding-win32-ia32-msvc": "2.0.0-rc.1",
|
||||
"@rspack/binding-win32-x64-msvc": "2.0.0-rc.1"
|
||||
"@rspack/binding-darwin-arm64": "2.0.8",
|
||||
"@rspack/binding-darwin-x64": "2.0.8",
|
||||
"@rspack/binding-linux-arm64-gnu": "2.0.8",
|
||||
"@rspack/binding-linux-arm64-musl": "2.0.8",
|
||||
"@rspack/binding-linux-x64-gnu": "2.0.8",
|
||||
"@rspack/binding-linux-x64-musl": "2.0.8",
|
||||
"@rspack/binding-wasm32-wasi": "2.0.8",
|
||||
"@rspack/binding-win32-arm64-msvc": "2.0.8",
|
||||
"@rspack/binding-win32-ia32-msvc": "2.0.8",
|
||||
"@rspack/binding-win32-x64-msvc": "2.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@rspack/binding-darwin-arm64": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-fYbeDDDg6QKZzXYt/J0/j0Qhr01wQLuISUsYnNhu5MLwdXVUSVcqz+CTqgF3d0EQVVn6FqLV63lbNRzUGfSq9g==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-2.0.8.tgz",
|
||||
"integrity": "sha512-vCgbgH7B7qom+uID+RCZsTCOYFb9wC4/4+1U6rMfytrXGVJ72eNQs2tbdjOl0lb18CT3N/n+VkWynUiLk84GwA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -205,9 +202,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rspack/binding-darwin-x64": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-MvXi9kr8xXn1y0PD1WI/4YphRNOdbykJjKdEsAG4JxEVoERmhIHOTwKvUqlejajizAwlVZcxQl/FacoPLsKN5Q==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-2.0.8.tgz",
|
||||
"integrity": "sha512-satPm2PD4B7jDTVlVAdvMVdUszwLvWUEnUDzLb77mvVkezKNDZmuhb+e8s+FfKs8hJpNbZ9VAejuA2rr8o985w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -219,9 +216,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rspack/binding-linux-arm64-gnu": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-j6WsHEwGSdUoiy4BsQBW0RjFl+MBzozdybSYhkiyVSoHlbm7CPt3XaaS3elH5YcwuLHORmVHPP91QhwWl9UFJg==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-2.0.8.tgz",
|
||||
"integrity": "sha512-pSI+npPQE/uDtiboqvcOIRJbEV2+B+H1xffmko/gw50la92oTUW60kVULFwsb6L0+GVCzIcwX3yq60GtYIn+Ug==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -236,9 +233,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rspack/binding-linux-arm64-musl": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-MPoZE0aS8oH+Wr0R5tIYch8gbUwYYf4LsiGdP6enMKMTrmpJyOVGlhPHVSwsrFgBg7fjTGOuxHuibtsvDUdLOQ==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-2.0.8.tgz",
|
||||
"integrity": "sha512-igjJ43yxWQ72GZqjDDZSSHax9/Vg+6rLMmOvFglTJUkQpB4Tyvu/YjW+WRjYj2xRw6blOjLxUSJWASvuSqqlvg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -253,9 +250,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rspack/binding-linux-x64-gnu": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-gOlPCwtIg9GsFG/8ZdUyV5SyXDaGq2kmtXmyyFU7RO33MaalltNEBMf2hevRPj9z39eSzxwgJDonMOdx5Fo0Og==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-2.0.8.tgz",
|
||||
"integrity": "sha512-zrkoEOnqj1hOEBO5T2I/2Ts2HSJsYFh1qXwMpK4dMJFGGNWDfNeUa6/LF5uq3VINF3JUl7RL47AgrucoSZJXPA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -270,9 +267,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rspack/binding-linux-x64-musl": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-K6Swk1rfP4z4b6bp84NlikGlUWMOPpIWCtlPr/W0TWgc2C/cd844oHdoIu7WtmOH7y9AwB5UG2bWpgFAVwykCw==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-2.0.8.tgz",
|
||||
"integrity": "sha512-6CtDaGZjNDvJd9TBp7a9zABbrPORO21W96+3ZcGBn0YNUPUk4ARxIxrTTpeJ/1F41QDM8AYIkGDdqEYMqTYBsA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -287,9 +284,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rspack/binding-wasm32-wasi": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-aa9oUTqOb1QjwsHVlMr5sV+7mcBI4MLQ/xhFO2CIEcfVnJIPl8XpKUbDEgqMwcFlzcgzKmHg5cVmIvd82BLgow==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-2.0.8.tgz",
|
||||
"integrity": "sha512-Yf4SiqTUroT5Ju+te0YAY2xxKOb35tECsO21v7hYyGa705wrgoAK/MmF7enOvs9GR1iZIqgiLD/wxsIxl8GjJw==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
@@ -297,13 +294,15 @@
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "1.1.2"
|
||||
"@emnapi/core": "1.10.0",
|
||||
"@emnapi/runtime": "1.10.0",
|
||||
"@napi-rs/wasm-runtime": "1.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@rspack/binding-win32-arm64-msvc": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-+UxF0c7E9bE3siFbMHi+mmoeQJzcTKl1j3x+Y6MY/PJ3V70cU23wOaxMvmSsCyq2JNJBT2RCNZ9HaL+o3kReug==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-2.0.8.tgz",
|
||||
"integrity": "sha512-8NCuiQsAhXrwRBy57QZoypqrws/zLBkaQVGiB8hksr6v++8hNigNjqpQARLbd0iyMuHsQQ++8+auGk6xlDXmzw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -315,9 +314,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rspack/binding-win32-ia32-msvc": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-gc0JdkdxSWo+o/b1qTCT6mZ3DrlGe32eW+Ps3xInxcG4UHjUG7hTDgFtOgVQ6VhQ8WMUXG+TQOz0CySVpYjsoQ==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-2.0.8.tgz",
|
||||
"integrity": "sha512-bxiekytbX7V9KFAra+HkwtNWC6pYfHEBBZFpiT0xUs3mCFOmAAFVBsBSQsoCP9AdCEXoMAvNdnrHNw3iov4OZw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -329,9 +328,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rspack/binding-win32-x64-msvc": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-Dnj0jthyVUikf65MGEyZy3akshtSmR1xsp/Xr0h/NWTo5JFWHKAFNYFE+jFfY0uzC8e4IDcLQLYoFomqV1DsEg==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-2.0.8.tgz",
|
||||
"integrity": "sha512-7zPs8YCe/ZVJTwd+5lpB0CP0tkn2pONf/T1ycmVY76u21Nrwt8mXQGc/2yH2eWP4B7fikYBr3hGr7mpR2fajqQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -343,20 +342,20 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rspack/core": {
|
||||
"version": "2.0.0-rc.1",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/core/-/core-2.0.0-rc.1.tgz",
|
||||
"integrity": "sha512-OIfkYn05/IWtVIdZ8Y/a0y/k4ipzqfApxIZqnJM59G/bGwQKMBrLHpOMGgV2Wmq1j9UMXzF7ZtsFMUbYBhFb9A==",
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/core/-/core-2.0.8.tgz",
|
||||
"integrity": "sha512-+NLGJf8gZxihDmMFzjlly3toc2SMjeDmuvz0/Cai9AMdV4F+Pqcnt2BA9V4e3SY2jmhJQtPwgyyLtR1RiJO77g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rspack/binding": "2.0.0-rc.1"
|
||||
"@rspack/binding": "2.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@module-federation/runtime-tools": "^0.24.1 || ^2.0.0",
|
||||
"@swc/helpers": ">=0.5.1"
|
||||
"@swc/helpers": "^0.5.23"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@module-federation/runtime-tools": {
|
||||
@@ -368,39 +367,36 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rspack/plugin-react-refresh": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-1.6.2.tgz",
|
||||
"integrity": "sha512-k+/VrfTNgo+KirjI6V+8CWRj6y+DH9jOUWv8JorYY4vKf/9xfnZ8xHzuB4iqCwTtoZl9YnxOaOuoyjJipc2tiQ==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@rspack/plugin-react-refresh/-/plugin-react-refresh-2.0.0.tgz",
|
||||
"integrity": "sha512-Cf6CxBStNDJbiXMc/GmsvG1G8PRlUpa0MSfWsMTI+e8npzuTN/p8nwLs3shriBZOLciqgkSZpBtPTd10BLpj1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"error-stack-parser": "^2.1.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react-refresh": ">=0.10.0 <1.0.0",
|
||||
"webpack-hot-middleware": "2.x"
|
||||
"@rspack/core": "^2.0.0-0",
|
||||
"react-refresh": ">=0.10.0 <1.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"webpack-hot-middleware": {
|
||||
"@rspack/core": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rspress/core": {
|
||||
"version": "2.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@rspress/core/-/core-2.0.9.tgz",
|
||||
"integrity": "sha512-cfbqqbWtdimrWIsfeyPnQOTKwJpdNLr8VnwLIL4JYC2ZcRq+xcInpszLXVpV86nONL6qI19usr2Or7uzZJ+ynA==",
|
||||
"version": "2.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@rspress/core/-/core-2.0.15.tgz",
|
||||
"integrity": "sha512-epLmUXYscNRw/GtQZx2oknoBE9wKbCrUGEOrQEDI4Qq8X32GdM4d7itzuHsliY7q3IbffKx8rMVbvlmygEocTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@mdx-js/mdx": "^3.1.1",
|
||||
"@mdx-js/react": "^3.1.1",
|
||||
"@rsbuild/core": "2.0.0-rc.1",
|
||||
"@rsbuild/plugin-react": "~1.4.6",
|
||||
"@rspress/shared": "2.0.9",
|
||||
"@shikijs/rehype": "^4.0.2",
|
||||
"@rsbuild/core": "^2.0.15",
|
||||
"@rsbuild/plugin-react": "~2.0.1",
|
||||
"@rspress/shared": "2.0.15",
|
||||
"@shikijs/rehype": "^4.2.0",
|
||||
"@types/unist": "^3.0.3",
|
||||
"@unhead/react": "^2.1.13",
|
||||
"@unhead/react": "^2.1.15",
|
||||
"body-scroll-lock": "4.0.0-beta.0",
|
||||
"clsx": "2.1.1",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
@@ -411,22 +407,22 @@
|
||||
"mdast-util-mdxjs-esm": "^2.0.1",
|
||||
"medium-zoom": "1.1.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"react": "^19.2.7",
|
||||
"react-dom": "^19.2.7",
|
||||
"react-lazy-with-preload": "^2.2.1",
|
||||
"react-reconciler": "0.33.0",
|
||||
"react-render-to-markdown": "19.0.1",
|
||||
"react-router-dom": "^7.13.2",
|
||||
"react-render-to-markdown": "19.1.0",
|
||||
"react-router-dom": "^7.15.1",
|
||||
"rehype-external-links": "^3.0.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-cjk-friendly": "^2.0.1",
|
||||
"remark-cjk-friendly-gfm-strikethrough": "^2.0.1",
|
||||
"remark-cjk-friendly": "^2.3.1",
|
||||
"remark-cjk-friendly-gfm-strikethrough": "^2.1.0",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"remark-mdx": "^3.1.1",
|
||||
"remark-parse": "^11.0.0",
|
||||
"remark-stringify": "^11.0.0",
|
||||
"scroll-into-view-if-needed": "^3.1.0",
|
||||
"shiki": "^4.0.2",
|
||||
"shiki": "^4.2.0",
|
||||
"unified": "^11.0.5",
|
||||
"unist-util-remove": "^4.0.0",
|
||||
"unist-util-visit": "^5.1.0",
|
||||
@@ -440,52 +436,52 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rspress/plugin-client-redirects": {
|
||||
"version": "2.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@rspress/plugin-client-redirects/-/plugin-client-redirects-2.0.9.tgz",
|
||||
"integrity": "sha512-r2GyHzOSt8CeS4UIsy/cPM5Zotekt1JVQFmgOYGapvll5ktUlVcd77HLtXDbZjtpgtj0XlaMLrXueOpV2gsBoQ==",
|
||||
"version": "2.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@rspress/plugin-client-redirects/-/plugin-client-redirects-2.0.15.tgz",
|
||||
"integrity": "sha512-bPf/KIHH7Y6huLTtK6JXwRfxM7zKjksoxm46+IBsF1wisw0doKkEKR9HwJydxWnykyKBbA2cuZOaoT4h174Z1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@rspress/core": "^2.0.9"
|
||||
"@rspress/core": "^2.0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@rspress/plugin-sitemap": {
|
||||
"version": "2.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@rspress/plugin-sitemap/-/plugin-sitemap-2.0.9.tgz",
|
||||
"integrity": "sha512-GTuXuySaeaazUZoUxdk2vZ8p0ehIgulPjCP9C7gDg6lIh5JGpUbcjG4def4tWHsxUoKp2rIwu/93bHwKb8T0Mw==",
|
||||
"version": "2.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@rspress/plugin-sitemap/-/plugin-sitemap-2.0.15.tgz",
|
||||
"integrity": "sha512-z1hbyGP79ZXdSGJxiWw7ZjmX8qW0q9nXMDxr14cVEg/wdj7ToVzGtZHw0wvTPE0YiKG3BMiGkVNfE1rdOaPXiQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@rspress/core": "^2.0.9"
|
||||
"@rspress/core": "^2.0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@rspress/shared": {
|
||||
"version": "2.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@rspress/shared/-/shared-2.0.9.tgz",
|
||||
"integrity": "sha512-G48n3pC7AVAR58pLqwClUCYj5Nt7ZgYEStR8VTBGFuPgXtzb3+KPfo/gz0hb6wxdKJ1cL5ohPsZ6EXqllu6lew==",
|
||||
"version": "2.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@rspress/shared/-/shared-2.0.15.tgz",
|
||||
"integrity": "sha512-o8aYwEzNuTmWnmKe91ntPv+34u3RbtAe+rcK9XC5MANOlgncwOaCs3bUa8/B1/llwyLoNgrpi+VB9bEiU11ZRQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rsbuild/core": "2.0.0-rc.1",
|
||||
"@shikijs/rehype": "^4.0.2",
|
||||
"@rsbuild/core": "^2.0.15",
|
||||
"@shikijs/rehype": "^4.2.0",
|
||||
"unified": "^11.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@shikijs/core": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.0.2.tgz",
|
||||
"integrity": "sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.2.0.tgz",
|
||||
"integrity": "sha512-Hc87Ab1Ld/vEbZRCbwx344I5v+4RU8CVToUTRkqXL1+TjbuOp9U5Xa0M23V4GEWHxVn+yO5otb+HkQVm3ptWQQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@shikijs/primitive": "4.0.2",
|
||||
"@shikijs/types": "4.0.2",
|
||||
"@shikijs/primitive": "4.2.0",
|
||||
"@shikijs/types": "4.2.0",
|
||||
"@shikijs/vscode-textmate": "^10.0.2",
|
||||
"@types/hast": "^3.0.4",
|
||||
"hast-util-to-html": "^9.0.5"
|
||||
@@ -495,28 +491,28 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@shikijs/engine-javascript": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.0.2.tgz",
|
||||
"integrity": "sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.2.0.tgz",
|
||||
"integrity": "sha512-fjETeq1k5ffyXqRgS6+3hpvqseLalp1kjNfRbXpUgWR8FpZ1CmQfiNHovc5lncYjt/Vg5JK/WJEmLahjwMa0og==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@shikijs/types": "4.0.2",
|
||||
"@shikijs/types": "4.2.0",
|
||||
"@shikijs/vscode-textmate": "^10.0.2",
|
||||
"oniguruma-to-es": "^4.3.4"
|
||||
"oniguruma-to-es": "^4.3.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/@shikijs/engine-oniguruma": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.0.2.tgz",
|
||||
"integrity": "sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.2.0.tgz",
|
||||
"integrity": "sha512-hTorK1dffPkpbMUk6Z+828PgRo7d07HbnizoP0hNPFjhxMHctj0Px/qoHeGMYafc6ju+u9iMldN4JbVzNQM++g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@shikijs/types": "4.0.2",
|
||||
"@shikijs/types": "4.2.0",
|
||||
"@shikijs/vscode-textmate": "^10.0.2"
|
||||
},
|
||||
"engines": {
|
||||
@@ -524,26 +520,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@shikijs/langs": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.0.2.tgz",
|
||||
"integrity": "sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.2.0.tgz",
|
||||
"integrity": "sha512-bwrVRlJ0wUhZxAbVdvBbv2TTC9yLsh4C/IO5Ofz0T8MQntgDvyVnkbjw9vi50r1kx7RCIJdnJnjZAwmAsXFLZQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@shikijs/types": "4.0.2"
|
||||
"@shikijs/types": "4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/@shikijs/primitive": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.0.2.tgz",
|
||||
"integrity": "sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.2.0.tgz",
|
||||
"integrity": "sha512-NOq+DtUkVBJtZMVXL5A0vI0Xk8nvDYaXetFHSJFlOqjDZIVhIPRYFdGkSoElDqNuegikcc3A76SNUa8dTqtAYA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@shikijs/types": "4.0.2",
|
||||
"@shikijs/types": "4.2.0",
|
||||
"@shikijs/vscode-textmate": "^10.0.2",
|
||||
"@types/hast": "^3.0.4"
|
||||
},
|
||||
@@ -552,16 +548,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@shikijs/rehype": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/rehype/-/rehype-4.0.2.tgz",
|
||||
"integrity": "sha512-cmPlKLD8JeojasNFoY64162ScpEdEdQUMuVodPCrv1nx1z3bjmGwoKWDruQWa/ejSznImlaeB0Ty6Q3zPaVQAA==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/rehype/-/rehype-4.2.0.tgz",
|
||||
"integrity": "sha512-ST3EWye/dwF1gWskczJNBnwFtDzEQ9ceytXZtyc/GfwR5V0qJrkoSGZO55O3SAKDDsXkTDcsfwd9pVe7ROlAHg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@shikijs/types": "4.0.2",
|
||||
"@shikijs/types": "4.2.0",
|
||||
"@types/hast": "^3.0.4",
|
||||
"hast-util-to-string": "^3.0.1",
|
||||
"shiki": "4.0.2",
|
||||
"shiki": "4.2.0",
|
||||
"unified": "^11.0.5",
|
||||
"unist-util-visit": "^5.1.0"
|
||||
},
|
||||
@@ -570,22 +566,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@shikijs/themes": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.0.2.tgz",
|
||||
"integrity": "sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.2.0.tgz",
|
||||
"integrity": "sha512-RX8IHYeLv8Cu2W6ruc3RxUqWn0IYCqSrMBzi/uRGAmfyDNOnNO5BF/Px7o97n4XTpmFTo5GbRaazuOWj+2ak2w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@shikijs/types": "4.0.2"
|
||||
"@shikijs/types": "4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/@shikijs/types": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.0.2.tgz",
|
||||
"integrity": "sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.2.0.tgz",
|
||||
"integrity": "sha512-VT/MKtlpOhEPZloSH3Pb9WCZEBDoQVMa9jedp5UAwmJOar1DVc9DRODAxmYPW9M93IK4ryuqRejFfmlvlVDemw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -604,9 +600,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz",
|
||||
"integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==",
|
||||
"version": "0.5.23",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz",
|
||||
"integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -614,9 +610,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
|
||||
"integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
|
||||
"integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
@@ -635,9 +631,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
|
||||
"integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -672,9 +668,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdx": {
|
||||
"version": "2.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz",
|
||||
"integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==",
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.14.tgz",
|
||||
"integrity": "sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -686,9 +682,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.2.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
|
||||
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
|
||||
"version": "19.2.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
|
||||
"integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
@@ -704,20 +700,20 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@ungap/structured-clone": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
|
||||
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.1.tgz",
|
||||
"integrity": "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@unhead/react": {
|
||||
"version": "2.1.13",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/react/-/react-2.1.13.tgz",
|
||||
"integrity": "sha512-gC48tNJ0UtbithkiKCc2WUlxbVVk5o171EtruS2w2hQUblfYFHzCPu2hljjT1e0tUHXXqN8EMv7mpxHddMB2sg==",
|
||||
"version": "2.1.15",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/react/-/react-2.1.15.tgz",
|
||||
"integrity": "sha512-5hfAaZ3XJq9JkspRzZdSPsMrXXA8v/SKiEOxZcN9L40o44byF/50bcQuOLgSSCAx8802mI5VG32KZXWTtsLu9Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"unhead": "2.1.13"
|
||||
"unhead": "2.1.15"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
@@ -727,9 +723,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.16.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
||||
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
||||
"version": "8.17.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
|
||||
"integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
@@ -972,16 +968,6 @@
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/error-stack-parser": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
|
||||
"integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"stackframe": "^1.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/esast-util-from-estree": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz",
|
||||
@@ -1164,9 +1150,9 @@
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/get-east-asian-width": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz",
|
||||
"integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==",
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
|
||||
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -1413,9 +1399,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/hookable": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hookable/-/hookable-6.1.0.tgz",
|
||||
"integrity": "sha512-ZoKZSJgu8voGK2geJS+6YtYjvIzu9AOM/KZXsBxr83uhLL++e9pEv/dlgwgy3dvHg06kTz6JOh1hk3C8Ceiymw==",
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/hookable/-/hookable-6.1.1.tgz",
|
||||
"integrity": "sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@@ -1835,6 +1821,53 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-to-markdown-cjk-friendly": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-to-markdown-cjk-friendly/-/mdast-util-to-markdown-cjk-friendly-1.0.0.tgz",
|
||||
"integrity": "sha512-BoaAm8mlJ+LAYz0Qs532Y3ciTuQYgBUPZcSFbvC/ZKmEMAKgulw84YvQK1gI34t/vL2euSfuaWlqczkTBgamkw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mdast-util-to-markdown": "^2.1.2",
|
||||
"micromark-extension-cjk-friendly-util": "3.0.1",
|
||||
"micromark-util-symbol": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/mdast": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/mdast": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-to-markdown-cjk-friendly-gfm-strikethrough": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-to-markdown-cjk-friendly-gfm-strikethrough/-/mdast-util-to-markdown-cjk-friendly-gfm-strikethrough-1.0.0.tgz",
|
||||
"integrity": "sha512-1ePVfB4P/vz3xSsm6H3D32r6VYGErxclnuLLFK02/2ReF+UdEKm7caulK6Vm0LBIp5gPRtB2Z1OYDznCkX3k2w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mdast-util-gfm-strikethrough": "^2.0.0",
|
||||
"mdast-util-to-markdown": "^2.1.2",
|
||||
"micromark-extension-cjk-friendly-util": "3.0.1",
|
||||
"micromark-util-symbol": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/mdast": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/mdast": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/mdast-util-to-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
|
||||
@@ -2697,20 +2730,20 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/oniguruma-parser": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz",
|
||||
"integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==",
|
||||
"version": "0.12.2",
|
||||
"resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz",
|
||||
"integrity": "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/oniguruma-to-es": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.5.tgz",
|
||||
"integrity": "sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==",
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz",
|
||||
"integrity": "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"oniguruma-parser": "^0.12.1",
|
||||
"oniguruma-parser": "^0.12.2",
|
||||
"regex": "^6.1.0",
|
||||
"regex-recursion": "^6.0.2"
|
||||
}
|
||||
@@ -2756,9 +2789,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/property-information": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
|
||||
"integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz",
|
||||
"integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
@@ -2767,9 +2800,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "19.2.5",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz",
|
||||
"integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==",
|
||||
"version": "19.2.7",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
|
||||
"integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -2777,16 +2810,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "19.2.5",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz",
|
||||
"integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==",
|
||||
"version": "19.2.7",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
|
||||
"integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"scheduler": "^0.27.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.2.5"
|
||||
"react": "^19.2.7"
|
||||
}
|
||||
},
|
||||
"node_modules/react-lazy-with-preload": {
|
||||
@@ -2823,9 +2856,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-render-to-markdown": {
|
||||
"version": "19.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-render-to-markdown/-/react-render-to-markdown-19.0.1.tgz",
|
||||
"integrity": "sha512-BPv48o+ubcu2JyUDIktvJXFqLIZqR7hA4mvGu1eFIofz9fogT2me9UvXwRvqvGs9jEtNaJkxZIUKUX0oiK4hDA==",
|
||||
"version": "19.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-render-to-markdown/-/react-render-to-markdown-19.1.0.tgz",
|
||||
"integrity": "sha512-dF9b3tO41ezqdmHP8X92kbHbMexJ6iC7iHw4ykC8fwiO7DgpFc9PhMoKlI+BcPzRxGcWgQSdrixVB9RykhjJpQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -2836,9 +2869,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "7.14.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.14.0.tgz",
|
||||
"integrity": "sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ==",
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.17.0.tgz",
|
||||
"integrity": "sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -2859,13 +2892,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "7.14.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.14.0.tgz",
|
||||
"integrity": "sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ==",
|
||||
"version": "7.17.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.17.0.tgz",
|
||||
"integrity": "sha512-fyU2yjGups/hE6Xz0I5ZYbVL8Gx29eCjgpHaRaTaVU+OOAdfRX05KsvyRm0GO8YQwOkhpU3MurW1jyMUJn+zSw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react-router": "7.14.0"
|
||||
"react-router": "7.17.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.0.0"
|
||||
@@ -3025,12 +3058,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/remark-cjk-friendly": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/remark-cjk-friendly/-/remark-cjk-friendly-2.0.1.tgz",
|
||||
"integrity": "sha512-6WwkoQyZf/4j5k53zdFYrR8Ca+UVn992jXdLUSBDZR4eBpFhKyVxmA4gUHra/5fesjGIxrDhHesNr/sVoiiysA==",
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/remark-cjk-friendly/-/remark-cjk-friendly-2.3.1.tgz",
|
||||
"integrity": "sha512-f+pKZRxCRwNEGFBKNRAZAqU91GIK1SAo3ZyFHWRUgC9zcxRR0BXKd6YwqgSsxtW0rNpUDtONj7H5nje2WL3fcA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mdast-util-to-markdown-cjk-friendly": "1.0.0",
|
||||
"micromark-extension-cjk-friendly": "2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3047,12 +3081,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/remark-cjk-friendly-gfm-strikethrough": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/remark-cjk-friendly-gfm-strikethrough/-/remark-cjk-friendly-gfm-strikethrough-2.0.1.tgz",
|
||||
"integrity": "sha512-pWKj25O2eLXIL1aBupayl1fKhco+Brw8qWUWJPVB9EBzbQNd7nGLj0nLmJpggWsGLR5j5y40PIdjxby9IEYTuA==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/remark-cjk-friendly-gfm-strikethrough/-/remark-cjk-friendly-gfm-strikethrough-2.1.0.tgz",
|
||||
"integrity": "sha512-3Kyq2hjY7V7eU8MbVbWW6QQLN81pjJcIvKHvPxr8hZZmcq/9wqm3MJ3iUG34Ch9QTM4WHN+a1JVAVC1fSi5mig==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mdast-util-to-markdown-cjk-friendly-gfm-strikethrough": "1.0.0",
|
||||
"micromark-extension-cjk-friendly-gfm-strikethrough": "2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3178,18 +3213,18 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/shiki": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-4.0.2.tgz",
|
||||
"integrity": "sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-4.2.0.tgz",
|
||||
"integrity": "sha512-hjNax6o/ylDy9lefQEaSDtzaT3iVNtZ3WmpQnbuQNoG4xvnSKf2kSKbihZVO4JRG1TTMejs7CmNRYlWgAL66pQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@shikijs/core": "4.0.2",
|
||||
"@shikijs/engine-javascript": "4.0.2",
|
||||
"@shikijs/engine-oniguruma": "4.0.2",
|
||||
"@shikijs/langs": "4.0.2",
|
||||
"@shikijs/themes": "4.0.2",
|
||||
"@shikijs/types": "4.0.2",
|
||||
"@shikijs/core": "4.2.0",
|
||||
"@shikijs/engine-javascript": "4.2.0",
|
||||
"@shikijs/engine-oniguruma": "4.2.0",
|
||||
"@shikijs/langs": "4.2.0",
|
||||
"@shikijs/themes": "4.2.0",
|
||||
"@shikijs/types": "4.2.0",
|
||||
"@shikijs/vscode-textmate": "^10.0.2",
|
||||
"@types/hast": "^3.0.4"
|
||||
},
|
||||
@@ -3218,13 +3253,6 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/stackframe": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
|
||||
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stringify-entities": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
|
||||
@@ -3311,9 +3339,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/unhead": {
|
||||
"version": "2.1.13",
|
||||
"resolved": "https://registry.npmjs.org/unhead/-/unhead-2.1.13.tgz",
|
||||
"integrity": "sha512-jO9M1sI6b2h/1KpIu4Jeu+ptumLmUKboRRLxys5pYHFeT+lqTzfNHbYUX9bxVDhC1FBszAGuWcUVlmvIPsah8Q==",
|
||||
"version": "2.1.15",
|
||||
"resolved": "https://registry.npmjs.org/unhead/-/unhead-2.1.15.tgz",
|
||||
"integrity": "sha512-MCt5T90mCWyr3Z6pUCdM9lVRXoMoVBlL7z7U4CYVIiaDiuzad/UCfLuMqz5MeNmpZUgoBCQnrucJimU7EZR+XA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
+19
-3
@@ -5,7 +5,7 @@
|
||||
"osvVulnerabilityAlerts": true,
|
||||
"lockFileMaintenance": {
|
||||
"enabled": true,
|
||||
"schedule": ["at any time"]
|
||||
"schedule": ["* * * * 0,6"]
|
||||
},
|
||||
"platformAutomerge": true,
|
||||
"nix": {
|
||||
@@ -66,6 +66,17 @@
|
||||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"groupName": "github-actions-non-major"
|
||||
},
|
||||
{
|
||||
"description": "Batch GitHub Actions digest updates",
|
||||
"matchManagers": ["github-actions"],
|
||||
"matchUpdateTypes": ["digest"],
|
||||
"groupName": "github-actions-digest",
|
||||
"automerge": true,
|
||||
"automergeStrategy": "fast-forward",
|
||||
"schedule": [
|
||||
"* 0-7 * * 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Batch patch-level Node.js dependency updates",
|
||||
"matchManagers": ["npm"],
|
||||
@@ -83,7 +94,10 @@
|
||||
"matchPackageNames": ["crate-ci/typos"],
|
||||
"matchUpdateTypes": ["minor", "patch"],
|
||||
"automerge": true,
|
||||
"automergeStrategy": "fast-forward"
|
||||
"automergeStrategy": "fast-forward",
|
||||
"schedule": [
|
||||
"* 0-7 * * 3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Auto-merge renovatebot docker image updates",
|
||||
@@ -91,7 +105,9 @@
|
||||
"matchPackageNames": ["ghcr.io/renovatebot/renovate"],
|
||||
"automerge": true,
|
||||
"automergeStrategy": "fast-forward",
|
||||
"extends": ["schedule:earlyMondays"]
|
||||
"schedule": [
|
||||
"* 0-7 * * 1"
|
||||
]
|
||||
}
|
||||
],
|
||||
"customManagers": [
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@
|
||||
|
||||
[toolchain]
|
||||
profile = "minimal"
|
||||
channel = "1.92.0"
|
||||
channel = "1.96.0"
|
||||
components = [
|
||||
# For rust-analyzer
|
||||
"rust-src",
|
||||
|
||||
@@ -81,9 +81,11 @@ conduwuit-macros.workspace = true
|
||||
conduwuit-service.workspace = true
|
||||
const-str.workspace = true
|
||||
ctor.workspace = true
|
||||
dtor.workspace = true
|
||||
futures.workspace = true
|
||||
lettre.workspace = true
|
||||
log.workspace = true
|
||||
assign.workspace = true
|
||||
ruma.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde-saphyr.workspace = true
|
||||
|
||||
+26
-11
@@ -1,5 +1,5 @@
|
||||
use clap::Parser;
|
||||
use conduwuit::Result;
|
||||
use conduwuit::{Err, Result};
|
||||
|
||||
use crate::{
|
||||
appservice::{self, AppserviceCommand},
|
||||
@@ -8,6 +8,7 @@
|
||||
debug::{self, DebugCommand},
|
||||
federation::{self, FederationCommand},
|
||||
media::{self, MediaCommand},
|
||||
oidc::{self, OidcCommand},
|
||||
query::{self, QueryCommand},
|
||||
room::{self, RoomCommand},
|
||||
server::{self, ServerCommand},
|
||||
@@ -16,46 +17,50 @@
|
||||
};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(name = conduwuit_core::name(), version = conduwuit_core::version())]
|
||||
#[command(name = conduwuit_core::BRANDING, version = conduwuit_core::version())]
|
||||
pub enum AdminCommand {
|
||||
#[command(subcommand)]
|
||||
/// Commands for managing appservices
|
||||
#[command(subcommand)]
|
||||
Appservices(AppserviceCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
/// Commands for managing local users
|
||||
#[command(subcommand)]
|
||||
Users(UserCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
/// Commands for managing registration tokens
|
||||
#[command(subcommand)]
|
||||
Token(TokenCommand),
|
||||
|
||||
/// Commands for managing OIDC
|
||||
#[command(subcommand)]
|
||||
Oidc(OidcCommand),
|
||||
|
||||
/// Commands for managing rooms
|
||||
#[command(subcommand)]
|
||||
Rooms(RoomCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
/// Commands for managing federation
|
||||
#[command(subcommand)]
|
||||
Federation(FederationCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
/// Commands for managing the server
|
||||
#[command(subcommand)]
|
||||
Server(ServerCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
/// Commands for managing media
|
||||
#[command(subcommand)]
|
||||
Media(MediaCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
/// Commands for checking integrity
|
||||
#[command(subcommand)]
|
||||
Check(CheckCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
/// Commands for debugging things
|
||||
#[command(subcommand)]
|
||||
Debug(DebugCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
/// Low-level queries for database getters and iterators
|
||||
#[command(subcommand)]
|
||||
Query(QueryCommand),
|
||||
}
|
||||
|
||||
@@ -80,6 +85,16 @@ pub(super) async fn process(command: AdminCommand, context: &Context<'_>) -> Res
|
||||
context.bail_restricted()?;
|
||||
token::process(command, context).await
|
||||
},
|
||||
| Oidc(command) => {
|
||||
// OIDC commands are all restricted
|
||||
context.bail_restricted()?;
|
||||
|
||||
if !context.services.oidc.enabled() {
|
||||
return Err!("OIDC is not configured");
|
||||
}
|
||||
|
||||
oidc::process(command, context).await
|
||||
},
|
||||
| Rooms(command) => room::process(command, context).await,
|
||||
| Federation(command) => federation::process(command, context).await,
|
||||
| Server(command) => server::process(command, context).await,
|
||||
|
||||
@@ -1,80 +1,76 @@
|
||||
use conduwuit::{Err, Result, checked};
|
||||
use futures::{FutureExt, StreamExt, TryFutureExt};
|
||||
|
||||
use crate::admin_command;
|
||||
impl crate::Context<'_> {
|
||||
pub(super) async fn register(&self) -> Result {
|
||||
let body = &self.body;
|
||||
let body_len = self.body.len();
|
||||
if body_len < 2
|
||||
|| !body[0].trim().starts_with("```")
|
||||
|| body.last().unwrap_or(&"").trim() != "```"
|
||||
{
|
||||
return Err!("Expected code block in command body. Add --help for details.");
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn register(&self) -> Result {
|
||||
let body = &self.body;
|
||||
let body_len = self.body.len();
|
||||
if body_len < 2
|
||||
|| !body[0].trim().starts_with("```")
|
||||
|| body.last().unwrap_or(&"").trim() != "```"
|
||||
{
|
||||
return Err!("Expected code block in command body. Add --help for details.");
|
||||
let range = 1..checked!(body_len - 1)?;
|
||||
let appservice_config_body = body[range].join("\n");
|
||||
let parsed_config = serde_saphyr::from_str(&appservice_config_body);
|
||||
match parsed_config {
|
||||
| Err(e) => return Err!("Could not parse appservice config as YAML: {e}"),
|
||||
| Ok(registration) => match self
|
||||
.services
|
||||
.appservice
|
||||
.register_appservice(®istration, &appservice_config_body)
|
||||
.await
|
||||
.map(|()| registration.id)
|
||||
{
|
||||
| Err(e) => return Err!("Failed to register appservice: {e}"),
|
||||
| Ok(id) => write!(self, "Appservice registered with ID: {id}"),
|
||||
},
|
||||
}
|
||||
.await
|
||||
}
|
||||
|
||||
let range = 1..checked!(body_len - 1)?;
|
||||
let appservice_config_body = body[range].join("\n");
|
||||
let parsed_config = serde_saphyr::from_str(&appservice_config_body);
|
||||
match parsed_config {
|
||||
| Err(e) => return Err!("Could not parse appservice config as YAML: {e}"),
|
||||
| Ok(registration) => match self
|
||||
pub(super) async fn unregister(&self, appservice_identifier: String) -> Result {
|
||||
match self
|
||||
.services
|
||||
.appservice
|
||||
.register_appservice(®istration, &appservice_config_body)
|
||||
.unregister_appservice(&appservice_identifier)
|
||||
.await
|
||||
.map(|()| registration.id)
|
||||
{
|
||||
| Err(e) => return Err!("Failed to register appservice: {e}"),
|
||||
| Ok(id) => write!(self, "Appservice registered with ID: {id}"),
|
||||
},
|
||||
}
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn unregister(&self, appservice_identifier: String) -> Result {
|
||||
match self
|
||||
.services
|
||||
.appservice
|
||||
.unregister_appservice(&appservice_identifier)
|
||||
| Err(e) => return Err!("Failed to unregister appservice: {e}"),
|
||||
| Ok(()) => write!(self, "Appservice unregistered."),
|
||||
}
|
||||
.await
|
||||
{
|
||||
| Err(e) => return Err!("Failed to unregister appservice: {e}"),
|
||||
| Ok(()) => write!(self, "Appservice unregistered."),
|
||||
}
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn show_appservice_config(&self, appservice_identifier: String) -> Result {
|
||||
match self
|
||||
.services
|
||||
.appservice
|
||||
.get_registration(&appservice_identifier)
|
||||
pub(super) async fn show_appservice_config(&self, appservice_identifier: String) -> Result {
|
||||
match self
|
||||
.services
|
||||
.appservice
|
||||
.get_registration(&appservice_identifier)
|
||||
.await
|
||||
{
|
||||
| None => return Err!("Appservice does not exist."),
|
||||
| Some(config) => {
|
||||
let config_str = serde_saphyr::to_string(&config)?;
|
||||
write!(self, "Config for {appservice_identifier}:\n\n```yaml\n{config_str}\n```")
|
||||
},
|
||||
}
|
||||
.await
|
||||
{
|
||||
| None => return Err!("Appservice does not exist."),
|
||||
| Some(config) => {
|
||||
let config_str = serde_saphyr::to_string(&config)?;
|
||||
write!(self, "Config for {appservice_identifier}:\n\n```yaml\n{config_str}\n```")
|
||||
},
|
||||
}
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn list_registered(&self) -> Result {
|
||||
self.services
|
||||
.appservice
|
||||
.iter_ids()
|
||||
.collect()
|
||||
.map(Ok)
|
||||
.and_then(|appservices: Vec<_>| {
|
||||
let len = appservices.len();
|
||||
let list = appservices.join(", ");
|
||||
write!(self, "Appservices ({len}): {list}")
|
||||
})
|
||||
.await
|
||||
pub(super) async fn list_registered(&self) -> Result {
|
||||
self.services
|
||||
.appservice
|
||||
.iter_ids()
|
||||
.collect()
|
||||
.map(Ok)
|
||||
.and_then(|appservices: Vec<_>| {
|
||||
let len = appservices.len();
|
||||
let list = appservices.join(", ");
|
||||
write!(self, "Appservices ({len}): {list}")
|
||||
})
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
+20
-15
@@ -1,23 +1,28 @@
|
||||
use conduwuit::Result;
|
||||
use conduwuit_macros::implement;
|
||||
use futures::StreamExt;
|
||||
|
||||
use crate::Context;
|
||||
|
||||
#[implement(Context, params = "<'_>")]
|
||||
pub(super) async fn check_all_users(&self) -> Result {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let users = self.services.users.iter().collect::<Vec<_>>().await;
|
||||
let query_time = timer.elapsed();
|
||||
impl Context<'_> {
|
||||
pub(super) async fn check_all_users(&self) -> Result {
|
||||
let timer = tokio::time::Instant::now();
|
||||
let users = self
|
||||
.services
|
||||
.users
|
||||
.stream_local_users()
|
||||
.collect::<Vec<_>>()
|
||||
.await;
|
||||
let query_time = timer.elapsed();
|
||||
|
||||
let total = users.len();
|
||||
let err_count = users.iter().filter(|_user| false).count();
|
||||
let ok_count = users.iter().filter(|_user| true).count();
|
||||
let total = users.len();
|
||||
let err_count = users.iter().filter(|_user| false).count();
|
||||
let ok_count = users.iter().filter(|_user| true).count();
|
||||
|
||||
self.write_str(&format!(
|
||||
"Database query completed in {query_time:?}:\n\n```\nTotal entries: \
|
||||
{total:?}\nFailure/Invalid user count: {err_count:?}\nSuccess/Valid user count: \
|
||||
{ok_count:?}\n```"
|
||||
))
|
||||
.await
|
||||
self.write_str(&format!(
|
||||
"Database query completed in {query_time:?}:\n\n```\nTotal entries: \
|
||||
{total:?}\nFailure/Invalid user count: {err_count:?}\nSuccess/Valid user count: \
|
||||
{ok_count:?}\n```"
|
||||
))
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
+1098
-782
File diff suppressed because it is too large
Load Diff
+23
-1
@@ -17,12 +17,21 @@ pub enum DebugCommand {
|
||||
message: Vec<String>,
|
||||
},
|
||||
|
||||
/// Get the auth_chain of a PDU
|
||||
/// Loads the auth_chain of a PDU, reporting how long it took.
|
||||
GetAuthChain {
|
||||
/// An event ID (the $ character followed by the base64 reference hash)
|
||||
event_id: OwnedEventId,
|
||||
},
|
||||
|
||||
/// Walks & displays the auth_chain of a PDU in a mermaid graph format.
|
||||
///
|
||||
/// This is useless to basically anyone but developers, and is also probably
|
||||
/// slow and memory hungry.
|
||||
ShowAuthChain {
|
||||
/// The root event ID to start walking back from.
|
||||
event_id: OwnedEventId,
|
||||
},
|
||||
|
||||
/// Parse and print a PDU from a JSON
|
||||
///
|
||||
/// The PDU event is only checked for validity and is not added to the
|
||||
@@ -86,6 +95,14 @@ pub enum DebugCommand {
|
||||
room_id: OwnedRoomOrAliasId,
|
||||
},
|
||||
|
||||
/// Gets all the room state events at the specified event.
|
||||
///
|
||||
/// State at event might not be available for some PDUs, such as rejected
|
||||
/// ones.
|
||||
GetStateAt {
|
||||
event_id: OwnedEventId,
|
||||
},
|
||||
|
||||
/// Get and display signing keys from local cache or remote server.
|
||||
GetSigningKeys {
|
||||
server_name: Option<OwnedServerName>,
|
||||
@@ -228,6 +245,11 @@ pub enum DebugCommand {
|
||||
/// Send a test email to the invoking admin's email address
|
||||
SendTestEmail,
|
||||
|
||||
/// Lists room IDs by forward extremity count in descending order
|
||||
RoomsByExtremityCount {
|
||||
page: Option<usize>,
|
||||
},
|
||||
|
||||
/// Developer test stubs
|
||||
#[command(subcommand)]
|
||||
#[allow(non_snake_case)]
|
||||
|
||||
+23
-28
@@ -1,6 +1,6 @@
|
||||
use conduwuit::{Err, Result};
|
||||
|
||||
use crate::{admin_command, admin_command_dispatch};
|
||||
use crate::admin_command_dispatch;
|
||||
|
||||
#[admin_command_dispatch]
|
||||
#[derive(Debug, clap::Subcommand)]
|
||||
@@ -11,37 +11,32 @@ pub enum TesterCommand {
|
||||
Timer,
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[admin_command]
|
||||
async fn panic(&self) -> Result {
|
||||
impl crate::Context<'_> {
|
||||
#[rustfmt::skip]
|
||||
async fn panic(&self) -> Result {
|
||||
panic!("panicked")
|
||||
}
|
||||
|
||||
panic!("panicked")
|
||||
}
|
||||
#[rustfmt::skip]
|
||||
async fn failure(&self) -> Result {
|
||||
Err!("failed")
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[admin_command]
|
||||
async fn failure(&self) -> Result {
|
||||
#[inline(never)]
|
||||
#[rustfmt::skip]
|
||||
async fn tester(&self) -> Result {
|
||||
self.write_str("Ok").await
|
||||
}
|
||||
|
||||
Err!("failed")
|
||||
}
|
||||
#[inline(never)]
|
||||
#[rustfmt::skip]
|
||||
async fn timer(&self) -> Result {
|
||||
let started = std::time::Instant::now();
|
||||
timed(self.body);
|
||||
|
||||
#[inline(never)]
|
||||
#[rustfmt::skip]
|
||||
#[admin_command]
|
||||
async fn tester(&self) -> Result {
|
||||
|
||||
self.write_str("Ok").await
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
#[rustfmt::skip]
|
||||
#[admin_command]
|
||||
async fn timer(&self) -> Result {
|
||||
let started = std::time::Instant::now();
|
||||
timed(self.body);
|
||||
|
||||
let elapsed = started.elapsed();
|
||||
self.write_str(&format!("completed in {elapsed:#?}")).await
|
||||
let elapsed = started.elapsed();
|
||||
self.write_str(&format!("completed in {elapsed:#?}")).await
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
|
||||
+119
-119
@@ -4,131 +4,131 @@
|
||||
use futures::StreamExt;
|
||||
use ruma::{OwnedRoomId, OwnedServerName, OwnedUserId};
|
||||
|
||||
use crate::{admin_command, get_room_info};
|
||||
use crate::get_room_info;
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn disable_room(&self, room_id: OwnedRoomId) -> Result {
|
||||
self.bail_restricted()?;
|
||||
self.services.rooms.metadata.disable_room(&room_id, true);
|
||||
self.write_str("Room disabled.").await
|
||||
}
|
||||
impl crate::Context<'_> {
|
||||
pub(super) async fn disable_room(&self, room_id: OwnedRoomId) -> Result {
|
||||
self.bail_restricted()?;
|
||||
self.services.rooms.metadata.disable_room(&room_id, true);
|
||||
self.write_str("Room disabled.").await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn enable_room(&self, room_id: OwnedRoomId) -> Result {
|
||||
self.bail_restricted()?;
|
||||
self.services.rooms.metadata.disable_room(&room_id, false);
|
||||
self.write_str("Room enabled.").await
|
||||
}
|
||||
pub(super) async fn enable_room(&self, room_id: OwnedRoomId) -> Result {
|
||||
self.bail_restricted()?;
|
||||
self.services.rooms.metadata.disable_room(&room_id, false);
|
||||
self.write_str("Room enabled.").await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn incoming_federation(&self) -> Result {
|
||||
let msg = {
|
||||
let map = self
|
||||
pub(super) async fn incoming_federation(&self) -> Result {
|
||||
let msg = {
|
||||
let map = self
|
||||
.services
|
||||
.rooms
|
||||
.event_handler
|
||||
.federation_handletime
|
||||
.read();
|
||||
|
||||
let mut msg = format!(
|
||||
"Handling {} incoming PDUs across {} active transactions:\n",
|
||||
map.len(),
|
||||
self.services.transactions.txn_active_handle_count()
|
||||
);
|
||||
for (r, (e, i)) in map.iter() {
|
||||
let elapsed = i.elapsed();
|
||||
writeln!(
|
||||
msg,
|
||||
"{} {}: {}m{}s",
|
||||
r,
|
||||
e,
|
||||
elapsed.as_secs() / 60,
|
||||
elapsed.as_secs() % 60
|
||||
)?;
|
||||
}
|
||||
msg
|
||||
};
|
||||
|
||||
self.write_str(&msg).await
|
||||
}
|
||||
|
||||
pub(super) async fn fetch_support_well_known(&self, server_name: OwnedServerName) -> Result {
|
||||
let response = self
|
||||
.services
|
||||
.client
|
||||
.default
|
||||
.get(format!("https://{server_name}/.well-known/matrix/support"))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
let text = response
|
||||
.limit_read_text(
|
||||
self.services
|
||||
.config
|
||||
.max_request_size
|
||||
.try_into()
|
||||
.expect("u64 fits into usize"),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if text.is_empty() {
|
||||
return Err!("Response text/body is empty.");
|
||||
}
|
||||
|
||||
if text.len() > 1500 {
|
||||
return Err!(
|
||||
"Response text/body is over 1500 characters, assuming no support well-known.",
|
||||
);
|
||||
}
|
||||
|
||||
let json: serde_json::Value = match serde_json::from_str(&text) {
|
||||
| Ok(json) => json,
|
||||
| Err(_) => {
|
||||
return Err!("Response text/body is not valid JSON.",);
|
||||
},
|
||||
};
|
||||
|
||||
let pretty_json: String = match serde_json::to_string_pretty(&json) {
|
||||
| Ok(json) => json,
|
||||
| Err(_) => {
|
||||
return Err!("Response text/body is not valid JSON.",);
|
||||
},
|
||||
};
|
||||
|
||||
self.write_str(&format!("Got JSON response:\n\n```json\n{pretty_json}\n```"))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn remote_user_in_rooms(&self, user_id: OwnedUserId) -> Result {
|
||||
if user_id.server_name() == self.services.server.name {
|
||||
return Err!(
|
||||
"User belongs to our server, please use `list-joined-rooms` user admin command \
|
||||
instead.",
|
||||
);
|
||||
}
|
||||
|
||||
let mut rooms: Vec<(OwnedRoomId, u64, String)> = self
|
||||
.services
|
||||
.rooms
|
||||
.event_handler
|
||||
.federation_handletime
|
||||
.read();
|
||||
.state_cache
|
||||
.rooms_joined(&user_id)
|
||||
.then(async |room_id| get_room_info(self.services, &room_id).await)
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
let mut msg = format!(
|
||||
"Handling {} incoming PDUs across {} active transactions:\n",
|
||||
map.len(),
|
||||
self.services.transactions.txn_active_handle_count()
|
||||
);
|
||||
for (r, (e, i)) in map.iter() {
|
||||
let elapsed = i.elapsed();
|
||||
writeln!(msg, "{} {}: {}m{}s", r, e, elapsed.as_secs() / 60, elapsed.as_secs() % 60)?;
|
||||
if rooms.is_empty() {
|
||||
return Err!("User is not in any rooms.");
|
||||
}
|
||||
msg
|
||||
};
|
||||
|
||||
self.write_str(&msg).await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn fetch_support_well_known(&self, server_name: OwnedServerName) -> Result {
|
||||
let response = self
|
||||
.services
|
||||
.client
|
||||
.default
|
||||
.get(format!("https://{server_name}/.well-known/matrix/support"))
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
let text = response
|
||||
.limit_read_text(
|
||||
self.services
|
||||
.config
|
||||
.max_request_size
|
||||
.try_into()
|
||||
.expect("u64 fits into usize"),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if text.is_empty() {
|
||||
return Err!("Response text/body is empty.");
|
||||
}
|
||||
|
||||
if text.len() > 1500 {
|
||||
return Err!(
|
||||
"Response text/body is over 1500 characters, assuming no support well-known.",
|
||||
);
|
||||
}
|
||||
|
||||
let json: serde_json::Value = match serde_json::from_str(&text) {
|
||||
| Ok(json) => json,
|
||||
| Err(_) => {
|
||||
return Err!("Response text/body is not valid JSON.",);
|
||||
},
|
||||
};
|
||||
|
||||
let pretty_json: String = match serde_json::to_string_pretty(&json) {
|
||||
| Ok(json) => json,
|
||||
| Err(_) => {
|
||||
return Err!("Response text/body is not valid JSON.",);
|
||||
},
|
||||
};
|
||||
|
||||
self.write_str(&format!("Got JSON response:\n\n```json\n{pretty_json}\n```"))
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn remote_user_in_rooms(&self, user_id: OwnedUserId) -> Result {
|
||||
if user_id.server_name() == self.services.server.name {
|
||||
return Err!(
|
||||
"User belongs to our server, please use `list-joined-rooms` user admin command \
|
||||
instead.",
|
||||
);
|
||||
}
|
||||
|
||||
if !self.services.users.exists(&user_id).await {
|
||||
return Err!("Remote user does not exist in our database.",);
|
||||
}
|
||||
|
||||
let mut rooms: Vec<(OwnedRoomId, u64, String)> = self
|
||||
.services
|
||||
.rooms
|
||||
.state_cache
|
||||
.rooms_joined(&user_id)
|
||||
.then(|room_id| get_room_info(self.services, room_id))
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
if rooms.is_empty() {
|
||||
return Err!("User is not in any rooms.");
|
||||
}
|
||||
|
||||
rooms.sort_by_key(|r| r.1);
|
||||
rooms.reverse();
|
||||
|
||||
let num = rooms.len();
|
||||
let body = rooms
|
||||
.iter()
|
||||
.map(|(id, members, name)| format!("{id} | Members: {members} | Name: {name}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
self.write_str(&format!("Rooms {user_id} shares with us ({num}):\n```\n{body}\n```",))
|
||||
.await
|
||||
rooms.sort_by_key(|r| r.1);
|
||||
rooms.reverse();
|
||||
|
||||
let num = rooms.len();
|
||||
let body = rooms
|
||||
.iter()
|
||||
.map(|(id, members, name)| format!("{id} | Members: {members} | Name: {name}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
self.write_str(&format!("Rooms {user_id} shares with us ({num}):\n```\n{body}\n```"))
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
+338
-335
@@ -6,403 +6,406 @@
|
||||
warn,
|
||||
};
|
||||
use conduwuit_service::media::Dim;
|
||||
use ruma::{Mxc, OwnedEventId, OwnedMxcUri, OwnedServerName};
|
||||
use ruma::{OwnedEventId, OwnedMxcUri, OwnedServerName};
|
||||
use service::media::mxc::Mxc;
|
||||
|
||||
use crate::{admin_command, utils::parse_local_user_id};
|
||||
use crate::utils::parse_local_user_id;
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn delete(
|
||||
&self,
|
||||
mxc: Option<OwnedMxcUri>,
|
||||
event_id: Option<OwnedEventId>,
|
||||
) -> Result {
|
||||
self.bail_restricted()?;
|
||||
impl crate::Context<'_> {
|
||||
pub(super) async fn delete(
|
||||
&self,
|
||||
mxc: Option<OwnedMxcUri>,
|
||||
event_id: Option<OwnedEventId>,
|
||||
) -> Result {
|
||||
self.bail_restricted()?;
|
||||
|
||||
if event_id.is_some() && mxc.is_some() {
|
||||
return Err!("Please specify either an MXC or an event ID, not both.",);
|
||||
}
|
||||
if event_id.is_some() && mxc.is_some() {
|
||||
return Err!("Please specify either an MXC or an event ID, not both.",);
|
||||
}
|
||||
|
||||
if let Some(mxc) = mxc {
|
||||
trace!("Got MXC URL: {mxc}");
|
||||
self.services
|
||||
.media
|
||||
.delete(&mxc.as_str().try_into()?)
|
||||
.await?;
|
||||
if let Some(mxc) = mxc {
|
||||
trace!("Got MXC URL: {mxc}");
|
||||
self.services
|
||||
.media
|
||||
.delete(&mxc.as_str().try_into()?)
|
||||
.await?;
|
||||
|
||||
return self
|
||||
.write_str("Deleted the MXC from our database and on our filesystem.")
|
||||
.await;
|
||||
}
|
||||
return self
|
||||
.write_str("Deleted the MXC from our database and on our filesystem.")
|
||||
.await;
|
||||
}
|
||||
|
||||
if let Some(event_id) = event_id {
|
||||
trace!("Got event ID to delete media from: {event_id}");
|
||||
if let Some(event_id) = event_id {
|
||||
trace!("Got event ID to delete media from: {event_id}");
|
||||
|
||||
let mut mxc_urls = Vec::with_capacity(4);
|
||||
let mut mxc_urls = Vec::with_capacity(4);
|
||||
|
||||
// parsing the PDU for any MXC URLs begins here
|
||||
match self.services.rooms.timeline.get_pdu_json(&event_id).await {
|
||||
| Ok(event_json) => {
|
||||
if let Some(content_key) = event_json.get("content") {
|
||||
debug!("Event ID has \"content\".");
|
||||
let content_obj = content_key.as_object();
|
||||
// parsing the PDU for any MXC URLs begins here
|
||||
match self.services.rooms.timeline.get_pdu_json(&event_id).await {
|
||||
| Ok(event_json) => {
|
||||
if let Some(content_key) = event_json.get("content") {
|
||||
debug!("Event ID has \"content\".");
|
||||
let content_obj = content_key.as_object();
|
||||
|
||||
if let Some(content) = content_obj {
|
||||
// 1. attempts to parse the "url" key
|
||||
debug!("Attempting to go into \"url\" key for main media file");
|
||||
if let Some(url) = content.get("url") {
|
||||
debug!("Got a URL in the event ID {event_id}: {url}");
|
||||
if let Some(content) = content_obj {
|
||||
// 1. attempts to parse the "url" key
|
||||
debug!("Attempting to go into \"url\" key for main media file");
|
||||
if let Some(url) = content.get("url") {
|
||||
debug!("Got a URL in the event ID {event_id}: {url}");
|
||||
|
||||
if url.to_string().starts_with("\"mxc://") {
|
||||
debug!("Pushing URL {url} to list of MXCs to delete");
|
||||
let final_url = url.to_string().replace('"', "");
|
||||
mxc_urls.push(final_url);
|
||||
} else {
|
||||
info!(
|
||||
"Found a URL in the event ID {event_id} but did not start \
|
||||
with mxc://, ignoring"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. attempts to parse the "info" key
|
||||
debug!("Attempting to go into \"info\" key for thumbnails");
|
||||
if let Some(info_key) = content.get("info") {
|
||||
debug!("Event ID has \"info\".");
|
||||
let info_obj = info_key.as_object();
|
||||
|
||||
if let Some(info) = info_obj {
|
||||
if let Some(thumbnail_url) = info.get("thumbnail_url") {
|
||||
debug!("Found a thumbnail_url in info key: {thumbnail_url}");
|
||||
|
||||
if thumbnail_url.to_string().starts_with("\"mxc://") {
|
||||
debug!(
|
||||
"Pushing thumbnail URL {thumbnail_url} to list of \
|
||||
MXCs to delete"
|
||||
);
|
||||
let final_thumbnail_url =
|
||||
thumbnail_url.to_string().replace('"', "");
|
||||
mxc_urls.push(final_thumbnail_url);
|
||||
} else {
|
||||
info!(
|
||||
"Found a thumbnail URL in the event ID {event_id} \
|
||||
but did not start with mxc://, ignoring"
|
||||
);
|
||||
}
|
||||
if url.to_string().starts_with("\"mxc://") {
|
||||
debug!("Pushing URL {url} to list of MXCs to delete");
|
||||
let final_url = url.to_string().replace('"', "");
|
||||
mxc_urls.push(final_url);
|
||||
} else {
|
||||
info!(
|
||||
"No \"thumbnail_url\" key in \"info\" key, assuming no \
|
||||
thumbnails."
|
||||
"Found a URL in the event ID {event_id} but did not \
|
||||
start with mxc://, ignoring"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. attempts to parse the "file" key
|
||||
debug!("Attempting to go into \"file\" key");
|
||||
if let Some(file_key) = content.get("file") {
|
||||
debug!("Event ID has \"file\".");
|
||||
let file_obj = file_key.as_object();
|
||||
// 2. attempts to parse the "info" key
|
||||
debug!("Attempting to go into \"info\" key for thumbnails");
|
||||
if let Some(info_key) = content.get("info") {
|
||||
debug!("Event ID has \"info\".");
|
||||
let info_obj = info_key.as_object();
|
||||
|
||||
if let Some(file) = file_obj {
|
||||
if let Some(url) = file.get("url") {
|
||||
debug!("Found url in file key: {url}");
|
||||
if let Some(info) = info_obj {
|
||||
if let Some(thumbnail_url) = info.get("thumbnail_url") {
|
||||
debug!(
|
||||
"Found a thumbnail_url in info key: {thumbnail_url}"
|
||||
);
|
||||
|
||||
if url.to_string().starts_with("\"mxc://") {
|
||||
debug!("Pushing URL {url} to list of MXCs to delete");
|
||||
let final_url = url.to_string().replace('"', "");
|
||||
mxc_urls.push(final_url);
|
||||
if thumbnail_url.to_string().starts_with("\"mxc://") {
|
||||
debug!(
|
||||
"Pushing thumbnail URL {thumbnail_url} to list \
|
||||
of MXCs to delete"
|
||||
);
|
||||
let final_thumbnail_url =
|
||||
thumbnail_url.to_string().replace('"', "");
|
||||
mxc_urls.push(final_thumbnail_url);
|
||||
} else {
|
||||
info!(
|
||||
"Found a thumbnail URL in the event ID \
|
||||
{event_id} but did not start with mxc://, \
|
||||
ignoring"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
warn!(
|
||||
"Found a URL in the event ID {event_id} but did not \
|
||||
start with mxc://, ignoring"
|
||||
info!(
|
||||
"No \"thumbnail_url\" key in \"info\" key, assuming \
|
||||
no thumbnails."
|
||||
);
|
||||
}
|
||||
} else {
|
||||
error!("No \"url\" key in \"file\" key.");
|
||||
}
|
||||
}
|
||||
|
||||
// 3. attempts to parse the "file" key
|
||||
debug!("Attempting to go into \"file\" key");
|
||||
if let Some(file_key) = content.get("file") {
|
||||
debug!("Event ID has \"file\".");
|
||||
let file_obj = file_key.as_object();
|
||||
|
||||
if let Some(file) = file_obj {
|
||||
if let Some(url) = file.get("url") {
|
||||
debug!("Found url in file key: {url}");
|
||||
|
||||
if url.to_string().starts_with("\"mxc://") {
|
||||
debug!("Pushing URL {url} to list of MXCs to delete");
|
||||
let final_url = url.to_string().replace('"', "");
|
||||
mxc_urls.push(final_url);
|
||||
} else {
|
||||
warn!(
|
||||
"Found a URL in the event ID {event_id} but did \
|
||||
not start with mxc://, ignoring"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
error!("No \"url\" key in \"file\" key.");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err!(
|
||||
"Event ID does not have a \"content\" key or failed parsing the \
|
||||
event ID JSON.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return Err!(
|
||||
"Event ID does not have a \"content\" key or failed parsing the \
|
||||
event ID JSON.",
|
||||
"Event ID does not have a \"content\" key, this is not a message or \
|
||||
an event type that contains media.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return Err!(
|
||||
"Event ID does not have a \"content\" key, this is not a message or an \
|
||||
event type that contains media.",
|
||||
);
|
||||
},
|
||||
| _ => {
|
||||
return Err!("Event ID does not exist or is not known to us.",);
|
||||
},
|
||||
}
|
||||
|
||||
if mxc_urls.is_empty() {
|
||||
return Err!("Parsed event ID but found no MXC URLs.",);
|
||||
}
|
||||
|
||||
let mut mxc_deletion_count: usize = 0;
|
||||
|
||||
for mxc_url in mxc_urls {
|
||||
match self
|
||||
.services
|
||||
.media
|
||||
.delete(&mxc_url.as_str().try_into()?)
|
||||
.await
|
||||
{
|
||||
| Ok(()) => {
|
||||
debug_info!(
|
||||
"Successfully deleted {mxc_url} from filesystem and database"
|
||||
);
|
||||
mxc_deletion_count = mxc_deletion_count.saturating_add(1);
|
||||
},
|
||||
| Err(e) => {
|
||||
debug_warn!(
|
||||
"Failed to delete {mxc_url}, ignoring error and skipping: {e}"
|
||||
);
|
||||
continue;
|
||||
},
|
||||
}
|
||||
},
|
||||
| _ => {
|
||||
return Err!("Event ID does not exist or is not known to us.",);
|
||||
},
|
||||
}
|
||||
|
||||
return self
|
||||
.write_str(&format!(
|
||||
"Deleted {mxc_deletion_count} total MXCs from our database and the \
|
||||
filesystem from event ID {event_id}."
|
||||
))
|
||||
.await;
|
||||
}
|
||||
|
||||
if mxc_urls.is_empty() {
|
||||
return Err!("Parsed event ID but found no MXC URLs.",);
|
||||
Err!(
|
||||
"Please specify either an MXC using --mxc or an event ID using --event-id of the \
|
||||
message containing an image. See --help for details."
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) async fn delete_list(&self) -> Result {
|
||||
self.bail_restricted()?;
|
||||
|
||||
if self.body.len() < 2
|
||||
|| !self.body[0].trim().starts_with("```")
|
||||
|| self.body.last().unwrap_or(&"").trim() != "```"
|
||||
{
|
||||
return Err!("Expected code block in command body. Add --help for details.",);
|
||||
}
|
||||
|
||||
let mut failed_parsed_mxcs: usize = 0;
|
||||
|
||||
let mxc_list = self
|
||||
.body
|
||||
.to_vec()
|
||||
.drain(1..self.body.len().checked_sub(1).unwrap())
|
||||
.filter_map(|mxc_s| {
|
||||
mxc_s
|
||||
.try_into()
|
||||
.inspect_err(|e| {
|
||||
debug_warn!("Failed to parse user-provided MXC URI: {e}");
|
||||
failed_parsed_mxcs = failed_parsed_mxcs.saturating_add(1);
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.collect::<Vec<Mxc<'_>>>();
|
||||
|
||||
let mut mxc_deletion_count: usize = 0;
|
||||
|
||||
for mxc_url in mxc_urls {
|
||||
match self
|
||||
.services
|
||||
.media
|
||||
.delete(&mxc_url.as_str().try_into()?)
|
||||
.await
|
||||
{
|
||||
for mxc in &mxc_list {
|
||||
trace!(%failed_parsed_mxcs, %mxc_deletion_count, "Deleting MXC {mxc} in bulk");
|
||||
match self.services.media.delete(mxc).await {
|
||||
| Ok(()) => {
|
||||
debug_info!("Successfully deleted {mxc_url} from filesystem and database");
|
||||
debug_info!("Successfully deleted {mxc} from filesystem and database");
|
||||
mxc_deletion_count = mxc_deletion_count.saturating_add(1);
|
||||
},
|
||||
| Err(e) => {
|
||||
debug_warn!("Failed to delete {mxc_url}, ignoring error and skipping: {e}");
|
||||
debug_warn!("Failed to delete {mxc}, ignoring error and skipping: {e}");
|
||||
continue;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return self
|
||||
.write_str(&format!(
|
||||
"Deleted {mxc_deletion_count} total MXCs from our database and the filesystem \
|
||||
from event ID {event_id}."
|
||||
))
|
||||
.await;
|
||||
self.write_str(&format!(
|
||||
"Finished bulk MXC deletion, deleted {mxc_deletion_count} total MXCs from our \
|
||||
database and the filesystem. {failed_parsed_mxcs} MXCs failed to be parsed from \
|
||||
the database.",
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
Err!(
|
||||
"Please specify either an MXC using --mxc or an event ID using --event-id of the \
|
||||
message containing an image. See --help for details."
|
||||
)
|
||||
}
|
||||
pub(super) async fn delete_past_remote_media(
|
||||
&self,
|
||||
duration: String,
|
||||
before: bool,
|
||||
after: bool,
|
||||
yes_i_want_to_delete_local_media: bool,
|
||||
) -> Result {
|
||||
self.bail_restricted()?;
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn delete_list(&self) -> Result {
|
||||
self.bail_restricted()?;
|
||||
|
||||
if self.body.len() < 2
|
||||
|| !self.body[0].trim().starts_with("```")
|
||||
|| self.body.last().unwrap_or(&"").trim() != "```"
|
||||
{
|
||||
return Err!("Expected code block in command body. Add --help for details.",);
|
||||
}
|
||||
|
||||
let mut failed_parsed_mxcs: usize = 0;
|
||||
|
||||
let mxc_list = self
|
||||
.body
|
||||
.to_vec()
|
||||
.drain(1..self.body.len().checked_sub(1).unwrap())
|
||||
.filter_map(|mxc_s| {
|
||||
mxc_s
|
||||
.try_into()
|
||||
.inspect_err(|e| {
|
||||
debug_warn!("Failed to parse user-provided MXC URI: {e}");
|
||||
failed_parsed_mxcs = failed_parsed_mxcs.saturating_add(1);
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.collect::<Vec<Mxc<'_>>>();
|
||||
|
||||
let mut mxc_deletion_count: usize = 0;
|
||||
|
||||
for mxc in &mxc_list {
|
||||
trace!(%failed_parsed_mxcs, %mxc_deletion_count, "Deleting MXC {mxc} in bulk");
|
||||
match self.services.media.delete(mxc).await {
|
||||
| Ok(()) => {
|
||||
debug_info!("Successfully deleted {mxc} from filesystem and database");
|
||||
mxc_deletion_count = mxc_deletion_count.saturating_add(1);
|
||||
},
|
||||
| Err(e) => {
|
||||
debug_warn!("Failed to delete {mxc}, ignoring error and skipping: {e}");
|
||||
continue;
|
||||
},
|
||||
if before && after {
|
||||
return Err!("Please only pick one argument, --before or --after.",);
|
||||
}
|
||||
}
|
||||
assert!(!(before && after), "--before and --after should not be specified together");
|
||||
|
||||
self.write_str(&format!(
|
||||
"Finished bulk MXC deletion, deleted {mxc_deletion_count} total MXCs from our database \
|
||||
and the filesystem. {failed_parsed_mxcs} MXCs failed to be parsed from the database.",
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn delete_past_remote_media(
|
||||
&self,
|
||||
duration: String,
|
||||
before: bool,
|
||||
after: bool,
|
||||
yes_i_want_to_delete_local_media: bool,
|
||||
) -> Result {
|
||||
self.bail_restricted()?;
|
||||
|
||||
if before && after {
|
||||
return Err!("Please only pick one argument, --before or --after.",);
|
||||
}
|
||||
assert!(!(before && after), "--before and --after should not be specified together");
|
||||
|
||||
let direction = if after {
|
||||
TimeDirection::After
|
||||
} else {
|
||||
TimeDirection::Before
|
||||
};
|
||||
|
||||
let time_boundary = parse_timepoint_ago(&duration)?;
|
||||
let deleted_count = self
|
||||
.services
|
||||
.media
|
||||
.delete_all_media_within_timeframe(
|
||||
time_boundary,
|
||||
direction,
|
||||
yes_i_want_to_delete_local_media,
|
||||
)
|
||||
.await?;
|
||||
|
||||
self.write_str(&format!("Deleted {deleted_count} total files.",))
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn delete_all_from_user(&self, username: String) -> Result {
|
||||
let user_id = parse_local_user_id(self.services, &username)?;
|
||||
|
||||
let deleted_count = self.services.media.delete_from_user(&user_id).await?;
|
||||
|
||||
self.write_str(&format!("Deleted {deleted_count} total files.",))
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn delete_all_from_server(
|
||||
&self,
|
||||
server_name: OwnedServerName,
|
||||
yes_i_want_to_delete_local_media: bool,
|
||||
) -> Result {
|
||||
self.bail_restricted()?;
|
||||
|
||||
if server_name == self.services.globals.server_name() && !yes_i_want_to_delete_local_media {
|
||||
return Err!("This command only works for remote media by default.",);
|
||||
}
|
||||
|
||||
let Ok(all_mxcs) = self
|
||||
.services
|
||||
.media
|
||||
.get_all_mxcs()
|
||||
.await
|
||||
.inspect_err(|e| error!("Failed to get MXC URIs from our database: {e}"))
|
||||
else {
|
||||
return Err!("Failed to get MXC URIs from our database",);
|
||||
};
|
||||
|
||||
let mut deleted_count: usize = 0;
|
||||
|
||||
for mxc in all_mxcs {
|
||||
let Ok(mxc_server_name) = mxc.server_name().inspect_err(|e| {
|
||||
debug_warn!(
|
||||
"Failed to parse MXC {mxc} server name from database, ignoring error and \
|
||||
skipping: {e}"
|
||||
);
|
||||
}) else {
|
||||
continue;
|
||||
let direction = if after {
|
||||
TimeDirection::After
|
||||
} else {
|
||||
TimeDirection::Before
|
||||
};
|
||||
|
||||
if mxc_server_name != server_name
|
||||
|| (self.services.globals.server_is_ours(mxc_server_name)
|
||||
&& !yes_i_want_to_delete_local_media)
|
||||
let time_boundary = parse_timepoint_ago(&duration)?;
|
||||
let deleted_count = self
|
||||
.services
|
||||
.media
|
||||
.delete_all_media_within_timeframe(
|
||||
time_boundary,
|
||||
direction,
|
||||
yes_i_want_to_delete_local_media,
|
||||
)
|
||||
.await?;
|
||||
|
||||
self.write_str(&format!("Deleted {deleted_count} total files."))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn delete_all_from_user(&self, username: String) -> Result {
|
||||
let user_id = parse_local_user_id(self.services, &username)?;
|
||||
|
||||
let deleted_count = self.services.media.delete_from_user(&user_id).await?;
|
||||
|
||||
self.write_str(&format!("Deleted {deleted_count} total files."))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn delete_all_from_server(
|
||||
&self,
|
||||
server_name: OwnedServerName,
|
||||
yes_i_want_to_delete_local_media: bool,
|
||||
) -> Result {
|
||||
self.bail_restricted()?;
|
||||
|
||||
if server_name == self.services.globals.server_name() && !yes_i_want_to_delete_local_media
|
||||
{
|
||||
trace!("skipping MXC URI {mxc}");
|
||||
continue;
|
||||
return Err!("This command only works for remote media by default.",);
|
||||
}
|
||||
|
||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||
let Ok(all_mxcs) = self
|
||||
.services
|
||||
.media
|
||||
.get_all_mxcs()
|
||||
.await
|
||||
.inspect_err(|e| error!("Failed to get MXC URIs from our database: {e}"))
|
||||
else {
|
||||
return Err!("Failed to get MXC URIs from our database",);
|
||||
};
|
||||
|
||||
match self.services.media.delete(&mxc).await {
|
||||
| Ok(()) => {
|
||||
deleted_count = deleted_count.saturating_add(1);
|
||||
},
|
||||
| Err(e) => {
|
||||
debug_warn!("Failed to delete {mxc}, ignoring error and skipping: {e}");
|
||||
let mut deleted_count: usize = 0;
|
||||
|
||||
for mxc in all_mxcs {
|
||||
let Ok(mxc_server_name) = mxc.server_name().inspect_err(|e| {
|
||||
debug_warn!(
|
||||
"Failed to parse MXC {mxc} server name from database, ignoring error and \
|
||||
skipping: {e}"
|
||||
);
|
||||
}) else {
|
||||
continue;
|
||||
},
|
||||
};
|
||||
|
||||
if mxc_server_name != server_name
|
||||
|| (self.services.globals.server_is_ours(mxc_server_name)
|
||||
&& !yes_i_want_to_delete_local_media)
|
||||
{
|
||||
trace!("skipping MXC URI {mxc}");
|
||||
continue;
|
||||
}
|
||||
|
||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||
|
||||
match self.services.media.delete(&mxc).await {
|
||||
| Ok(()) => {
|
||||
deleted_count = deleted_count.saturating_add(1);
|
||||
},
|
||||
| Err(e) => {
|
||||
debug_warn!("Failed to delete {mxc}, ignoring error and skipping: {e}");
|
||||
continue;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
self.write_str(&format!("Deleted {deleted_count} total files."))
|
||||
.await
|
||||
}
|
||||
|
||||
self.write_str(&format!("Deleted {deleted_count} total files.",))
|
||||
.await
|
||||
}
|
||||
pub(super) async fn get_file_info(&self, mxc: OwnedMxcUri) -> Result {
|
||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||
let metadata = self.services.media.get_metadata(&mxc).await;
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn get_file_info(&self, mxc: OwnedMxcUri) -> Result {
|
||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||
let metadata = self.services.media.get_metadata(&mxc).await;
|
||||
|
||||
self.write_str(&format!("```\n{metadata:#?}\n```")).await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn get_remote_file(
|
||||
&self,
|
||||
mxc: OwnedMxcUri,
|
||||
server: Option<OwnedServerName>,
|
||||
timeout: u32,
|
||||
) -> Result {
|
||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||
let timeout = Duration::from_millis(timeout.into());
|
||||
let mut result = self
|
||||
.services
|
||||
.media
|
||||
.fetch_remote_content(&mxc, None, server.as_deref(), timeout)
|
||||
.await?;
|
||||
|
||||
// Grab the length of the content before clearing it to not flood the output
|
||||
let len = result.content.as_ref().expect("content").len();
|
||||
result.content.as_mut().expect("content").clear();
|
||||
|
||||
self.write_str(&format!("```\n{result:#?}\nreceived {len} bytes for file content.\n```"))
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn get_remote_thumbnail(
|
||||
&self,
|
||||
mxc: OwnedMxcUri,
|
||||
server: Option<OwnedServerName>,
|
||||
timeout: u32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Result {
|
||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||
let timeout = Duration::from_millis(timeout.into());
|
||||
let dim = Dim::new(width, height, None);
|
||||
let mut result = self
|
||||
.services
|
||||
.media
|
||||
.fetch_remote_thumbnail(&mxc, None, server.as_deref(), timeout, &dim)
|
||||
.await?;
|
||||
|
||||
// Grab the length of the content before clearing it to not flood the output
|
||||
let len = result.content.as_ref().expect("content").len();
|
||||
result.content.as_mut().expect("content").clear();
|
||||
|
||||
self.write_str(&format!("```\n{result:#?}\nreceived {len} bytes for file content.\n```"))
|
||||
.await
|
||||
}
|
||||
|
||||
#[admin_command]
|
||||
pub(super) async fn delete_url_preview(&self, url: Option<String>, all: bool) -> Result {
|
||||
if all {
|
||||
self.services.media.clear_url_previews().await;
|
||||
|
||||
return self.write_str("Deleted all cached URL previews.").await;
|
||||
self.write_str(&format!("```\n{metadata:#?}\n```")).await
|
||||
}
|
||||
|
||||
let url = url.expect("clap enforces url is required unless --all");
|
||||
pub(super) async fn get_remote_file(
|
||||
&self,
|
||||
mxc: OwnedMxcUri,
|
||||
server: Option<OwnedServerName>,
|
||||
timeout: u32,
|
||||
) -> Result {
|
||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||
let timeout = Duration::from_millis(timeout.into());
|
||||
let mut result = self
|
||||
.services
|
||||
.media
|
||||
.fetch_remote_content(&mxc, None, server.as_deref(), timeout)
|
||||
.await?;
|
||||
|
||||
self.services.media.remove_url_preview(&url).await?;
|
||||
// Grab the length of the content before clearing it to not flood the output
|
||||
let len = result.content.as_ref().expect("content").len();
|
||||
result.content.as_mut().expect("content").clear();
|
||||
|
||||
self.write_str(&format!("Deleted cached URL preview for: {url}"))
|
||||
.await
|
||||
self.write_str(&format!("```\n{result:#?}\nreceived {len} bytes for file content.\n```"))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn get_remote_thumbnail(
|
||||
&self,
|
||||
mxc: OwnedMxcUri,
|
||||
server: Option<OwnedServerName>,
|
||||
timeout: u32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Result {
|
||||
let mxc: Mxc<'_> = mxc.as_str().try_into()?;
|
||||
let timeout = Duration::from_millis(timeout.into());
|
||||
let dim = Dim::new(width, height, None);
|
||||
let mut result = self
|
||||
.services
|
||||
.media
|
||||
.fetch_remote_thumbnail(&mxc, None, server.as_deref(), timeout, &dim)
|
||||
.await?;
|
||||
|
||||
// Grab the length of the content before clearing it to not flood the output
|
||||
let len = result.content.as_ref().expect("content").len();
|
||||
result.content.as_mut().expect("content").clear();
|
||||
|
||||
self.write_str(&format!("```\n{result:#?}\nreceived {len} bytes for file content.\n```"))
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn delete_url_preview(&self, url: Option<String>, all: bool) -> Result {
|
||||
if all {
|
||||
self.services.media.clear_url_previews().await;
|
||||
|
||||
return self.write_str("Deleted all cached URL previews.").await;
|
||||
}
|
||||
|
||||
let url = url.expect("clap enforces url is required unless --all");
|
||||
|
||||
self.services.media.remove_url_preview(&url).await?;
|
||||
|
||||
self.write_str(&format!("Deleted cached URL preview for: {url}"))
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user