summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2024-01-05 13:39:31 +0100
committerLibravatar GitHub <noreply@github.com>2024-01-05 13:39:31 +0100
commitd5e3996a18ee37fc4bdf5718632d3d19ac7a8c1b (patch)
tree7b8df224893611c77cadc847c2fd8d7ec239b636 /internal
parent[bugfix] fix check for closed poll to account for non-zero closed time but in... (diff)
downloadgotosocial-d5e3996a18ee37fc4bdf5718632d3d19ac7a8c1b.tar.xz
[feature] Parse instance descriptors as markdown, show T&C on /about (#2481)
* [feature] Parse instance descriptors as markdown, show T&C on /about * lint * remove unnecessary nullzero tags
Diffstat (limited to 'internal')
-rw-r--r--internal/api/client/instance/instancepatch_test.go50
-rw-r--r--internal/api/model/instancev1.go6
-rw-r--r--internal/api/model/instancev2.go4
-rw-r--r--internal/db/bundb/migrations/20231227110845_instance_description_updates.go64
-rw-r--r--internal/gtsmodel/instance.go7
-rw-r--r--internal/processing/instance.go228
-rw-r--r--internal/processing/processor.go17
-rw-r--r--internal/typeutils/internaltofrontend.go53
-rw-r--r--internal/typeutils/internaltofrontend_test.go15
9 files changed, 311 insertions, 133 deletions
diff --git a/internal/api/client/instance/instancepatch_test.go b/internal/api/client/instance/instancepatch_test.go
index 420bcd79e..936d6efd9 100644
--- a/internal/api/client/instance/instancepatch_test.go
+++ b/internal/api/client/instance/instancepatch_test.go
@@ -78,8 +78,10 @@ func (suite *InstancePatchTestSuite) TestInstancePatch1() {
"uri": "http://localhost:8080",
"account_domain": "localhost:8080",
"title": "Example Instance",
- "description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "description": "<p>Here's a fuller description of the GoToSocial testrig instance.</p><p>This instance is for testing purposes only. It doesn't federate at all. Go check out <a href=\"https://github.com/superseriousbusiness/gotosocial/tree/main/testrig\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/tree/main/testrig</a> and <a href=\"https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing</a></p><p>Users on this instance:</p><ul><li><span class=\"h-card\"><a href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>admin</span></a></span> (admin!).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span> (posts about turtles, we don't know why).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@the_mighty_zork\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>the_mighty_zork</span></a></span> (who knows).</li></ul><p>If you need to edit the models for the testrig, you can do so at <code>internal/testmodels.go</code>.</p>",
+ "description_text": "Here's a fuller description of the GoToSocial testrig instance.\n\nThis instance is for testing purposes only. It doesn't federate at all. Go check out https://github.com/superseriousbusiness/gotosocial/tree/main/testrig and https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\n\nUsers on this instance:\n\n- @admin (admin!).\n- @1happyturtle (posts about turtles, we don't know why).\n- @the_mighty_zork (who knows).\n\nIf you need to edit the models for the testrig, you can do so at `+"`"+`internal/testmodels.go`+"`"+`.",
"short_description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "short_description_text": "This is the GoToSocial testrig. It doesn't federate or anything.\n\nWhen the testrig is shut down, all data on it will be deleted.\n\nDon't use this in production!",
"email": "someone@example.org",
"version": "0.0.0-testrig",
"languages": [
@@ -173,7 +175,9 @@ func (suite *InstancePatchTestSuite) TestInstancePatch1() {
"id": "01GP3DFY9XQ1TJMZT5BGAZPXX3",
"text": "Do crime"
}
- ]
+ ],
+ "terms": "<p>This is where a list of terms and conditions might go.</p><p>For example:</p><p>If you want to sign up on this instance, you oughta know that we:</p><ol><li>Will sell your data to whoever offers.</li><li>Secure the server with password <code>password</code> wherever possible.</li></ol>",
+ "terms_text": "This is where a list of terms and conditions might go.\n\nFor example:\n\nIf you want to sign up on this instance, you oughta know that we:\n\n1. Will sell your data to whoever offers.\n2. Secure the server with password `+"`"+`password`+"`"+` wherever possible."
}`, dst.String())
}
@@ -195,8 +199,10 @@ func (suite *InstancePatchTestSuite) TestInstancePatch2() {
"uri": "http://localhost:8080",
"account_domain": "localhost:8080",
"title": "Geoff's Instance",
- "description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "description": "<p>Here's a fuller description of the GoToSocial testrig instance.</p><p>This instance is for testing purposes only. It doesn't federate at all. Go check out <a href=\"https://github.com/superseriousbusiness/gotosocial/tree/main/testrig\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/tree/main/testrig</a> and <a href=\"https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing</a></p><p>Users on this instance:</p><ul><li><span class=\"h-card\"><a href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>admin</span></a></span> (admin!).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span> (posts about turtles, we don't know why).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@the_mighty_zork\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>the_mighty_zork</span></a></span> (who knows).</li></ul><p>If you need to edit the models for the testrig, you can do so at <code>internal/testmodels.go</code>.</p>",
+ "description_text": "Here's a fuller description of the GoToSocial testrig instance.\n\nThis instance is for testing purposes only. It doesn't federate at all. Go check out https://github.com/superseriousbusiness/gotosocial/tree/main/testrig and https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\n\nUsers on this instance:\n\n- @admin (admin!).\n- @1happyturtle (posts about turtles, we don't know why).\n- @the_mighty_zork (who knows).\n\nIf you need to edit the models for the testrig, you can do so at `+"`"+`internal/testmodels.go`+"`"+`.",
"short_description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "short_description_text": "This is the GoToSocial testrig. It doesn't federate or anything.\n\nWhen the testrig is shut down, all data on it will be deleted.\n\nDon't use this in production!",
"email": "admin@example.org",
"version": "0.0.0-testrig",
"languages": [
@@ -290,13 +296,15 @@ func (suite *InstancePatchTestSuite) TestInstancePatch2() {
"id": "01GP3DFY9XQ1TJMZT5BGAZPXX3",
"text": "Do crime"
}
- ]
+ ],
+ "terms": "<p>This is where a list of terms and conditions might go.</p><p>For example:</p><p>If you want to sign up on this instance, you oughta know that we:</p><ol><li>Will sell your data to whoever offers.</li><li>Secure the server with password <code>password</code> wherever possible.</li></ol>",
+ "terms_text": "This is where a list of terms and conditions might go.\n\nFor example:\n\nIf you want to sign up on this instance, you oughta know that we:\n\n1. Will sell your data to whoever offers.\n2. Secure the server with password `+"`"+`password`+"`"+` wherever possible."
}`, dst.String())
}
func (suite *InstancePatchTestSuite) TestInstancePatch3() {
code, b := suite.instancePatch("", "", map[string][]string{
- "short_description": {"<p>This is some html, which is <em>allowed</em> in short descriptions.</p>"},
+ "short_description": {"This is some html, which is <em>allowed</em> in short descriptions."},
})
if expectedCode := http.StatusOK; code != expectedCode {
@@ -312,8 +320,10 @@ func (suite *InstancePatchTestSuite) TestInstancePatch3() {
"uri": "http://localhost:8080",
"account_domain": "localhost:8080",
"title": "GoToSocial Testrig Instance",
- "description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "description": "<p>Here's a fuller description of the GoToSocial testrig instance.</p><p>This instance is for testing purposes only. It doesn't federate at all. Go check out <a href=\"https://github.com/superseriousbusiness/gotosocial/tree/main/testrig\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/tree/main/testrig</a> and <a href=\"https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing</a></p><p>Users on this instance:</p><ul><li><span class=\"h-card\"><a href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>admin</span></a></span> (admin!).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span> (posts about turtles, we don't know why).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@the_mighty_zork\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>the_mighty_zork</span></a></span> (who knows).</li></ul><p>If you need to edit the models for the testrig, you can do so at <code>internal/testmodels.go</code>.</p>",
+ "description_text": "Here's a fuller description of the GoToSocial testrig instance.\n\nThis instance is for testing purposes only. It doesn't federate at all. Go check out https://github.com/superseriousbusiness/gotosocial/tree/main/testrig and https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\n\nUsers on this instance:\n\n- @admin (admin!).\n- @1happyturtle (posts about turtles, we don't know why).\n- @the_mighty_zork (who knows).\n\nIf you need to edit the models for the testrig, you can do so at `+"`"+`internal/testmodels.go`+"`"+`.",
"short_description": "<p>This is some html, which is <em>allowed</em> in short descriptions.</p>",
+ "short_description_text": "This is some html, which is <em>allowed</em> in short descriptions.",
"email": "admin@example.org",
"version": "0.0.0-testrig",
"languages": [
@@ -407,7 +417,9 @@ func (suite *InstancePatchTestSuite) TestInstancePatch3() {
"id": "01GP3DFY9XQ1TJMZT5BGAZPXX3",
"text": "Do crime"
}
- ]
+ ],
+ "terms": "<p>This is where a list of terms and conditions might go.</p><p>For example:</p><p>If you want to sign up on this instance, you oughta know that we:</p><ol><li>Will sell your data to whoever offers.</li><li>Secure the server with password <code>password</code> wherever possible.</li></ol>",
+ "terms_text": "This is where a list of terms and conditions might go.\n\nFor example:\n\nIf you want to sign up on this instance, you oughta know that we:\n\n1. Will sell your data to whoever offers.\n2. Secure the server with password `+"`"+`password`+"`"+` wherever possible."
}`, dst.String())
}
@@ -480,8 +492,10 @@ func (suite *InstancePatchTestSuite) TestInstancePatch6() {
"uri": "http://localhost:8080",
"account_domain": "localhost:8080",
"title": "GoToSocial Testrig Instance",
- "description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "description": "<p>Here's a fuller description of the GoToSocial testrig instance.</p><p>This instance is for testing purposes only. It doesn't federate at all. Go check out <a href=\"https://github.com/superseriousbusiness/gotosocial/tree/main/testrig\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/tree/main/testrig</a> and <a href=\"https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing</a></p><p>Users on this instance:</p><ul><li><span class=\"h-card\"><a href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>admin</span></a></span> (admin!).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span> (posts about turtles, we don't know why).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@the_mighty_zork\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>the_mighty_zork</span></a></span> (who knows).</li></ul><p>If you need to edit the models for the testrig, you can do so at <code>internal/testmodels.go</code>.</p>",
+ "description_text": "Here's a fuller description of the GoToSocial testrig instance.\n\nThis instance is for testing purposes only. It doesn't federate at all. Go check out https://github.com/superseriousbusiness/gotosocial/tree/main/testrig and https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\n\nUsers on this instance:\n\n- @admin (admin!).\n- @1happyturtle (posts about turtles, we don't know why).\n- @the_mighty_zork (who knows).\n\nIf you need to edit the models for the testrig, you can do so at `+"`"+`internal/testmodels.go`+"`"+`.",
"short_description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "short_description_text": "This is the GoToSocial testrig. It doesn't federate or anything.\n\nWhen the testrig is shut down, all data on it will be deleted.\n\nDon't use this in production!",
"email": "",
"version": "0.0.0-testrig",
"languages": [
@@ -575,7 +589,9 @@ func (suite *InstancePatchTestSuite) TestInstancePatch6() {
"id": "01GP3DFY9XQ1TJMZT5BGAZPXX3",
"text": "Do crime"
}
- ]
+ ],
+ "terms": "<p>This is where a list of terms and conditions might go.</p><p>For example:</p><p>If you want to sign up on this instance, you oughta know that we:</p><ol><li>Will sell your data to whoever offers.</li><li>Secure the server with password <code>password</code> wherever possible.</li></ol>",
+ "terms_text": "This is where a list of terms and conditions might go.\n\nFor example:\n\nIf you want to sign up on this instance, you oughta know that we:\n\n1. Will sell your data to whoever offers.\n2. Secure the server with password `+"`"+`password`+"`"+` wherever possible."
}`, dst.String())
}
@@ -619,8 +635,10 @@ func (suite *InstancePatchTestSuite) TestInstancePatch8() {
"uri": "http://localhost:8080",
"account_domain": "localhost:8080",
"title": "GoToSocial Testrig Instance",
- "description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "description": "<p>Here's a fuller description of the GoToSocial testrig instance.</p><p>This instance is for testing purposes only. It doesn't federate at all. Go check out <a href=\"https://github.com/superseriousbusiness/gotosocial/tree/main/testrig\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/tree/main/testrig</a> and <a href=\"https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing</a></p><p>Users on this instance:</p><ul><li><span class=\"h-card\"><a href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>admin</span></a></span> (admin!).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span> (posts about turtles, we don't know why).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@the_mighty_zork\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>the_mighty_zork</span></a></span> (who knows).</li></ul><p>If you need to edit the models for the testrig, you can do so at <code>internal/testmodels.go</code>.</p>",
+ "description_text": "Here's a fuller description of the GoToSocial testrig instance.\n\nThis instance is for testing purposes only. It doesn't federate at all. Go check out https://github.com/superseriousbusiness/gotosocial/tree/main/testrig and https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\n\nUsers on this instance:\n\n- @admin (admin!).\n- @1happyturtle (posts about turtles, we don't know why).\n- @the_mighty_zork (who knows).\n\nIf you need to edit the models for the testrig, you can do so at `+"`"+`internal/testmodels.go`+"`"+`.",
"short_description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "short_description_text": "This is the GoToSocial testrig. It doesn't federate or anything.\n\nWhen the testrig is shut down, all data on it will be deleted.\n\nDon't use this in production!",
"email": "admin@example.org",
"version": "0.0.0-testrig",
"languages": [
@@ -716,7 +734,9 @@ func (suite *InstancePatchTestSuite) TestInstancePatch8() {
"id": "01GP3DFY9XQ1TJMZT5BGAZPXX3",
"text": "Do crime"
}
- ]
+ ],
+ "terms": "<p>This is where a list of terms and conditions might go.</p><p>For example:</p><p>If you want to sign up on this instance, you oughta know that we:</p><ol><li>Will sell your data to whoever offers.</li><li>Secure the server with password <code>password</code> wherever possible.</li></ol>",
+ "terms_text": "This is where a list of terms and conditions might go.\n\nFor example:\n\nIf you want to sign up on this instance, you oughta know that we:\n\n1. Will sell your data to whoever offers.\n2. Secure the server with password `+"`"+`password`+"`"+` wherever possible."
}`, dst.String())
// extra bonus: check the v2 model thumbnail after the patch
@@ -773,8 +793,10 @@ func (suite *InstancePatchTestSuite) TestInstancePatch9() {
"uri": "http://localhost:8080",
"account_domain": "localhost:8080",
"title": "GoToSocial Testrig Instance",
- "description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "description": "<p>Here's a fuller description of the GoToSocial testrig instance.</p><p>This instance is for testing purposes only. It doesn't federate at all. Go check out <a href=\"https://github.com/superseriousbusiness/gotosocial/tree/main/testrig\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/tree/main/testrig</a> and <a href=\"https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing</a></p><p>Users on this instance:</p><ul><li><span class=\"h-card\"><a href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>admin</span></a></span> (admin!).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span> (posts about turtles, we don't know why).</li><li><span class=\"h-card\"><a href=\"http://localhost:8080/@the_mighty_zork\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>the_mighty_zork</span></a></span> (who knows).</li></ul><p>If you need to edit the models for the testrig, you can do so at <code>internal/testmodels.go</code>.</p>",
+ "description_text": "Here's a fuller description of the GoToSocial testrig instance.\n\nThis instance is for testing purposes only. It doesn't federate at all. Go check out https://github.com/superseriousbusiness/gotosocial/tree/main/testrig and https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\n\nUsers on this instance:\n\n- @admin (admin!).\n- @1happyturtle (posts about turtles, we don't know why).\n- @the_mighty_zork (who knows).\n\nIf you need to edit the models for the testrig, you can do so at `+"`"+`internal/testmodels.go`+"`"+`.",
"short_description": "<p>This is the GoToSocial testrig. It doesn't federate or anything.</p><p>When the testrig is shut down, all data on it will be deleted.</p><p>Don't use this in production!</p>",
+ "short_description_text": "This is the GoToSocial testrig. It doesn't federate or anything.\n\nWhen the testrig is shut down, all data on it will be deleted.\n\nDon't use this in production!",
"email": "admin@example.org",
"version": "0.0.0-testrig",
"languages": [
@@ -868,7 +890,9 @@ func (suite *InstancePatchTestSuite) TestInstancePatch9() {
"id": "01GP3DFY9XQ1TJMZT5BGAZPXX3",
"text": "Do crime"
}
- ]
+ ],
+ "terms": "<p>This is where a list of terms and conditions might go.</p><p>For example:</p><p>If you want to sign up on this instance, you oughta know that we:</p><ol><li>Will sell your data to whoever offers.</li><li>Secure the server with password <code>password</code> wherever possible.</li></ol>",
+ "terms_text": "This is where a list of terms and conditions might go.\n\nFor example:\n\nIf you want to sign up on this instance, you oughta know that we:\n\n1. Will sell your data to whoever offers.\n2. Secure the server with password `+"`"+`password`+"`"+` wherever possible."
}`, dst.String())
}
diff --git a/internal/api/model/instancev1.go b/internal/api/model/instancev1.go
index 2e5fef123..bec719941 100644
--- a/internal/api/model/instancev1.go
+++ b/internal/api/model/instancev1.go
@@ -38,12 +38,16 @@ type InstanceV1 struct {
//
// This should be displayed on the 'about' page for an instance.
Description string `json:"description"`
+ // Raw (unparsed) version of description.
+ DescriptionText string `json:"description_text,omitempty"`
// A shorter description of the instance.
//
// Should be HTML formatted, but might be plaintext.
//
// This should be displayed on the instance splash/landing page.
ShortDescription string `json:"short_description"`
+ // Raw (unparsed) version of short description.
+ ShortDescriptionText string `json:"short_description_text,omitempty"`
// An email address that may be used for inquiries.
// example: admin@example.org
Email string `json:"email"`
@@ -92,6 +96,8 @@ type InstanceV1 struct {
Rules []InstanceRule `json:"rules"`
// Terms and conditions for accounts on this instance.
Terms string `json:"terms,omitempty"`
+ // Raw (unparsed) version of terms.
+ TermsRaw string `json:"terms_text,omitempty"`
}
// InstanceV1URLs models instance-relevant URLs for client application consumption.
diff --git a/internal/api/model/instancev2.go b/internal/api/model/instancev2.go
index 6af657813..dda9033b4 100644
--- a/internal/api/model/instancev2.go
+++ b/internal/api/model/instancev2.go
@@ -49,6 +49,8 @@ type InstanceV2 struct {
//
// This should be displayed on the 'about' page for an instance.
Description string `json:"description"`
+ // Raw (unparsed) version of description.
+ DescriptionText string `json:"description_text,omitempty"`
// Basic anonymous usage data for this instance.
Usage InstanceV2Usage `json:"usage"`
// An image used to represent this instance.
@@ -66,6 +68,8 @@ type InstanceV2 struct {
Rules []InstanceRule `json:"rules"`
// Terms and conditions for accounts on this instance.
Terms string `json:"terms,omitempty"`
+ // Raw (unparsed) version of terms.
+ TermsText string `json:"terms_text,omitempty"`
}
// Usage data for this instance.
diff --git a/internal/db/bundb/migrations/20231227110845_instance_description_updates.go b/internal/db/bundb/migrations/20231227110845_instance_description_updates.go
new file mode 100644
index 000000000..94914ff55
--- /dev/null
+++ b/internal/db/bundb/migrations/20231227110845_instance_description_updates.go
@@ -0,0 +1,64 @@
+// GoToSocial
+// Copyright (C) GoToSocial Authors admin@gotosocial.org
+// SPDX-License-Identifier: AGPL-3.0-or-later
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package migrations
+
+import (
+ "context"
+ "strings"
+
+ "github.com/uptrace/bun"
+)
+
+func init() {
+ up := func(ctx context.Context, db *bun.DB) error {
+ return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error {
+ columns := []string{
+ "short_description_text",
+ "description_text",
+ "terms_text",
+ }
+
+ for _, column := range columns {
+ _, err := tx.ExecContext(ctx,
+ "ALTER TABLE ? ADD COLUMN ? TEXT",
+ bun.Ident("instances"), bun.Ident(column),
+ )
+ if err != nil {
+ e := err.Error()
+ if !(strings.Contains(e, "already exists") ||
+ strings.Contains(e, "duplicate column name") ||
+ strings.Contains(e, "SQLSTATE 42701")) {
+ return err
+ }
+ }
+ }
+
+ return nil
+ })
+ }
+
+ down := func(ctx context.Context, db *bun.DB) error {
+ return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error {
+ return nil
+ })
+ }
+
+ if err := Migrations.Register(up, down); err != nil {
+ panic(err)
+ }
+}
diff --git a/internal/gtsmodel/instance.go b/internal/gtsmodel/instance.go
index 6d572f519..027d8fba4 100644
--- a/internal/gtsmodel/instance.go
+++ b/internal/gtsmodel/instance.go
@@ -31,8 +31,11 @@ type Instance struct {
DomainBlockID string `bun:"type:CHAR(26),nullzero"` // ID of any existing domain block for this instance in the database
DomainBlock *DomainBlock `bun:"rel:belongs-to"` // Domain block corresponding to domainBlockID
ShortDescription string `bun:""` // Short description of this instance
- Description string `bun:""` // Longer description of this instance
- Terms string `bun:""` // Terms and conditions of this instance
+ ShortDescriptionText string `bun:""` // Raw text version of short description (before parsing).
+ Description string `bun:""` // Longer description of this instance.
+ DescriptionText string `bun:""` // Raw text version of long description (before parsing).
+ Terms string `bun:""` // Terms and conditions of this instance.
+ TermsText string `bun:""` // Raw text version of terms (before parsing).
ContactEmail string `bun:""` // Contact email address for this instance
ContactAccountUsername string `bun:",nullzero"` // Username of the contact account for this instance
ContactAccountID string `bun:"type:CHAR(26),nullzero"` // Contact account ID in the database for this instance
diff --git a/internal/processing/instance.go b/internal/processing/instance.go
index caf2b9fc1..a93936425 100644
--- a/internal/processing/instance.go
+++ b/internal/processing/instance.go
@@ -33,15 +33,6 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/validate"
)
-func (p *Processor) getThisInstance(ctx context.Context) (*gtsmodel.Instance, error) {
- instance, err := p.state.DB.GetInstance(ctx, config.GetHost())
- if err != nil {
- return nil, err
- }
-
- return instance, nil
-}
-
func (p *Processor) InstanceGetV1(ctx context.Context) (*apimodel.InstanceV1, gtserror.WithCode) {
i, err := p.getThisInstance(ctx)
if err != nil {
@@ -146,67 +137,55 @@ func (p *Processor) InstanceGetRules(ctx context.Context) ([]apimodel.InstanceRu
}
func (p *Processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSettingsUpdateRequest) (*apimodel.InstanceV1, gtserror.WithCode) {
- // fetch the instance entry from the db for processing
- host := config.GetHost()
-
- instance, err := p.state.DB.GetInstance(ctx, host)
+ // Fetch this instance from the db for processing.
+ instance, err := p.getThisInstance(ctx)
if err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error fetching instance %s: %s", host, err))
+ err = fmt.Errorf("db error fetching instance: %w", err)
+ return nil, gtserror.NewErrorInternalError(err)
}
- // fetch the instance account from the db for processing
- ia, err := p.state.DB.GetInstanceAccount(ctx, "")
+ // Fetch this instance account from the db for processing.
+ instanceAcc, err := p.state.DB.GetInstanceAccount(ctx, "")
if err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error fetching instance account %s: %s", host, err))
+ err = fmt.Errorf("db error fetching instance account: %w", err)
+ return nil, gtserror.NewErrorInternalError(err)
}
- updatingColumns := []string{}
+ // Columns to update
+ // in the database.
+ var columns []string
- // validate & update site title if it's set on the form
+ // Validate & update site
+ // title if set on the form.
if form.Title != nil {
- if err := validate.SiteTitle(*form.Title); err != nil {
- return nil, gtserror.NewErrorBadRequest(err, fmt.Sprintf("site title invalid: %s", err))
+ title := *form.Title
+ if err := validate.SiteTitle(title); err != nil {
+ return nil, gtserror.NewErrorBadRequest(err, err.Error())
}
- updatingColumns = append(updatingColumns, "title")
- instance.Title = text.SanitizeToPlaintext(*form.Title) // don't allow html in site title
+
+ // Don't allow html in site title.
+ instance.Title = text.SanitizeToPlaintext(title)
+ columns = append(columns, "title")
}
- // validate & update site contact account if it's set on the form
+ // Validate & update site contact
+ // account if set on the form.
+ //
+ // Empty username unsets contact.
if form.ContactUsername != nil {
- // make sure the account with the given username exists in the db
- contactAccount, err := p.state.DB.GetAccountByUsernameDomain(ctx, *form.ContactUsername, "")
- if err != nil {
- return nil, gtserror.NewErrorBadRequest(err, fmt.Sprintf("account with username %s not retrievable", *form.ContactUsername))
- }
- // make sure it has a user associated with it
- contactUser, err := p.state.DB.GetUserByAccountID(ctx, contactAccount.ID)
+ contactAccountID, err := p.contactAccountIDForUsername(ctx, *form.ContactUsername)
if err != nil {
- return nil, gtserror.NewErrorBadRequest(err, fmt.Sprintf("user for account with username %s not retrievable", *form.ContactUsername))
- }
- // suspended accounts cannot be contact accounts
- if !contactAccount.SuspendedAt.IsZero() {
- err := fmt.Errorf("selected contact account %s is suspended", contactAccount.Username)
- return nil, gtserror.NewErrorBadRequest(err, err.Error())
- }
- // unconfirmed or unapproved users cannot be contacts
- if contactUser.ConfirmedAt.IsZero() {
- err := fmt.Errorf("user of selected contact account %s is not confirmed", contactAccount.Username)
- return nil, gtserror.NewErrorBadRequest(err, err.Error())
- }
- if !*contactUser.Approved {
- err := fmt.Errorf("user of selected contact account %s is not approved", contactAccount.Username)
- return nil, gtserror.NewErrorBadRequest(err, err.Error())
- }
- // contact account user must be admin or moderator otherwise what's the point of contacting them
- if !*contactUser.Admin && !*contactUser.Moderator {
- err := fmt.Errorf("user of selected contact account %s is neither admin nor moderator", contactAccount.Username)
return nil, gtserror.NewErrorBadRequest(err, err.Error())
}
- updatingColumns = append(updatingColumns, "contact_account_id")
- instance.ContactAccountID = contactAccount.ID
+
+ columns = append(columns, "contact_account_id")
+ instance.ContactAccountID = contactAccountID
}
- // validate & update site contact email if it's set on the form
+ // Validate & update contact
+ // email if set on the form.
+ //
+ // Empty email unsets contact.
if form.ContactEmail != nil {
contactEmail := *form.ContactEmail
if contactEmail != "" {
@@ -214,87 +193,162 @@ func (p *Processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe
return nil, gtserror.NewErrorBadRequest(err, err.Error())
}
}
- updatingColumns = append(updatingColumns, "contact_email")
+
+ columns = append(columns, "contact_email")
instance.ContactEmail = contactEmail
}
- // validate & update site short description if it's set on the form
+ // Validate & update site short
+ // description if set on the form.
if form.ShortDescription != nil {
- if err := validate.SiteShortDescription(*form.ShortDescription); err != nil {
+ shortDescription := *form.ShortDescription
+ if err := validate.SiteShortDescription(shortDescription); err != nil {
return nil, gtserror.NewErrorBadRequest(err, err.Error())
}
- updatingColumns = append(updatingColumns, "short_description")
- instance.ShortDescription = text.SanitizeToHTML(*form.ShortDescription) // html is OK in site description, but we should sanitize it
+
+ // Parse description as Markdown, keep
+ // the raw version for later editing.
+ instance.ShortDescriptionText = shortDescription
+ instance.ShortDescription = p.formatter.FromMarkdown(ctx, p.parseMentionFunc, instanceAcc.ID, "", shortDescription).HTML
+ columns = append(columns, []string{"short_description", "short_description_text"}...)
}
// validate & update site description if it's set on the form
if form.Description != nil {
- if err := validate.SiteDescription(*form.Description); err != nil {
+ description := *form.Description
+ if err := validate.SiteDescription(description); err != nil {
return nil, gtserror.NewErrorBadRequest(err, err.Error())
}
- updatingColumns = append(updatingColumns, "description")
- instance.Description = text.SanitizeToHTML(*form.Description) // html is OK in site description, but we should sanitize it
+
+ // Parse description as Markdown, keep
+ // the raw version for later editing.
+ instance.DescriptionText = description
+ instance.Description = p.formatter.FromMarkdown(ctx, p.parseMentionFunc, instanceAcc.ID, "", description).HTML
+ columns = append(columns, []string{"description", "description_text"}...)
}
- // validate & update site terms if it's set on the form
+ // Validate & update site
+ // terms if set on the form.
if form.Terms != nil {
- if err := validate.SiteTerms(*form.Terms); err != nil {
+ terms := *form.Terms
+ if err := validate.SiteTerms(terms); err != nil {
return nil, gtserror.NewErrorBadRequest(err, err.Error())
}
- updatingColumns = append(updatingColumns, "terms")
- instance.Terms = text.SanitizeToHTML(*form.Terms) // html is OK in site terms, but we should sanitize it
+
+ // Parse terms as Markdown, keep
+ // the raw version for later editing.
+ instance.TermsText = terms
+ instance.Terms = p.formatter.FromMarkdown(ctx, p.parseMentionFunc, "", "", terms).HTML
+ columns = append(columns, []string{"terms", "terms_text"}...)
}
var updateInstanceAccount bool
if form.Avatar != nil && form.Avatar.Size != 0 {
- // process instance avatar image + description
- avatarInfo, err := p.account.UpdateAvatar(ctx, form.Avatar, form.AvatarDescription, ia.ID)
+ // Process instance avatar image + description.
+ avatarInfo, err := p.account.UpdateAvatar(ctx, form.Avatar, form.AvatarDescription, instanceAcc.ID)
if err != nil {
return nil, gtserror.NewErrorBadRequest(err, "error processing avatar")
}
- ia.AvatarMediaAttachmentID = avatarInfo.ID
- ia.AvatarMediaAttachment = avatarInfo
+ instanceAcc.AvatarMediaAttachmentID = avatarInfo.ID
+ instanceAcc.AvatarMediaAttachment = avatarInfo
updateInstanceAccount = true
- } else if form.AvatarDescription != nil && ia.AvatarMediaAttachment != nil {
- // process just the description for the existing avatar
- ia.AvatarMediaAttachment.Description = *form.AvatarDescription
- if err := p.state.DB.UpdateAttachment(ctx, ia.AvatarMediaAttachment, "description"); err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error updating instance avatar description: %s", err))
+ } else if form.AvatarDescription != nil && instanceAcc.AvatarMediaAttachment != nil {
+ // Process just the description for the existing avatar.
+ instanceAcc.AvatarMediaAttachment.Description = *form.AvatarDescription
+ if err := p.state.DB.UpdateAttachment(ctx, instanceAcc.AvatarMediaAttachment, "description"); err != nil {
+ err = fmt.Errorf("db error updating instance avatar description: %w", err)
+ return nil, gtserror.NewErrorInternalError(err)
}
}
if form.Header != nil && form.Header.Size != 0 {
// process instance header image
- headerInfo, err := p.account.UpdateHeader(ctx, form.Header, nil, ia.ID)
+ headerInfo, err := p.account.UpdateHeader(ctx, form.Header, nil, instanceAcc.ID)
if err != nil {
return nil, gtserror.NewErrorBadRequest(err, "error processing header")
}
- ia.HeaderMediaAttachmentID = headerInfo.ID
- ia.HeaderMediaAttachment = headerInfo
+ instanceAcc.HeaderMediaAttachmentID = headerInfo.ID
+ instanceAcc.HeaderMediaAttachment = headerInfo
updateInstanceAccount = true
}
if updateInstanceAccount {
- // if either avatar or header is updated, we need
- // to update the instance account that stores them
- if err := p.state.DB.UpdateAccount(ctx, ia); err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error updating instance account: %s", err))
+ // If either avatar or header is updated, we need
+ // to update the instance account that stores them.
+ if err := p.state.DB.UpdateAccount(ctx, instanceAcc); err != nil {
+ err = fmt.Errorf("db error updating instance account: %w", err)
+ return nil, gtserror.NewErrorInternalError(err, err.Error())
}
}
- if len(updatingColumns) != 0 {
- if err := p.state.DB.UpdateInstance(ctx, instance, updatingColumns...); err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error updating instance %s: %s", host, err))
+ if len(columns) != 0 {
+ if err := p.state.DB.UpdateInstance(ctx, instance, columns...); err != nil {
+ err = fmt.Errorf("db error updating instance: %w", err)
+ return nil, gtserror.NewErrorInternalError(err, err.Error())
}
}
- ai, err := p.converter.InstanceToAPIV1Instance(ctx, instance)
+ return p.InstanceGetV1(ctx)
+}
+
+func (p *Processor) getThisInstance(ctx context.Context) (*gtsmodel.Instance, error) {
+ instance, err := p.state.DB.GetInstance(ctx, config.GetHost())
if err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("error converting instance to api representation: %s", err))
+ return nil, err
}
- return ai, nil
+ return instance, nil
+}
+
+func (p *Processor) contactAccountIDForUsername(ctx context.Context, username string) (string, error) {
+ if username == "" {
+ // Easy: unset
+ // contact account.
+ return "", nil
+ }
+
+ // Make sure local account with the given username exists in the db.
+ contactAccount, err := p.state.DB.GetAccountByUsernameDomain(ctx, username, "")
+ if err != nil {
+ err = fmt.Errorf("db error getting selected contact account with username %s: %w", username, err)
+ return "", err
+ }
+
+ // Make sure account corresponds to a user.
+ contactUser, err := p.state.DB.GetUserByAccountID(ctx, contactAccount.ID)
+ if err != nil {
+ err = fmt.Errorf("db error getting user for selected contact account %s: %w", username, err)
+ return "", err
+ }
+
+ // Ensure account/user is:
+ //
+ // - confirmed and approved
+ // - not suspended
+ // - an admin or a moderator
+ if contactUser.ConfirmedAt.IsZero() {
+ err := fmt.Errorf("user of selected contact account %s is not confirmed", contactAccount.Username)
+ return "", err
+ }
+
+ if !*contactUser.Approved {
+ err := fmt.Errorf("user of selected contact account %s is not approved", contactAccount.Username)
+ return "", err
+ }
+
+ if !contactAccount.SuspendedAt.IsZero() {
+ err := fmt.Errorf("selected contact account %s is suspended", contactAccount.Username)
+ return "", err
+ }
+
+ if !*contactUser.Admin && !*contactUser.Moderator {
+ err := fmt.Errorf("user of selected contact account %s is neither admin nor moderator", contactAccount.Username)
+ return "", err
+ }
+
+ // All good!
+ return contactAccount.ID, nil
}
func obfuscate(domain string) string {
diff --git a/internal/processing/processor.go b/internal/processing/processor.go
index ac930aeb2..6ac7a6bf0 100644
--- a/internal/processing/processor.go
+++ b/internal/processing/processor.go
@@ -21,6 +21,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/cleaner"
"github.com/superseriousbusiness/gotosocial/internal/email"
"github.com/superseriousbusiness/gotosocial/internal/federation"
+ "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
mm "github.com/superseriousbusiness/gotosocial/internal/media"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/processing/account"
@@ -39,6 +40,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/processing/user"
"github.com/superseriousbusiness/gotosocial/internal/processing/workers"
"github.com/superseriousbusiness/gotosocial/internal/state"
+ "github.com/superseriousbusiness/gotosocial/internal/text"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
"github.com/superseriousbusiness/gotosocial/internal/visibility"
)
@@ -56,6 +58,13 @@ type Processor struct {
state *state.State
/*
+ Required for instance description / terms updating.
+ */
+
+ formatter *text.Formatter
+ parseMentionFunc gtsmodel.ParseMentionFunc
+
+ /*
SUB-PROCESSORS
*/
@@ -147,9 +156,11 @@ func NewProcessor(
)
processor := &Processor{
- converter: converter,
- oauthServer: oauthServer,
- state: state,
+ converter: converter,
+ oauthServer: oauthServer,
+ state: state,
+ formatter: text.NewFormatter(state.DB),
+ parseMentionFunc: parseMentionFunc,
}
// Instantiate sub processors.
diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go
index 9d1f7edeb..abae81d04 100644
--- a/internal/typeutils/internaltofrontend.go
+++ b/internal/typeutils/internaltofrontend.go
@@ -941,20 +941,23 @@ func (c *Converter) InstanceRuleToAdminAPIRule(r *gtsmodel.Rule) *apimodel.Admin
// InstanceToAPIV1Instance converts a gts instance into its api equivalent for serving at /api/v1/instance
func (c *Converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Instance) (*apimodel.InstanceV1, error) {
instance := &apimodel.InstanceV1{
- URI: i.URI,
- AccountDomain: config.GetAccountDomain(),
- Title: i.Title,
- Description: i.Description,
- ShortDescription: i.ShortDescription,
- Email: i.ContactEmail,
- Version: config.GetSoftwareVersion(),
- Languages: config.GetInstanceLanguages().TagStrs(),
- Registrations: config.GetAccountsRegistrationOpen(),
- ApprovalRequired: config.GetAccountsApprovalRequired(),
- InvitesEnabled: false, // todo: not supported yet
- MaxTootChars: uint(config.GetStatusesMaxChars()),
- Rules: c.InstanceRulesToAPIRules(i.Rules),
- Terms: i.Terms,
+ URI: i.URI,
+ AccountDomain: config.GetAccountDomain(),
+ Title: i.Title,
+ Description: i.Description,
+ DescriptionText: i.DescriptionText,
+ ShortDescription: i.ShortDescription,
+ ShortDescriptionText: i.ShortDescriptionText,
+ Email: i.ContactEmail,
+ Version: config.GetSoftwareVersion(),
+ Languages: config.GetInstanceLanguages().TagStrs(),
+ Registrations: config.GetAccountsRegistrationOpen(),
+ ApprovalRequired: config.GetAccountsApprovalRequired(),
+ InvitesEnabled: false, // todo: not supported yet
+ MaxTootChars: uint(config.GetStatusesMaxChars()),
+ Rules: c.InstanceRulesToAPIRules(i.Rules),
+ Terms: i.Terms,
+ TermsRaw: i.TermsText,
}
if config.GetInstanceInjectMastodonVersion() {
@@ -1050,16 +1053,18 @@ func (c *Converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
// InstanceToAPIV2Instance converts a gts instance into its api equivalent for serving at /api/v2/instance
func (c *Converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Instance) (*apimodel.InstanceV2, error) {
instance := &apimodel.InstanceV2{
- Domain: i.Domain,
- AccountDomain: config.GetAccountDomain(),
- Title: i.Title,
- Version: config.GetSoftwareVersion(),
- SourceURL: instanceSourceURL,
- Description: i.Description,
- Usage: apimodel.InstanceV2Usage{}, // todo: not implemented
- Languages: config.GetInstanceLanguages().TagStrs(),
- Rules: c.InstanceRulesToAPIRules(i.Rules),
- Terms: i.Terms,
+ Domain: i.Domain,
+ AccountDomain: config.GetAccountDomain(),
+ Title: i.Title,
+ Version: config.GetSoftwareVersion(),
+ SourceURL: instanceSourceURL,
+ Description: i.Description,
+ DescriptionText: i.DescriptionText,
+ Usage: apimodel.InstanceV2Usage{}, // todo: not implemented
+ Languages: config.GetInstanceLanguages().TagStrs(),
+ Rules: c.InstanceRulesToAPIRules(i.Rules),
+ Terms: i.Terms,
+ TermsText: i.TermsText,
}
if config.GetInstanceInjectMastodonVersion() {
diff --git a/internal/typeutils/internaltofrontend_test.go b/internal/typeutils/internaltofrontend_test.go
index d65d47bf1..68b075310 100644
--- a/internal/typeutils/internaltofrontend_test.go
+++ b/internal/typeutils/internaltofrontend_test.go
@@ -841,8 +841,10 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV1ToFrontend() {
"uri": "http://localhost:8080",
"account_domain": "localhost:8080",
"title": "GoToSocial Testrig Instance",
- "description": "\u003cp\u003eThis is the GoToSocial testrig. It doesn't federate or anything.\u003c/p\u003e\u003cp\u003eWhen the testrig is shut down, all data on it will be deleted.\u003c/p\u003e\u003cp\u003eDon't use this in production!\u003c/p\u003e",
+ "description": "\u003cp\u003eHere's a fuller description of the GoToSocial testrig instance.\u003c/p\u003e\u003cp\u003eThis instance is for testing purposes only. It doesn't federate at all. Go check out \u003ca href=\"https://github.com/superseriousbusiness/gotosocial/tree/main/testrig\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003ehttps://github.com/superseriousbusiness/gotosocial/tree/main/testrig\u003c/a\u003e and \u003ca href=\"https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003ehttps://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\u003c/a\u003e\u003c/p\u003e\u003cp\u003eUsers on this instance:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cspan class=\"h-card\"\u003e\u003ca href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e@\u003cspan\u003eadmin\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e (admin!).\u003c/li\u003e\u003cli\u003e\u003cspan class=\"h-card\"\u003e\u003ca href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e@\u003cspan\u003e1happyturtle\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e (posts about turtles, we don't know why).\u003c/li\u003e\u003cli\u003e\u003cspan class=\"h-card\"\u003e\u003ca href=\"http://localhost:8080/@the_mighty_zork\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e@\u003cspan\u003ethe_mighty_zork\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e (who knows).\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eIf you need to edit the models for the testrig, you can do so at \u003ccode\u003einternal/testmodels.go\u003c/code\u003e.\u003c/p\u003e",
+ "description_text": "Here's a fuller description of the GoToSocial testrig instance.\n\nThis instance is for testing purposes only. It doesn't federate at all. Go check out https://github.com/superseriousbusiness/gotosocial/tree/main/testrig and https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\n\nUsers on this instance:\n\n- @admin (admin!).\n- @1happyturtle (posts about turtles, we don't know why).\n- @the_mighty_zork (who knows).\n\nIf you need to edit the models for the testrig, you can do so at `+"`"+`internal/testmodels.go`+"`"+`.",
"short_description": "\u003cp\u003eThis is the GoToSocial testrig. It doesn't federate or anything.\u003c/p\u003e\u003cp\u003eWhen the testrig is shut down, all data on it will be deleted.\u003c/p\u003e\u003cp\u003eDon't use this in production!\u003c/p\u003e",
+ "short_description_text": "This is the GoToSocial testrig. It doesn't federate or anything.\n\nWhen the testrig is shut down, all data on it will be deleted.\n\nDon't use this in production!",
"email": "admin@example.org",
"version": "0.0.0-testrig",
"languages": [
@@ -927,7 +929,9 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV1ToFrontend() {
}
},
"max_toot_chars": 5000,
- "rules": []
+ "rules": [],
+ "terms": "\u003cp\u003eThis is where a list of terms and conditions might go.\u003c/p\u003e\u003cp\u003eFor example:\u003c/p\u003e\u003cp\u003eIf you want to sign up on this instance, you oughta know that we:\u003c/p\u003e\u003col\u003e\u003cli\u003eWill sell your data to whoever offers.\u003c/li\u003e\u003cli\u003eSecure the server with password \u003ccode\u003epassword\u003c/code\u003e wherever possible.\u003c/li\u003e\u003c/ol\u003e",
+ "terms_text": "This is where a list of terms and conditions might go.\n\nFor example:\n\nIf you want to sign up on this instance, you oughta know that we:\n\n1. Will sell your data to whoever offers.\n2. Secure the server with password `+"`"+`password`+"`"+` wherever possible."
}`, string(b))
}
@@ -953,7 +957,8 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV2ToFrontend() {
"title": "GoToSocial Testrig Instance",
"version": "0.0.0-testrig",
"source_url": "https://github.com/superseriousbusiness/gotosocial",
- "description": "\u003cp\u003eThis is the GoToSocial testrig. It doesn't federate or anything.\u003c/p\u003e\u003cp\u003eWhen the testrig is shut down, all data on it will be deleted.\u003c/p\u003e\u003cp\u003eDon't use this in production!\u003c/p\u003e",
+ "description": "\u003cp\u003eHere's a fuller description of the GoToSocial testrig instance.\u003c/p\u003e\u003cp\u003eThis instance is for testing purposes only. It doesn't federate at all. Go check out \u003ca href=\"https://github.com/superseriousbusiness/gotosocial/tree/main/testrig\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003ehttps://github.com/superseriousbusiness/gotosocial/tree/main/testrig\u003c/a\u003e and \u003ca href=\"https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003ehttps://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\u003c/a\u003e\u003c/p\u003e\u003cp\u003eUsers on this instance:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cspan class=\"h-card\"\u003e\u003ca href=\"http://localhost:8080/@admin\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e@\u003cspan\u003eadmin\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e (admin!).\u003c/li\u003e\u003cli\u003e\u003cspan class=\"h-card\"\u003e\u003ca href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e@\u003cspan\u003e1happyturtle\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e (posts about turtles, we don't know why).\u003c/li\u003e\u003cli\u003e\u003cspan class=\"h-card\"\u003e\u003ca href=\"http://localhost:8080/@the_mighty_zork\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"\u003e@\u003cspan\u003ethe_mighty_zork\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e (who knows).\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eIf you need to edit the models for the testrig, you can do so at \u003ccode\u003einternal/testmodels.go\u003c/code\u003e.\u003c/p\u003e",
+ "description_text": "Here's a fuller description of the GoToSocial testrig instance.\n\nThis instance is for testing purposes only. It doesn't federate at all. Go check out https://github.com/superseriousbusiness/gotosocial/tree/main/testrig and https://github.com/superseriousbusiness/gotosocial/blob/main/CONTRIBUTING.md#testing\n\nUsers on this instance:\n\n- @admin (admin!).\n- @1happyturtle (posts about turtles, we don't know why).\n- @the_mighty_zork (who knows).\n\nIf you need to edit the models for the testrig, you can do so at `+"`"+`internal/testmodels.go`+"`"+`.",
"usage": {
"users": {
"active_month": 0
@@ -1045,7 +1050,9 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV2ToFrontend() {
}
}
},
- "rules": []
+ "rules": [],
+ "terms": "\u003cp\u003eThis is where a list of terms and conditions might go.\u003c/p\u003e\u003cp\u003eFor example:\u003c/p\u003e\u003cp\u003eIf you want to sign up on this instance, you oughta know that we:\u003c/p\u003e\u003col\u003e\u003cli\u003eWill sell your data to whoever offers.\u003c/li\u003e\u003cli\u003eSecure the server with password \u003ccode\u003epassword\u003c/code\u003e wherever possible.\u003c/li\u003e\u003c/ol\u003e",
+ "terms_text": "This is where a list of terms and conditions might go.\n\nFor example:\n\nIf you want to sign up on this instance, you oughta know that we:\n\n1. Will sell your data to whoever offers.\n2. Secure the server with password `+"`"+`password`+"`"+` wherever possible."
}`, string(b))
}