Compare commits

...

7 Commits

Author SHA1 Message Date
Osma Ahvenlampi 57ec90ee24
Merge 85ee2692f1 into 72eb6a6271 2024-02-06 11:01:42 +01:00
Henri Dickson 72eb6a6271
add application/activity+json to accept header to improve compatibility (#694) 2024-02-05 21:40:04 -05:00
Jamie Bliss b2223ddf42
Back out push notification changes 2024-02-05 21:18:59 -05:00
Jamie Bliss 045a499ddf
Fix docs 2024-02-05 20:59:22 -05:00
Jamie Bliss 0fa48578f2
Write release notes for 0.11.0 2024-02-05 20:53:09 -05:00
Osma Ahvenlampi 85ee2692f1 change in migrations formatting 2023-11-16 17:45:25 +02:00
Osma Ahvenlampi 05ec6cbe74 add support for enabling Mastodon 4.2 search indexing 2023-11-16 16:25:39 +02:00
15 changed files with 93 additions and 14 deletions

View File

@ -3,7 +3,7 @@
A *beta* Fediverse server for microblogging. Not fully polished yet -
we're still working towards a 1.0!
**Current version: [0.10.1](https://docs.jointakahe.org/en/latest/releases/0.10/)**
**Current version: [0.11.0](https://docs.jointakahe.org/en/latest/releases/0.11/)**
Key features:

View File

@ -71,6 +71,7 @@ class Account(Schema):
bot: bool
group: bool
discoverable: bool
indexable: bool
moved: Union[None, bool, "Account"]
suspended: bool = False
limited: bool = False

View File

@ -559,6 +559,7 @@ schemas = {
"@context": {
"toot": "http://joinmastodon.org/ns#",
"discoverable": "toot:discoverable",
"indexable": "toot:indexable",
"devices": "toot:devices",
"featured": "toot:featured",
"featuredTags": "toot:featuredTags",

View File

@ -219,7 +219,7 @@ class HttpSignature:
body_bytes = b""
# GET requests get implicit accept headers added
if method == "get":
headers["Accept"] = "application/ld+json"
headers["Accept"] = "application/activity+json,application/ld+json"
# Sign the headers
signed_string = "\n".join(
f"{name.lower()}: {value}" for name, value in headers.items()

View File

@ -1,21 +1,37 @@
0.11
====
*Released: Not Yet Released*
*Released: 2024-02-05*
Notes TBD.
This is largely a bugfix and catch up release.
Some highlights:
Upgrade Notes
-------------
* Python 3.10 has been dropped. The new minimum Python version is 3.11
* Jamie (`@astraluma@tacobelllabs.net <https://tacobelllabs.net/@astraluma>`_)
has officially joined the project
* If your S3 does not use TLS, you must use ``s3-insecure`` in your
configuration
* Takahē now supports unicode hashtags
* Add a Maximum Media Attachments setting
* Inverted the pruning command exit codes
* Posts are no longer required to have text content
VAPID keys and Push notifications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
And some interoperability bugs:
Takahē now supports push notifications if you supply a valid VAPID keypair as
the ``TAKAHE_VAPID_PUBLIC_KEY`` and ``TAKAHE_VAPID_PRIVATE_KEY`` environment
variables. You can generate a keypair via `https://web-push-codelab.glitch.me/`_.
* Fixed a bug with GoToSocial
* Attempted to fix follows from Misskey family
* Correctly handle when a federated report doesn't have content
Note that users of apps may need to sign out and in again to their accounts for
the app to notice that it can now do push notifications. Some apps, like Elk,
may cache the fact your server didn't support it for a while.
In additions, there's many bugfixes and minor changes, including:
* Several JSON handling improvements
* Post pruning now has a random element to it
* More specific loggers
* Don't make local identities stale
* Don't try to unmute when there's no expiration
* Don't try to WebFinger local users
* Synchronize follow accepting and profile fetching
* Perform some basic domain validity
* Correctly reject more operations when the identity is deleted
* Post edit fanouts for likers/boosters

View File

@ -7,6 +7,7 @@ Versions
.. toctree::
:maxdepth: 1
0.11
0.10
0.9
0.8

15
docs/releases/next.rst Normal file
View File

@ -0,0 +1,15 @@
Upgrade Notes
-------------
VAPID keys and Push notifications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Takahē now supports push notifications if you supply a valid VAPID keypair as
the ``TAKAHE_VAPID_PUBLIC_KEY`` and ``TAKAHE_VAPID_PRIVATE_KEY`` environment
variables. You can generate a keypair via `https://web-push-codelab.glitch.me/`_.
Note that users of apps may need to sign out and in again to their accounts for
the app to notice that it can now do push notifications. Some apps, like Elk,
may cache the fact your server didn't support it for a while.

View File

@ -31,6 +31,7 @@
{% include "forms/_field.html" with field=form.domain %}
{% include "forms/_field.html" with field=form.name %}
{% include "forms/_field.html" with field=form.discoverable %}
{% include "forms/_field.html" with field=form.indexable %}
</fieldset>
<div class="buttons">
<button>Create</button>

View File

@ -24,6 +24,7 @@
<fieldset>
<legend>Privacy</legend>
{% include "forms/_field.html" with field=form.discoverable %}
{% include "forms/_field.html" with field=form.indexable %}
{% include "forms/_field.html" with field=form.visible_follows %}
{% include "forms/_field.html" with field=form.search_enabled %}
</fieldset>

View File

@ -204,6 +204,8 @@ def test_fetch_actor(httpx_mock, config_system):
assert identity.image_uri == "https://example.com/image.jpg"
assert identity.summary == "<p>A test user</p>"
assert "ts-a-faaaake" in identity.public_key
# convention is that indexability should be opt-in
assert not identity.indexable
@pytest.mark.django_db

View File

@ -0,0 +1,17 @@
# Generated by Django 4.2.3 on 2023-11-16 13:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("users", "0022_follow_request"),
]
operations = [
migrations.AddField(
model_name="identity",
name="indexable",
field=models.BooleanField(default=False),
),
]

View File

@ -233,6 +233,7 @@ class Identity(StatorModel):
summary = models.TextField(blank=True, null=True)
manually_approves_followers = models.BooleanField(blank=True, null=True)
discoverable = models.BooleanField(default=True)
indexable = models.BooleanField(default=False)
profile_uri = models.CharField(max_length=500, blank=True, null=True)
inbox_uri = models.CharField(max_length=500, blank=True, null=True)
@ -597,6 +598,7 @@ class Identity(StatorModel):
"published": self.created.strftime("%Y-%m-%dT%H:%M:%SZ"),
"url": self.absolute_profile_uri(),
"toot:discoverable": self.discoverable,
"toot:indexable": self.indexable,
}
if self.name:
response["name"] = self.name
@ -958,6 +960,7 @@ class Identity(StatorModel):
self.icon_uri = get_first_image_url(document.get("icon", None))
self.image_uri = get_first_image_url(document.get("image", None))
self.discoverable = document.get("toot:discoverable", True)
self.indexable = document.get("toot:indexable", False)
# Profile links/metadata
self.metadata = []
for attachment in get_list(document, "attachment"):
@ -1095,6 +1098,7 @@ class Identity(StatorModel):
"bot": self.actor_type.lower() in ["service", "application"],
"group": self.actor_type.lower() == "group",
"discoverable": self.discoverable,
"indexable": self.indexable,
"suspended": False,
"limited": False,
"created_at": format_ld_date(

View File

@ -38,6 +38,7 @@ class IdentityService:
domain: Domain,
name: str,
discoverable: bool = True,
indexable: bool = False,
) -> Identity:
identity = Identity.objects.create(
actor_uri=f"https://{domain.uri_domain}/@{username}@{domain.domain}/",
@ -46,6 +47,7 @@ class IdentityService:
name=name,
local=True,
discoverable=discoverable,
indexable=indexable,
)
identity.users.add(user)
identity.generate_keypair()

View File

@ -313,6 +313,14 @@ class CreateIdentity(FormView):
),
required=False,
)
indexable = forms.BooleanField(
help_text="Should this user's activities be indexable on other servers.",
initial=False,
widget=forms.Select(
choices=[(True, "Indexable"), (False, "Not Indexable")]
),
required=False,
)
def __init__(self, user, *args, **kwargs):
super().__init__(*args, **kwargs)
@ -385,6 +393,7 @@ class CreateIdentity(FormView):
domain=domain_instance,
name=form.cleaned_data["name"],
discoverable=form.cleaned_data["discoverable"],
indexable=form.cleaned_data["indexable"],
)
self.request.session["identity_id"] = identity.id
return redirect(identity.urls.view)

View File

@ -43,6 +43,13 @@ class ProfilePage(FormView):
),
required=False,
)
indexable = forms.BooleanField(
help_text="Opt-in to be indexed for search on other servers.\n(Disabling this does not guarantee third-party servers won't index your posts without permission)",
widget=forms.Select(
choices=[(True, "Indexable"), (False, "Not Indexable")]
),
required=False,
)
visible_follows = forms.BooleanField(
help_text="Whether or not to show your following and follower counts in your profile",
widget=forms.Select(choices=[(True, "Visible"), (False, "Hidden")]),
@ -93,6 +100,7 @@ class ProfilePage(FormView):
"icon": self.identity.icon and self.identity.icon.url,
"image": self.identity.image and self.identity.image.url,
"discoverable": self.identity.discoverable,
"indexable": self.identity.indexable,
"visible_follows": self.identity.config_identity.visible_follows,
"metadata": self.identity.metadata or [],
"search_enabled": self.identity.config_identity.search_enabled,
@ -104,6 +112,7 @@ class ProfilePage(FormView):
service = IdentityService(self.identity)
self.identity.name = form.cleaned_data["name"]
self.identity.discoverable = form.cleaned_data["discoverable"]
self.identity.indexable = form.cleaned_data["indexable"]
service.set_summary(form.cleaned_data["summary"])
# Resize images
icon = form.cleaned_data.get("icon")