dscord 0.2.0-alpha.1 → 0.4.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +22 -0
- package/README.md +70 -49
- package/bin/dscord.mjs +5 -4
- package/cordis.patch.yml +3 -0
- package/deploy/synapse/dscord_guard.py +212 -0
- package/dist/admin/assets/index-DXyc54Ce.css +1 -0
- package/dist/admin/assets/index-vZ7hJNEU.js +10 -0
- package/dist/admin/assets/mark-128-C4ed4p0U.png +0 -0
- package/dist/admin/index.html +13 -0
- package/dist/admin/licenses/bundled-dependencies.txt +421 -0
- package/dist/admin/licenses/lucide.txt +43 -0
- package/dist/admin/licenses/ui-foundation.txt +336 -0
- package/dist/admin/theme.js +66 -0
- package/dist/web/assets/apple-touch-icon-C_qAgjR1.png +0 -0
- package/dist/web/assets/common-DGlCXKV6.js +5 -0
- package/dist/web/assets/favicon-32-CEKpvmlx.png +0 -0
- package/dist/web/assets/favicon-6aWeKmcy.ico +0 -0
- package/dist/web/assets/index-62nMLjE0.css +1 -0
- package/dist/web/assets/index-OaWUoxQD.js +55 -0
- package/dist/web/assets/{manifest-eq_1S_IC.webmanifest → manifest-Ca-bIZpP.webmanifest} +2 -8
- package/dist/web/assets/mark-128-C4ed4p0U.png +0 -0
- package/dist/web/assets/rolldown-runtime-XKyaHtl9.js +1 -0
- package/dist/web/client-config.json +3 -0
- package/dist/web/icons/apple-touch-icon.png +0 -0
- package/dist/web/icons/favicon-32.png +0 -0
- package/dist/web/icons/favicon.ico +0 -0
- package/dist/web/icons/icon-192.png +0 -0
- package/dist/web/icons/icon-512.png +0 -0
- package/dist/web/icons/mark-128.png +0 -0
- package/dist/web/index.html +9 -7
- package/dist/web/licenses/bundled-dependencies.txt +2452 -0
- package/dist/web/licenses/ui-foundation.txt +336 -0
- package/dist/web/manifest.webmanifest +2 -8
- package/dist/web/sw.js +233 -79
- package/dist/web/theme.js +27 -5
- package/dsh-connect/KERNEL.md +70 -0
- package/dsh-connect/client.js +28821 -0
- package/dsh-connect/controller.mjs +450 -0
- package/dsh-connect/decision-settings.mjs +66 -0
- package/dsh-connect/index.mjs +40 -0
- package/dsh-connect/kernel-runtime.mjs +120 -0
- package/dsh-connect/models.mjs +64 -0
- package/dsh-connect/native-bots.mjs +97 -0
- package/dsh-connect/native-bridge.mjs +482 -0
- package/dsh-connect/native-connections.mjs +160 -0
- package/dsh-connect/native-team.mjs +63 -0
- package/dsh-connect/processes.mjs +119 -0
- package/dsh-connect/work-core.mjs +573 -0
- package/dsh-plugin/README.md +32 -31
- package/dsh-plugin/index.mjs +18 -11
- package/dsh-plugin/model-profile.mjs +73 -0
- package/dsh-plugin/runtime-dependencies-lock.json +696 -6
- package/dsh-plugin/runtime-dependencies-pnpm-lock.yaml +489 -0
- package/dsh-plugin/runtime-dependencies.json +7 -2
- package/dsh-plugin/runtime-rules.mjs +9 -0
- package/dsh-plugin/runtime.mjs +330 -45
- package/dsh-plugin/scoped-work.mjs +73 -0
- package/dsh-plugin/work-files.mjs +24 -5
- package/memory/contacts.mjs +36 -0
- package/memory/ingress.mjs +57 -0
- package/memory/model-options.mjs +9 -0
- package/memory/native.mjs +374 -0
- package/memory/observation-policy.mjs +67 -0
- package/memory/ombre.mjs +165 -0
- package/memory/panel.mjs +88 -0
- package/memory/review.mjs +90 -0
- package/memory/service.mjs +429 -0
- package/memory/snapshot-context.mjs +95 -0
- package/memory/source-query.mjs +87 -0
- package/memory/store.mjs +339 -0
- package/memory/views.mjs +304 -0
- package/memory//345/244/215/347/224/250/344/270/216/350/277/220/350/241/214.md +47 -0
- package/memory//345/275/223/345/211/215/344/270/212/344/270/213/346/226/207/344/270/216/345/233/236/351/241/276.md +73 -0
- package/package.json +46 -6
- package/scripts/admin.mjs +41 -0
- package/scripts/central-init.mjs +39 -0
- package/scripts/dsh-node.mjs +92 -54
- package/scripts/memory-setup.mjs +21 -0
- package/scripts/runtime-config.mjs +55 -23
- package/scripts/runtime-dependencies.mjs +79 -0
- package/scripts/server-admin.mjs +25 -3
- package/scripts/server-bootstrap.mjs +55 -9
- package/scripts/server-init.mjs +88 -10
- package/scripts/service.mjs +39 -14
- package/service/ombre/LICENSE +21 -0
- package/service/ombre/SOURCE.json +15 -0
- package/service/ombre/controlled_store.py +295 -0
- package/service/ombre/harrier_profile.py +320 -0
- package/service/ombre/protocol.py +67 -0
- package/service/ombre/requirements.lock.txt +1100 -0
- package/service/ombre/semantic.py +449 -0
- package/service/ombre/service.py +204 -0
- package/src/accounts.mjs +373 -0
- package/src/admin-auth.mjs +246 -0
- package/src/admin.mjs +285 -0
- package/src/attachment-access.mjs +57 -0
- package/src/attention.mjs +140 -0
- package/src/bot-node.mjs +839 -48
- package/src/bot-work-policy.mjs +77 -0
- package/src/bot-work.mjs +276 -0
- package/src/budget.mjs +22 -7
- package/src/collaboration.mjs +178 -0
- package/src/contact-book.mjs +206 -0
- package/src/core/attachment-routes.mjs +43 -0
- package/src/core/bot-routes.mjs +37 -0
- package/src/core/node-routes.mjs +51 -0
- package/src/core/room-routes.mjs +285 -0
- package/src/core/router.mjs +31 -0
- package/src/core/session-routes.mjs +58 -0
- package/src/core.mjs +139 -356
- package/src/decision-provider.mjs +128 -0
- package/src/file-formats.mjs +1 -1
- package/src/governance.mjs +350 -0
- package/src/http-json.mjs +19 -0
- package/src/identity.mjs +100 -0
- package/src/kernel-control.mjs +374 -0
- package/src/kernel-node-client.mjs +162 -0
- package/src/matrix-client.mjs +70 -13
- package/src/media.mjs +50 -28
- package/src/mentions.mjs +28 -8
- package/src/message-context.mjs +105 -0
- package/src/model-config.mjs +51 -0
- package/src/model-failure.mjs +5 -0
- package/src/native-bot-catalog.mjs +75 -0
- package/src/native-request.mjs +42 -0
- package/src/node-auth.mjs +60 -0
- package/src/node-delivery.mjs +2 -2
- package/src/node-files.mjs +29 -7
- package/src/node-store.mjs +581 -13
- package/src/node-work.mjs +43 -0
- package/src/participant-labels.mjs +9 -0
- package/src/push.mjs +23 -3
- package/src/room-media.mjs +122 -0
- package/src/synapse-control.mjs +409 -0
- package/src/tasks.mjs +19 -5
- package/src/verified-media.mjs +283 -0
- package/src/web-mode.mjs +9 -0
- package/vendor/ds-bot/NOTICE +86 -0
- package/vendor/ds-bot/UPSTREAM.json +83 -5
- package/vendor/ds-bot/client.js +15079 -9868
- package/vendor/ds-bot/index.js +6 -2
- package/vendor/ds-bot/package.json +9 -4
- package/vendor/ds-bot/src/host/approvals.js +54 -7
- package/vendor/ds-bot/src/host/browser/script-child.js +136 -0
- package/vendor/ds-bot/src/host/browser/script-runner.js +77 -0
- package/vendor/ds-bot/src/host/browser/script.js +1 -0
- package/vendor/ds-bot/src/host/browser/session.js +19 -29
- package/vendor/ds-bot/src/host/capabilities.js +6 -3
- package/vendor/ds-bot/src/host/channel.js +214 -54
- package/vendor/ds-bot/src/host/computer/catalog.js +91 -0
- package/vendor/ds-bot/src/host/computer/index.js +1213 -0
- package/vendor/ds-bot/src/host/computer/leases.js +71 -0
- package/vendor/ds-bot/src/host/connectors/catalog.js +96 -0
- package/vendor/ds-bot/src/host/connectors/gateway.js +264 -0
- package/vendor/ds-bot/src/host/connectors/index.js +863 -0
- package/vendor/ds-bot/src/host/connectors/mail/index.js +613 -0
- package/vendor/ds-bot/src/host/connectors/mail/presets.js +23 -0
- package/vendor/ds-bot/src/host/connectors/mail/transport.js +306 -0
- package/vendor/ds-bot/src/host/connectors/oauth.js +191 -0
- package/vendor/ds-bot/src/host/constants.js +1 -1
- package/vendor/ds-bot/src/host/context-failure.js +11 -0
- package/vendor/ds-bot/src/host/delivery.js +6 -3
- package/vendor/ds-bot/src/host/feed.js +10 -3
- package/vendor/ds-bot/src/host/groups.js +58 -16
- package/vendor/ds-bot/src/host/home-lock.js +103 -35
- package/vendor/ds-bot/src/host/im/format.js +190 -0
- package/vendor/ds-bot/src/host/im/index.js +943 -0
- package/vendor/ds-bot/src/host/im/platforms/dingtalk.js +207 -0
- package/vendor/ds-bot/src/host/im/platforms/discord.js +234 -0
- package/vendor/ds-bot/src/host/im/platforms/feishu.js +352 -0
- package/vendor/ds-bot/src/host/im/platforms/index.js +12 -0
- package/vendor/ds-bot/src/host/im/platforms/qq.js +216 -0
- package/vendor/ds-bot/src/host/im/platforms/slack.js +210 -0
- package/vendor/ds-bot/src/host/im/platforms/telegram.js +249 -0
- package/vendor/ds-bot/src/host/im/platforms/wecom.js +217 -0
- package/vendor/ds-bot/src/host/im/platforms/weixin.js +256 -0
- package/vendor/ds-bot/src/host/images.js +22 -7
- package/vendor/ds-bot/src/host/learning.js +27 -7
- package/vendor/ds-bot/src/host/legacy.mjs +4 -0
- package/vendor/ds-bot/src/host/local-agents/acp.js +232 -0
- package/vendor/ds-bot/src/host/local-agents/adapter.js +540 -0
- package/vendor/ds-bot/src/host/local-agents/claude.js +179 -0
- package/vendor/ds-bot/src/host/local-agents/codex.js +175 -0
- package/vendor/ds-bot/src/host/local-agents/discover.js +99 -0
- package/vendor/ds-bot/src/host/local-agents/engines.js +65 -0
- package/vendor/ds-bot/src/host/local-agents/index.js +235 -0
- package/vendor/ds-bot/src/host/local-agents/jsonrpc.js +111 -0
- package/vendor/ds-bot/src/host/local-agents/mcp.js +141 -0
- package/vendor/ds-bot/src/host/memory.js +14 -1
- package/vendor/ds-bot/src/host/message-source.js +56 -0
- package/vendor/ds-bot/src/host/parts.js +259 -48
- package/vendor/ds-bot/src/host/providers.js +142 -17
- package/vendor/ds-bot/src/host/resume.js +54 -4
- package/vendor/ds-bot/src/host/roster.js +25 -3
- package/vendor/ds-bot/src/host/schedules.js +101 -7
- package/vendor/ds-bot/src/host/steward.js +2 -1
- package/vendor/ds-bot/src/host/store.js +52 -5
- package/vendor/ds-bot/src/host/tools.js +102 -15
- package/vendor/ds-bot/src/host/turns.js +28 -5
- package/vendor/ds-bot/src/host/update.js +3 -0
- package/vendor/ds-bot/src/shared/im-platforms.js +86 -0
- package//346/250/241/345/236/213/351/205/215/347/275/256/344/270/216/350/277/201/347/247/273.md +66 -0
- package/dist/web/assets/apple-touch-icon-BVvy03qx.png +0 -0
- package/dist/web/assets/icon-C8lhqe5n.svg +0 -6
- package/dist/web/assets/index-D2MsIF_C.js +0 -20
- package/dist/web/assets/index-DpwihgYi.css +0 -1
- package/dist/web/icons/icon.svg +0 -6
- package/vendor/ds-bot/README.md +0 -258
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
DSCord
|
|
2
|
+
Copyright 2026 DSCord contributors
|
|
3
|
+
|
|
4
|
+
DSCord-specific source code and documentation in this package are licensed
|
|
5
|
+
under the Apache License, Version 2.0. See LICENSE.
|
|
6
|
+
|
|
7
|
+
Third-party components retain their own licenses and notices.
|
|
8
|
+
|
|
9
|
+
DS-Bot
|
|
10
|
+
The vendored kernel is based on DS-Bot 0.3.1 by Fei2411 and the DS Bot
|
|
11
|
+
contributors, under Apache-2.0. See vendor/ds-bot/LICENSE,
|
|
12
|
+
vendor/ds-bot/NOTICE and vendor/ds-bot/UPSTREAM.json for provenance,
|
|
13
|
+
additional third-party notices and the DSCord modifications.
|
|
14
|
+
|
|
15
|
+
Ombre
|
|
16
|
+
The optional memory service is distributed under its MIT license.
|
|
17
|
+
See service/ombre/LICENSE and service/ombre/SOURCE.json.
|
|
18
|
+
|
|
19
|
+
Web interfaces
|
|
20
|
+
Bundled UI and icon notices are in web/licenses/ and the corresponding
|
|
21
|
+
licenses/ directory in each prebuilt interface. Other installed dependencies
|
|
22
|
+
retain the licenses provided by their respective packages.
|
package/README.md
CHANGED
|
@@ -1,87 +1,108 @@
|
|
|
1
|
-
# DSCord
|
|
1
|
+
# DSCord 0.4.0-alpha.2 安装与连接
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> [!WARNING]
|
|
4
|
+
> **实验性项目。** DSCord 目前是实验性质的项目,接口、数据格式和行为随时可能变化,不保证兼容旧版本。项目不考虑安全问题,因此将别人加入到你的服务器当中的时候,请确认你有线下找他喝茶的能力。
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
DSCord 的 npm 包包含 Core、预构建网页/PWA、Matrix 适配器和 DSCord Bot 内核。完整服务器源码发行包另含 Compose 部署文件;同一部署的 Core、客户端和节点使用同一发行版本。
|
|
7
|
+
|
|
8
|
+
本指南对应预发布版本 0.4.0-alpha.2,npm 安装包由该版本的 GitHub Release 提供。Node 支持范围由 [package.json](package.json) 声明为 `>=24.19.0 <25`。Bot 宿主固定使用 DSH `0.2.2-rc.1` 的 SDK 契约,见[内核说明](dsh-connect/KERNEL.md)。Docker 服务器无需在宿主另装 Node。
|
|
6
9
|
|
|
7
10
|
## 安装
|
|
8
11
|
|
|
12
|
+
从发行页下载 `dscord-0.4.0-alpha.2.tgz` 后,可在 DSH 的 `Plugins → Add plugin` 中安装并启用 `dscord`,再登录服务器连接 Bot。发行页同时提供 `SHA256SUMS` 校验文件。[下载发行包](https://github.com/MixGeekers/dscord/releases/tag/ds-group-v0.4.0-alpha.2)
|
|
13
|
+
|
|
14
|
+
全局安装 CLI 用于服务器与独立节点管理。npm 可以直接安装同一发行包,安装后核对 `dscord --version`。
|
|
15
|
+
|
|
9
16
|
```sh
|
|
10
|
-
npm install --global dscord
|
|
17
|
+
npm install --global https://github.com/MixGeekers/dscord/releases/download/ds-group-v0.4.0-alpha.2/dscord-0.4.0-alpha.2.tgz
|
|
11
18
|
dscord --help
|
|
12
19
|
dscord --version
|
|
13
20
|
```
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
Core、CLI 和 DSH 插件使用同一发行版本。已有全局安装可用上述命令升级。
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
以下步骤使用 Docker 运行独立 Synapse,核心通过 Node 启动。先安装 Docker Engine 并启动 Docker 服务。
|
|
24
|
+
从源码构建 npm 包,在 `apps/ds-group/` 中执行:
|
|
20
25
|
|
|
21
26
|
```sh
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export DS_GROUP_MATRIX_URL=http://127.0.0.1:18008
|
|
25
|
-
export DS_GROUP_MATRIX_PUBLIC_URL=http://localhost:18008
|
|
26
|
-
export DS_GROUP_PUBLIC_URL=http://localhost:18100
|
|
27
|
-
dscord init
|
|
28
|
-
|
|
29
|
-
docker run --detach --name dscord-synapse \
|
|
30
|
-
--user "$(id -u):$(id -g)" \
|
|
31
|
-
--publish 127.0.0.1:18008:8008 \
|
|
32
|
-
--mount "type=bind,source=$DS_GROUP_DATA_DIR/synapse,target=/data" \
|
|
33
|
-
ghcr.io/element-hq/synapse@sha256:f0df87cff259872637b4b5e5174b9977e5e3046dd421505407803b5e45c5f842
|
|
27
|
+
npm ci --ignore-scripts
|
|
28
|
+
npm run npm:pack
|
|
34
29
|
```
|
|
35
30
|
|
|
36
|
-
|
|
31
|
+
该版本默认生成 `.local/npm-release/dscord-0.4.0-alpha.2.tgz`,仍应核对命令实际输出的版本、路径与校验值。构建需要开发依赖,运行已提供的预构建包不需要重新构建界面。
|
|
32
|
+
|
|
33
|
+
## 部署服务器
|
|
34
|
+
|
|
35
|
+
完整服务器采用[Compose 部署指南](https://github.com/MixGeekers/dscord/blob/ds-group-v0.4.0-alpha.2/apps/ds-group/deploy/README.md),先配置自己的 Matrix 身份域、公开地址和持久存储。npm CLI 不代替 Synapse 或反向代理。需要 `dscord server`、初始化及节点导入等命令时,在各终端保持同一个绝对数据路径:
|
|
37
36
|
|
|
38
37
|
```sh
|
|
39
|
-
dscord
|
|
40
|
-
dscord
|
|
41
|
-
dscord server
|
|
38
|
+
export DS_GROUP_DATA_DIR="$HOME/.local/share/dscord-server"
|
|
39
|
+
dscord --version
|
|
42
40
|
```
|
|
43
41
|
|
|
44
|
-
|
|
42
|
+
上面的路径可自行替换。npm CLI 未设置数据目录时使用当前工作目录下的 `.dscord/`,在不同目录执行管理命令可能选中不同实例。
|
|
43
|
+
|
|
44
|
+
## 在 DSH 中连接
|
|
45
|
+
|
|
46
|
+
1. 准备固定基线的官方 CLI,或提供相同 SDK 服务的 DSH 宿主。CLI 可执行 `npm install --global @deepseek-ai/dsh@0.2.2-rc.1`。在 DSH 中配置自己的业务模型和凭据。
|
|
47
|
+
2. 安装同版本 `dscord` 插件并启用,打开左侧 **DSCord**,填写 Core/PWA 的地址和自己的账号,登录服务器。
|
|
48
|
+
3. 在“此节点的 Bot”中创建 Bot,选择 DSH 已配置的模型并填写职责,或选择已有 Bot。纯读取状态不会自动创建 Bot。
|
|
49
|
+
4. 点击“加入服务器”。网页“我的 Bot → 添加已有 Bot”也可选择这个已连接节点公布的 Bot。两端必须是同一账号。
|
|
50
|
+
5. 在网页打开私聊或邀请 Bot 进入需要参与的群聊。参与方式、来源记忆和当前工作在 Bot 设置中查看。
|
|
45
51
|
|
|
46
|
-
|
|
52
|
+
地址、账号、模型和路径都来自部署者自己的配置。业务模型没有指定服务商;自然参与的单独判断服务是可选功能,见[模型与参与设置](模型配置与迁移.md)。
|
|
47
53
|
|
|
48
|
-
|
|
54
|
+
Core 提供的 Matrix 公开地址必须能从节点访问。一个连接页使用一个归属账号,可管理多个本机 Bot。连接数据默认位于实际 DSH home 的 `dscord/<profile>/`,Bot 数据保留在该 home 的 `bot/`。断开服务器、退出连接页或关闭网页不删除本机 Bot;DSH 停止后,Bot 也无法继续工作。
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
## 升级和已有 Bot
|
|
57
|
+
|
|
58
|
+
先备份服务器数据和各 DSH Bot home,再停止当前工作并升级到同一发行版本。已有 `ds-bot` 插件必须先停用,DSCord 才能在同一目录接管;同时启动两个内核会报冲突。接管会保存迁移快照,保留 Bot 与 Session 身份。[生命周期与迁移](https://github.com/MixGeekers/dscord/blob/ds-group-v0.4.0-alpha.2/apps/ds-group/deploy/kernel-runtime.md)
|
|
59
|
+
|
|
60
|
+
旧服务器 Bot 可在连接页绑定已有本机 Bot,保留 Matrix 身份;两套独立 Session 或记忆不会自动合并。已有原生绑定的 Bot 应从所属 DSH 连接,导出其配置不能在另一台机器创建身份副本。
|
|
61
|
+
|
|
62
|
+
## 独立 CLI 节点
|
|
63
|
+
|
|
64
|
+
CLI 适用于没有已有原生绑定的独立 Bot。已绑定本机 Bot 的成员必须使用所属 DSH 的连接页,启动器会拒绝复制其身份。
|
|
65
|
+
|
|
66
|
+
在服务器端导出目标 Bot,参数使用完整 Matrix ID 中 `@` 与 `:` 之间的账号部分,不是显示名称:
|
|
51
67
|
|
|
52
68
|
```sh
|
|
69
|
+
BOT_ACCOUNT='your-bot-account'
|
|
53
70
|
umask 077
|
|
54
|
-
dscord admin export-node
|
|
71
|
+
dscord admin export-node "$BOT_ACCOUNT" > bot-node.json
|
|
55
72
|
```
|
|
56
73
|
|
|
57
|
-
|
|
74
|
+
将私有导出文件传到节点,安装同版本程序和兼容 DSH。以下数据目录、空闲端口、来源 profile 和 `provider/model-id` 均须替换为自己的配置:
|
|
58
75
|
|
|
59
76
|
```sh
|
|
60
|
-
|
|
61
|
-
export DS_GROUP_DATA_DIR="$HOME/.local/share/dscord-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
export
|
|
65
|
-
|
|
77
|
+
BOT_ACCOUNT='your-bot-account'
|
|
78
|
+
export DS_GROUP_DATA_DIR="$HOME/.local/share/dscord-nodes/$BOT_ACCOUNT"
|
|
79
|
+
export DS_GROUP_BRIDGE_PORT=23100
|
|
80
|
+
dscord admin import-node bot-node.json "$DS_GROUP_DATA_DIR"
|
|
81
|
+
export DS_GROUP_DSH_SOURCE_HOME='/absolute/path/to/your/dsh-home'
|
|
82
|
+
export DS_GROUP_DSH_SOURCE_PROFILE='your-profile'
|
|
83
|
+
export DS_GROUP_MODEL='provider/model-id'
|
|
84
|
+
dscord service up "$BOT_ACCOUNT"
|
|
66
85
|
```
|
|
67
86
|
|
|
68
|
-
|
|
87
|
+
若 DSH 不在 PATH,用 `DS_GROUP_DSH_CLI` 指定可执行文件、`DS_GROUP_DSH_RUNTIME` 指定实际 SDK 包根或安装前缀。启动器按锁准备自己的运行依赖,不需要手工复制库目录。独立节点会复制所选模型配置所需的凭据到私有数据目录,行为与直接复用宿主的图形节点不同。[模型与凭据](模型配置与迁移.md)
|
|
88
|
+
|
|
89
|
+
在同一组环境变量下停止:
|
|
69
90
|
|
|
70
91
|
```sh
|
|
71
|
-
dscord service down
|
|
72
|
-
dscord dsh stop
|
|
92
|
+
dscord service down "$BOT_ACCOUNT"
|
|
93
|
+
dscord dsh stop "$BOT_ACCOUNT"
|
|
73
94
|
```
|
|
74
95
|
|
|
75
|
-
|
|
96
|
+
每个 Bot 同时运行一个节点,每个独立节点使用自己的数据目录和桥接端口。Linux 常驻服务见 [systemd](https://github.com/MixGeekers/dscord/blob/ds-group-v0.4.0-alpha.2/apps/ds-group/deploy/systemd/README.md)。
|
|
97
|
+
|
|
98
|
+
## 存储与组件
|
|
99
|
+
|
|
100
|
+
附件默认使用 Synapse 本地媒体目录,可选 S3-compatible 后端。[存储配置](https://github.com/MixGeekers/dscord/blob/ds-group-v0.4.0-alpha.2/apps/ds-group/deploy/storage/README.md)说明远端对象、缓存和备份关系;已有云盘扫描与历史迁移不是自动功能。
|
|
101
|
+
|
|
102
|
+
`dscord server` 运行 Core/PWA,`init` 和 `bootstrap` 初始化服务器,`admin` 管理导出与导入,`node` 运行 Matrix 适配器,`dsh` 管理独立宿主,`service` 管理本机进程,`path` 显示安装目录。
|
|
76
103
|
|
|
77
|
-
|
|
104
|
+
DS-Bot 的 Apache-2.0 LICENSE 与 NOTICE 位于 `vendor/ds-bot/`,界面图标许可随 `dist/web/licenses/` 提供。
|
|
78
105
|
|
|
79
|
-
|
|
80
|
-
- `dscord init` 与 `dscord bootstrap` 管理服务器初始化和 Matrix 成员。
|
|
81
|
-
- `dscord admin` 读取账号、导出和导入节点配置。
|
|
82
|
-
- `dscord node` 运行 Matrix 适配进程。
|
|
83
|
-
- `dscord dsh` 管理独立 DSH 运行时。
|
|
84
|
-
- `dscord service` 管理本机核心和 Bot 进程。
|
|
85
|
-
- `dscord path` 显示安装目录。
|
|
106
|
+
## 许可证
|
|
86
107
|
|
|
87
|
-
|
|
108
|
+
DSCord 自有代码和文档采用 Apache-2.0。安装包包含本体许可及第三方声明,预构建界面的依赖许可位于各自的 `licenses/` 目录。[LICENSE](LICENSE) · [NOTICE](NOTICE)
|
package/bin/dscord.mjs
CHANGED
|
@@ -17,8 +17,8 @@ const entries = new Map([
|
|
|
17
17
|
]);
|
|
18
18
|
const help = `Usage: dscord <command> [arguments]
|
|
19
19
|
|
|
20
|
-
server Run the core server
|
|
21
|
-
init
|
|
20
|
+
server Run the core server in its configured web mode
|
|
21
|
+
init [--web-mode MODE] Prepare configuration (MODE: bundled or api-only)
|
|
22
22
|
bootstrap Register initial members on the configured Synapse
|
|
23
23
|
admin <arguments> Manage server credentials and node exports
|
|
24
24
|
node <arguments> Run a Matrix Bot adapter
|
|
@@ -29,6 +29,7 @@ const help = `Usage: dscord <command> [arguments]
|
|
|
29
29
|
help Show this help
|
|
30
30
|
|
|
31
31
|
DS_GROUP_DATA_DIR defaults to .dscord in the current directory.
|
|
32
|
+
DS_GROUP_WEB_MODE overrides web hosting; init persists it in core-config.json.
|
|
32
33
|
`;
|
|
33
34
|
|
|
34
35
|
async function run() {
|
|
@@ -48,10 +49,10 @@ async function run() {
|
|
|
48
49
|
const entry = entries.get(command);
|
|
49
50
|
if (!entry) throw new Error(`Unknown command "${command}". Run dscord help.`);
|
|
50
51
|
if (command === 'service' && ['up', 'down', 'restart'].includes(args[0]) && !args[1]) {
|
|
51
|
-
throw new Error('Choose a service component explicitly: all, core,
|
|
52
|
+
throw new Error('Choose a service component explicitly: all, core, or a local Bot account name.');
|
|
52
53
|
}
|
|
53
54
|
if (command === 'dsh' && args.length < 2) {
|
|
54
|
-
throw new Error('Use dscord dsh <start|run|stop|status|prepare> <
|
|
55
|
+
throw new Error('Use dscord dsh <start|run|stop|status|prepare> <bot-account>.');
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
const env = { ...process.env };
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"""DSCord private federation admission. Pinned and tested with Synapse 1.164.2.
|
|
2
|
+
|
|
3
|
+
Policy is local authority, never instructions from room content. Each host enforces
|
|
4
|
+
its own local users and rooms; remote message history is not rewritten by this module.
|
|
5
|
+
"""
|
|
6
|
+
import json
|
|
7
|
+
import hashlib
|
|
8
|
+
import os
|
|
9
|
+
import time
|
|
10
|
+
import uuid
|
|
11
|
+
|
|
12
|
+
from synapse.module_api import NOT_SPAM
|
|
13
|
+
from synapse.module_api.errors import Codes, SynapseError
|
|
14
|
+
from twisted.web.resource import Resource
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def domain(user_id):
|
|
18
|
+
return user_id.split(":", 1)[1] if isinstance(user_id, str) and ":" in user_id else None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def acl_host(server):
|
|
22
|
+
return server.split(":", 1)[0]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class GovernanceStatus(Resource):
|
|
26
|
+
isLeaf = True
|
|
27
|
+
|
|
28
|
+
def __init__(self, guard):
|
|
29
|
+
super().__init__()
|
|
30
|
+
self.guard = guard
|
|
31
|
+
|
|
32
|
+
def render_GET(self, request):
|
|
33
|
+
self.guard.policy()
|
|
34
|
+
request.setHeader(b"Content-Type", b"application/json")
|
|
35
|
+
request.setHeader(b"Cache-Control", b"no-store")
|
|
36
|
+
if self.guard.document["error"]:
|
|
37
|
+
request.setResponseCode(503)
|
|
38
|
+
return json.dumps(self.guard.document).encode("utf-8")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class GovernanceModule:
|
|
42
|
+
def __init__(self, config, api):
|
|
43
|
+
self.api = api
|
|
44
|
+
self.config = config
|
|
45
|
+
self.server = config["server_name"]
|
|
46
|
+
self.boot_id = str(uuid.uuid4())
|
|
47
|
+
with open(__file__, "rb") as stream:
|
|
48
|
+
self.source_hash = hashlib.sha256(stream.read()).hexdigest()
|
|
49
|
+
self.last_status = None
|
|
50
|
+
self.document = {}
|
|
51
|
+
api.register_spam_checker_callbacks(user_may_invite=self.may_invite, user_may_join_room=self.may_join)
|
|
52
|
+
api.register_third_party_rules_callbacks(check_event_allowed=self.check_event, on_create_room=self.on_create)
|
|
53
|
+
api.register_web_resource("/_synapse/client/dscord-governance/status", GovernanceStatus(self))
|
|
54
|
+
self.policy()
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def parse_config(config):
|
|
58
|
+
for key in ("server_name", "policy_path", "status_path"):
|
|
59
|
+
if not isinstance(config.get(key), str) or not config[key]:
|
|
60
|
+
raise ValueError("Missing DSCord guard " + key)
|
|
61
|
+
return config
|
|
62
|
+
|
|
63
|
+
def policy(self):
|
|
64
|
+
try:
|
|
65
|
+
with open(self.config["policy_path"], encoding="utf-8") as stream:
|
|
66
|
+
policy = json.load(stream)
|
|
67
|
+
if policy["schemaVersion"] != 1 or policy["serverName"] != self.server or not isinstance(policy["revision"], int):
|
|
68
|
+
raise ValueError("Invalid policy identity")
|
|
69
|
+
# Fail closed on missing or malformed configuration, including local operations.
|
|
70
|
+
for key in ("partners", "members", "rooms", "botPolicies"):
|
|
71
|
+
if not isinstance(policy[key], list):
|
|
72
|
+
raise ValueError("Invalid policy collection")
|
|
73
|
+
revision = policy["revision"]
|
|
74
|
+
error = None
|
|
75
|
+
except (OSError, ValueError, KeyError, TypeError):
|
|
76
|
+
policy = None
|
|
77
|
+
revision = None
|
|
78
|
+
error = "POLICY_UNAVAILABLE"
|
|
79
|
+
status = (revision, error)
|
|
80
|
+
self.document = {"serverName": self.server, "bootId": self.boot_id, "synapseVersion": "1.164.2",
|
|
81
|
+
"sourceSha256": self.source_hash,
|
|
82
|
+
"liveRevision": revision, "loadedPartners": self.config.get("loaded_partners", []),
|
|
83
|
+
"observedAt": int(time.time() * 1000), "error": error}
|
|
84
|
+
if status != self.last_status:
|
|
85
|
+
self.last_status = status
|
|
86
|
+
filename = self.config["status_path"]
|
|
87
|
+
temporary = filename + "." + str(os.getpid()) + ".tmp"
|
|
88
|
+
try:
|
|
89
|
+
with open(temporary, "w", encoding="utf-8") as stream:
|
|
90
|
+
json.dump(self.document, stream)
|
|
91
|
+
os.chmod(temporary, 0o600)
|
|
92
|
+
os.replace(temporary, filename)
|
|
93
|
+
except OSError:
|
|
94
|
+
self.last_status = None
|
|
95
|
+
return policy
|
|
96
|
+
|
|
97
|
+
def partners(self, policy):
|
|
98
|
+
return [row["serverName"] for row in policy["partners"] if row.get("enabled") is True]
|
|
99
|
+
|
|
100
|
+
def admitted(self, policy, user):
|
|
101
|
+
return domain(user) == self.server or domain(user) in self.partners(policy) and any(
|
|
102
|
+
row["id"] == user and row.get("enabled") is True for row in policy["members"])
|
|
103
|
+
|
|
104
|
+
def rule(self, policy, room):
|
|
105
|
+
return next((row for row in policy["rooms"] if row["roomId"] == room), None)
|
|
106
|
+
|
|
107
|
+
def allowed(self, policy, room, user):
|
|
108
|
+
row = self.rule(policy, room)
|
|
109
|
+
return bool(row and row.get("enabled") is True and self.admitted(policy, user)
|
|
110
|
+
and (user in row.get("memberIds", []) or domain(user) == self.server and row["authority"] == self.server))
|
|
111
|
+
|
|
112
|
+
async def may_invite(self, inviter, invitee, room_id):
|
|
113
|
+
policy = self.policy()
|
|
114
|
+
if not policy:
|
|
115
|
+
return Codes.FORBIDDEN
|
|
116
|
+
if domain(inviter) == self.server and domain(invitee) == self.server:
|
|
117
|
+
return NOT_SPAM
|
|
118
|
+
# Both participating servers approve the exact room and external identity.
|
|
119
|
+
if not self.admitted(policy, inviter) or not self.admitted(policy, invitee):
|
|
120
|
+
return Codes.FORBIDDEN
|
|
121
|
+
row = self.rule(policy, room_id)
|
|
122
|
+
if not row or not row.get("enabled"):
|
|
123
|
+
return Codes.FORBIDDEN
|
|
124
|
+
if row["authority"] == self.server:
|
|
125
|
+
return NOT_SPAM if self.allowed(policy, room_id, invitee) else Codes.FORBIDDEN
|
|
126
|
+
return NOT_SPAM if row["authority"] in self.partners(policy) and invitee in row.get("memberIds", []) else Codes.FORBIDDEN
|
|
127
|
+
|
|
128
|
+
async def may_join(self, user, room, is_invited):
|
|
129
|
+
policy = self.policy()
|
|
130
|
+
if not policy:
|
|
131
|
+
return Codes.FORBIDDEN
|
|
132
|
+
row = self.rule(policy, room)
|
|
133
|
+
if row:
|
|
134
|
+
return NOT_SPAM if self.allowed(policy, room, user) and (row["authority"] == self.server or is_invited) else Codes.FORBIDDEN
|
|
135
|
+
# Legacy local-only rooms retain their membership behavior. Foreign rooms
|
|
136
|
+
# need an explicit policy even when a user bypasses Core and calls /join.
|
|
137
|
+
state = await self.api.get_room_state(room, [("m.room.create", "")])
|
|
138
|
+
creator = state.get(("m.room.create", ""))
|
|
139
|
+
return NOT_SPAM if creator and domain(creator.sender) == self.server and domain(user) == self.server else Codes.FORBIDDEN
|
|
140
|
+
|
|
141
|
+
async def on_create(self, requester, request_content, is_requester_admin):
|
|
142
|
+
policy = self.policy()
|
|
143
|
+
if not policy:
|
|
144
|
+
raise SynapseError(403, "DSCord admission policy unavailable", Codes.FORBIDDEN)
|
|
145
|
+
for target in request_content.get("invite", []):
|
|
146
|
+
if domain(target) != self.server:
|
|
147
|
+
# Register the room rule first, then invite. There is no stable
|
|
148
|
+
# room ID before creation to which an external grant can bind.
|
|
149
|
+
raise SynapseError(403, "Create the room, approve its rule, then invite external members", Codes.FORBIDDEN)
|
|
150
|
+
states = [row for row in request_content.get("initial_state", []) if row.get("type") not in ("m.room.server_acl", "m.room.join_rules")]
|
|
151
|
+
states.extend([{"type": "m.room.server_acl", "state_key": "", "content": {
|
|
152
|
+
"allow": sorted({acl_host(self.server), self.server}), "deny": [], "allow_ip_literals": False}},
|
|
153
|
+
{"type": "m.room.join_rules", "state_key": "", "content": {"join_rule": "invite"}}])
|
|
154
|
+
request_content["initial_state"] = states
|
|
155
|
+
request_content["visibility"] = "private"
|
|
156
|
+
|
|
157
|
+
async def check_event(self, event, state_events):
|
|
158
|
+
policy = self.policy()
|
|
159
|
+
# Incoming federated history is governed by Matrix auth; rejecting its
|
|
160
|
+
# messages here would create divergent room DAGs. Revoke through bans.
|
|
161
|
+
if domain(event.sender) != self.server:
|
|
162
|
+
if event.type == "m.room.member" and event.content.get("membership") in ("invite", "join"):
|
|
163
|
+
creator = state_events.get(("m.room.create", ""))
|
|
164
|
+
row = self.rule(policy, event.room_id) if policy else None
|
|
165
|
+
local_authority = row["authority"] == self.server if row else creator and domain(creator.sender) == self.server
|
|
166
|
+
if local_authority:
|
|
167
|
+
return bool(policy and self.allowed(policy, event.room_id, event.state_key)), None
|
|
168
|
+
return True, None
|
|
169
|
+
if not policy:
|
|
170
|
+
return False, None
|
|
171
|
+
row = self.rule(policy, event.room_id)
|
|
172
|
+
creator = state_events.get(("m.room.create", ""))
|
|
173
|
+
local_room = row["authority"] == self.server if row else not creator or domain(creator.sender) == self.server
|
|
174
|
+
if not local_room and event.type not in ("m.room.member", "m.room.server_acl", "m.room.join_rules", "org.dscord.work_policy"):
|
|
175
|
+
return bool(row and self.allowed(policy, event.room_id, event.sender)), None
|
|
176
|
+
if event.type == "m.room.member":
|
|
177
|
+
membership = event.content.get("membership")
|
|
178
|
+
if membership in ("leave", "ban"):
|
|
179
|
+
return True, None
|
|
180
|
+
if domain(event.state_key) != self.server:
|
|
181
|
+
return self.allowed(policy, event.room_id, event.state_key), None
|
|
182
|
+
if not local_room:
|
|
183
|
+
return self.allowed(policy, event.room_id, event.state_key), None
|
|
184
|
+
if event.type == "m.room.join_rules":
|
|
185
|
+
return event.content.get("join_rule") == "invite", None
|
|
186
|
+
if event.type == "m.room.server_acl":
|
|
187
|
+
# Host patterns enforce the specification. The full local name also
|
|
188
|
+
# satisfies Synapse 1.164.2's validator, which checks the port-bearing
|
|
189
|
+
# local server name without stripping its port.
|
|
190
|
+
permitted = {acl_host(self.server), self.server}
|
|
191
|
+
if row and row.get("enabled"):
|
|
192
|
+
if row["authority"] == self.server or row["authority"] in self.partners(policy):
|
|
193
|
+
permitted.add(acl_host(row["authority"]))
|
|
194
|
+
permitted.add(row["authority"])
|
|
195
|
+
for user in row["memberIds"]:
|
|
196
|
+
if self.admitted(policy, user):
|
|
197
|
+
permitted.update({acl_host(domain(user)), domain(user)})
|
|
198
|
+
allow = event.content.get("allow", [])
|
|
199
|
+
return bool(allow and set(allow).issubset(permitted) and event.content.get("allow_ip_literals") is False), None
|
|
200
|
+
if event.type == "org.dscord.work_policy":
|
|
201
|
+
if not local_room:
|
|
202
|
+
return False, None
|
|
203
|
+
expected = {"schemaVersion": 1, "roomId": event.room_id,
|
|
204
|
+
"revision": policy["revision"], "authority": self.server,
|
|
205
|
+
"issuerId": "@dscord-control:" + self.server,
|
|
206
|
+
"localMemberAdmission": "matrix-membership",
|
|
207
|
+
"enabled": bool(row and row.get("enabled")),
|
|
208
|
+
"botIds": [user for user in row.get("botIds", []) if self.admitted(policy, user)] if row else [],
|
|
209
|
+
"tools": row.get("tools", []) if row else [],
|
|
210
|
+
"memberIds": [user for user in row.get("memberIds", []) if self.admitted(policy, user)] if row else []}
|
|
211
|
+
return event.sender == expected["issuerId"] and event.content == expected, None
|
|
212
|
+
return True, None
|