Merge branch 'main' of https://framagit.org/framasoft/mobilizon into fomo-3.1.0

This commit is contained in:
johndoe4 2023-06-13 01:05:41 +02:00
commit f12e39c907
23 changed files with 153 additions and 73 deletions

View file

@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 3.1.1 (2023-06-02)
### Features
* **anti-spam:** allow to only scan for spam in profiles or events ([c971287](https://framagit.org/framasoft/mobilizon/-/commit/c971287624913c8555fe288af0df1175701e6209))
### Bug Fixes
* **front:** fix group settings getting unresponsive because of reactive bug ([f1e119c](https://framagit.org/framasoft/mobilizon/-/commit/f1e119cb7ad580dfab73de3083f20a7303822888)), closes [#1298](https://framagit.org/framasoft/mobilizon/-/issues/1298)
* **search:** fix global search sorting ([39e24c3](https://framagit.org/framasoft/mobilizon/-/commit/39e24c328a21f7058e4d2526e13eae85e39bae86)), closes [#1297](https://framagit.org/framasoft/mobilizon/-/issues/1297)
## 3.1.0 (2023-05-31)
### Features
@ -84,11 +95,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* **i18n:** fix Swedish translations error that prevented Participate button from showing up ([643a5b5](https://framagit.org/framasoft/mobilizon/-/commit/643a5b5921f91fed6a9f674c0ab3a36bf2d05835)), closes [#1281](https://framagit.org/framasoft/mobilizon/-/issues/1281)
* **rich media:** fix error handling when resource preview URL leads to empty parsed data ([850b4e2](https://framagit.org/framasoft/mobilizon/-/commit/850b4e2a735e335c4737caa8b60e190613e778ef)), closes [#1279](https://framagit.org/framasoft/mobilizon/-/issues/1279)
* **sharepostmodal:** only show the share warning message if the post is accessible by link ([8e626dc](https://framagit.org/framasoft/mobilizon/-/commit/8e626dce7807640a89770e50ca2621d34d6a5d97))
* **apps:** fix device flow authorization process ([9a457fb](https://framagit.org/framasoft/mobilizon/commits/9a457fb011b77b27dc465f1bc7327a08f554ccfb))
* **apps:** fix typo in redirect_uri parameter ([5664625](https://framagit.org/framasoft/mobilizon/commits/5664625c1c57ccba947400475414c1301d4bf955))
* **apps:** show scope from device activation in authorize device view ([c9d2074](https://framagit.org/framasoft/mobilizon/commits/c9d20748a4dd3e0687515f4776335d0ec9bdfcdc))
* **front:** fix homepage event and groups cards snapping ([8809db5](https://framagit.org/framasoft/mobilizon/commits/8809db582ccf45fcd477f46dcf70e106720626a8))
* **front:** fix selecting addresses in autocomplete ([e0488dd](https://framagit.org/framasoft/mobilizon/commits/e0488dd87ffc0184162a2ff67a13717e6263d56d))
* **apps:** fix device flow authorization process ([9a457fb](https://framagit.org/framasoft/mobilizon/-/commit/9a457fb011b77b27dc465f1bc7327a08f554ccfb))
* **apps:** fix typo in redirect_uri parameter ([5664625](https://framagit.org/framasoft/mobilizon/-/commit/5664625c1c57ccba947400475414c1301d4bf955))
* **apps:** show scope from device activation in authorize device view ([c9d2074](https://framagit.org/framasoft/mobilizon/-/commit/c9d20748a4dd3e0687515f4776335d0ec9bdfcdc))
* **front:** fix homepage event and groups cards snapping ([8809db5](https://framagit.org/framasoft/mobilizon/-/commit/8809db582ccf45fcd477f46dcf70e106720626a8))
* **front:** fix selecting addresses in autocomplete ([e0488dd](https://framagit.org/framasoft/mobilizon/-/commit/e0488dd87ffc0184162a2ff67a13717e6263d56d))
* include user role in moderator role ([c4d6019](https://framagit.org/framasoft/mobilizon/-/commit/c4d60194a6900a3f9430355c5fbb346d910e4df6))
@ -96,11 +107,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Bug Fixes
* **apps:** fix device flow authorization process ([9a457fb](https://framagit.org/framasoft/mobilizon/commits/9a457fb011b77b27dc465f1bc7327a08f554ccfb))
* **apps:** fix typo in redirect_uri parameter ([5664625](https://framagit.org/framasoft/mobilizon/commits/5664625c1c57ccba947400475414c1301d4bf955))
* **apps:** show scope from device activation in authorize device view ([c9d2074](https://framagit.org/framasoft/mobilizon/commits/c9d20748a4dd3e0687515f4776335d0ec9bdfcdc))
* **front:** fix homepage event and groups cards snapping ([8809db5](https://framagit.org/framasoft/mobilizon/commits/8809db582ccf45fcd477f46dcf70e106720626a8))
* **front:** fix selecting addresses in autocomplete ([e0488dd](https://framagit.org/framasoft/mobilizon/commits/e0488dd87ffc0184162a2ff67a13717e6263d56d))
* **apps:** fix device flow authorization process ([9a457fb](https://framagit.org/framasoft/mobilizon/-/commit/9a457fb011b77b27dc465f1bc7327a08f554ccfb))
* **apps:** fix typo in redirect_uri parameter ([5664625](https://framagit.org/framasoft/mobilizon/-/commit/5664625c1c57ccba947400475414c1301d4bf955))
* **apps:** show scope from device activation in authorize device view ([c9d2074](https://framagit.org/framasoft/mobilizon/-/commit/c9d20748a4dd3e0687515f4776335d0ec9bdfcdc))
* **front:** fix homepage event and groups cards snapping ([8809db5](https://framagit.org/framasoft/mobilizon/-/commit/8809db582ccf45fcd477f46dcf70e106720626a8))
* **front:** fix selecting addresses in autocomplete ([e0488dd](https://framagit.org/framasoft/mobilizon/-/commit/e0488dd87ffc0184162a2ff67a13717e6263d56d))
## 3.1.0-rc.1 (2023-05-30)

View file

@ -306,7 +306,7 @@ config :mobilizon, Oban,
crontab: [
{"@hourly", Mobilizon.Service.Workers.BuildSiteMap, queue: :background},
{"17 4 * * *", Mobilizon.Service.Workers.RefreshGroups, queue: :background},
{"36 * * * *", Mobilizon.Service.Workers.RefreshInstances, queue: :background},
{"36 3 * * *", Mobilizon.Service.Workers.RefreshInstances, queue: :background},
{"@hourly", Mobilizon.Service.Workers.CleanOrphanMediaWorker, queue: :background},
{"@hourly", Mobilizon.Service.Workers.CleanUnconfirmedUsersWorker, queue: :background},
{"@hourly", Mobilizon.Service.Workers.ExportCleanerWorker, queue: :background},

View file

@ -1,6 +1,6 @@
{
"name": "mobilizon",
"version": "3.1.0",
"version": "3.1.1",
"private": true,
"scripts": {
"dev": "vite",

View file

@ -295,7 +295,7 @@ export const JOIN_EVENT = gql`
$email: String
$message: String
$locale: String
$timezone: String
$timezone: Timezone
) {
joinEvent(
eventId: $eventId

View file

@ -151,7 +151,7 @@ export const LOGGED_USER_TIMEZONE = gql`
export const SET_USER_SETTINGS = gql`
mutation SetUserSettings(
$timezone: String
$timezone: Timezone
$notificationOnDay: Boolean
$notificationEachWeek: Boolean
$notificationBeforeEvent: Boolean

View file

@ -16,7 +16,7 @@
"A cookie is a small file containing information that is sent to your computer when you visit a website. When you visit the site again, the cookie allows that site to recognize your browser. Cookies may store user preferences and other information. You can configure your browser to refuse all cookies. However, this may result in some website features or services partially working. Local storage works the same way but allows you to store more data.": "Kolačić je mala datoteka koja sadrži sve informacije poslane vašem računalu kada posjetite stranicu. Kada ju opet posjetite, kolačić omogućuje stranici da prepozna vaš preglednik. Kolačić može sadržavati vaše postavke ili druge informacije. Možete postaviti svoj preglednik da blokira sve kolačiće, ali to može dovesti do djelomičnog kvara nekih funkcija stranice. Lokalno spremište radi na isti način ali vam dopušta da spremite više podataka.",
"A discussion has been created or updated": "Jedna diskusija je stvorena ili aktualizirana",
"A federated software": "Federaliziran softver",
"A fediverse account URL to follow for event updates": "",
"A fediverse account URL to follow for event updates": "URL Fediverse računa za praćenje aktualiziranja događaja",
"A few lines about your group": "Par redaka o tvojoj grupi",
"A link to a page presenting the event schedule": "Poveznica na stranicu s rasporedom događaja",
"A link to a page presenting the price options": "Poveznica na stranicu sa cijenama",
@ -32,7 +32,7 @@
"A practical tool": "Praktični alat",
"A resource has been created or updated": "Jedan resurs je stvoren ili aktualiziran",
"A short tagline for your instance homepage. Defaults to \"Gather ⋅ Organize ⋅ Mobilize\"": "Kartki slogan za naslovnu stranicu instance. Zadan je na \"Skupi ⋅ Organiziraj ⋅ Mobiliziraj\"",
"A twitter account handle to follow for event updates": "",
"A twitter account handle to follow for event updates": "Twitter račun za praćenje aktualiziranja događaja",
"A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Emancipacijski i etični alat za okupljanje, organiziranje, i mobiliziranje, sa prijateljskim korisničkim sučeljem.",
"A validation email was sent to {email}": "E-mail za ovjeru je poslan na {email}",
"API": "API",
@ -86,7 +86,7 @@
"All the places have already been taken": "Sva mjesta su već zauzeta",
"Allow all comments from users with accounts": "Dozvoli sve komentare prijavljenih korisnika",
"Allow registrations": "Dozvoli registracije",
"An URL to an external ticketing platform": "",
"An URL to an external ticketing platform": "URL-adresa eksterne platforme za prodaju karata",
"An error has occured while refreshing the page.": "Dogodila se greška prilikom aktualiziranja stranice.",
"An error has occured. Sorry about that. You may try to reload the page.": "Desila se greška! Isprike. Možete probati ponovno učitati stranicu.",
"An ethical alternative": "Etična alternativa",
@ -98,6 +98,7 @@
"An event from one of my groups has been published": "Događaj jedne od mojih grupa je objavljen",
"An event from one of my groups has been updated or deleted": "Događaj jedne od mojih grupa je aktualiziran ili izbrisan",
"An instance is an installed version of the Mobilizon software running on a server. An instance can be run by anyone using the {mobilizon_software} or other federated apps, aka the “fediverse”. This instance's name is {instance_name}. Mobilizon is a federated network of multiple instances (just like email servers), users registered on different instances may communicate even though they didn't register on the same instance.": "Instanca je instalirana verzija Mobilizon softvera koja radi na serveru. Instancu može postaviti bilo tko, tko koristi {mobilizon_software} ili druge federalizirane aplikacije, poznato i kao „fediverse”. Ime ove instance je {instance_name}. Mobilizon je federalizirana mreža kaj se sastoji od više instanca (kao e-mail serveri) gdje korisnici, koji su registrirani na različitim instancama mogu komunicirati iako se ne nalaze na istoj instanci.",
"An “application programming interface” or “API” is a communication protocol that allows software components to communicate with each other. The Mobilizon API, for example, can allow third-party software tools to communicate with Mobilizon instances to carry out certain actions, such as posting events, automatically and remotely.": "„Sučelje za programiranje aplikacija” ili „API” je komunikacijski protokol koji omogućuje komponentama softvera da međusobno komuniciraju. Mobilizon API, na primjer, može dozvoliti softverskim alatima trećih strana da komuniciraju s Mobilizon instancama za izvođenje određenih radnji, kao što je objavljivanje događaja, automatski i na daljinski način.",
"And {number} comments": "I {number} komentara",
"Announcements and mentions notifications are always sent straight away.": "Najave i obavijesti o spominjanjima uvijek se šalju odmah.",
"Anonymous participant": "Anonimni sudionik",
@ -158,7 +159,7 @@
"Cancel": "Otkaži",
"Cancel anonymous participation": "Otkaži anonimno sudjelovanje",
"Cancel creation": "Otkaži stvaranje",
"Cancel discussion title edition": "",
"Cancel discussion title edition": "Prekini mijenjanje naslova diskusije",
"Cancel edition": "Otkaži uređivanje",
"Cancel follow request": "",
"Cancel membership request": "",
@ -297,7 +298,7 @@
"Do you really want to suspend this account? All of the user's profiles will be deleted.": "Stvarno želiš suspendirati ovaj račun? Svi korisnički profili će se izbrisati.",
"Do you wish to {create_event} or {explore_events}?": "Želite li {create_event} ili {explore_event}?",
"Do you wish to {create_group} or {explore_groups}?": "Želite li {create_group} ili {explore_groups}?",
"Does the event needs to be confirmed later or is it cancelled?": "",
"Does the event needs to be confirmed later or is it cancelled?": "Treba li događaj kasnije potvrditi ili je otkazan?",
"Domain": "Domena",
"Draft": "Skica",
"Drafts": "Skice",
@ -684,7 +685,7 @@
"On {instance} and other federated instances": "Na {instance} i drugim federaliziranim instancama",
"Online": "Online",
"Online events": "Online događaji",
"Online ticketing": "",
"Online ticketing": "Online prodaja karata",
"Only accessible through link": "Dostupno samo preko poveznice",
"Only accessible through link (private)": "Dostupno samo kroz poveznicu (privatno)",
"Only accessible to members of the group": "Dostupno samo članovima grupe",
@ -1075,7 +1076,7 @@
"Upcoming events from your groups": "",
"Update": "Ažuriraj",
"Update app": "Aktualiziraj program",
"Update discussion title": "",
"Update discussion title": "Aktualiziraj naslov diskusije",
"Update event {name}": "Ažuriraj događaj {name}",
"Update group": "Ažuriraj grupu",
"Update my event": "Ažuriraj moj događaj",
@ -1136,7 +1137,7 @@
"Whether the event is accessible with a wheelchair": "Je li postoji pristup za osobe u invalidskim kolicima",
"Whether the event is interpreted in sign language": "Je li se događaj prevodi na znakovni jezik",
"Whether the event live video is subtitled": "Je li video događaja uživo titlovan",
"Who can post a comment?": "",
"Who can post a comment?": "Tko smije komentirati?",
"Who can view this event and participate": "Tko može vidjeti ovaj događaj i sudjelovati",
"Who can view this post": "Tko može vidjeti ovu objavu",
"Who published {number} events": "Koji su objavili {number} događaja",

View file

@ -426,7 +426,9 @@
>
<option
v-for="timezone in groupTimezones"
:value="`${group}/${timezone}`"
:value="
group === t('Other') ? timezone : `${group}/${timezone}`
"
:key="timezone"
>
{{ sanitizeTimezone(timezone) }}

View file

@ -344,11 +344,11 @@ const canShowCopyButton = computed((): boolean => {
});
const currentAddress = computed({
get(): IAddress {
return new Address(editableGroup.value?.physicalAddress);
get(): IAddress | null {
return editableGroup.value?.physicalAddress ?? null;
},
set(address: IAddress) {
if (editableGroup.value) {
set(address: IAddress | null) {
if (editableGroup.value && address) {
editableGroup.value = {
...editableGroup.value,
physicalAddress: address,

View file

@ -73,7 +73,7 @@
<tr v-for="subType in notificationType.subtypes" :key="subType.id">
<td v-for="(method, key) in notificationMethods" :key="key">
<o-checkbox
:value="notificationValues[subType.id][key].enabled"
:modelValue="notificationValues[subType.id][key].enabled"
@update:modelValue="
(e: boolean) =>
updateNotificationValue({
@ -645,7 +645,7 @@ const dialog = inject<Dialog>("dialog");
const openRegenerateFeedTokensConfirmation = () => {
dialog?.confirm({
type: "warning",
variant: "warning",
title: t("Regenerate new links") as string,
message: t(
"You'll need to change the URLs where there were previously entered."

View file

@ -22,7 +22,9 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
| {:error,
:invalid_url | :http_gone | :http_error | :http_not_found | :content_not_json}
def fetch(url, options \\ []) do
on_behalf_of = Keyword.get(options, :on_behalf_of, Relay.get_actor())
Logger.debug("Fetching #{url} with AP Fetcher")
on_behalf_of = Keyword.get(options, :on_behalf_of, actor_relay())
Logger.debug("Fetching on behalf of #{inspect(on_behalf_of.url)}")
date = Signature.generate_date_header()
headers =
@ -32,29 +34,8 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
client = ActivityPubClient.client(headers: headers)
if address_valid?(url) do
case ActivityPubClient.get(client, url) do
{:ok, %Tesla.Env{body: data, status: code}} when code in 200..299 and is_map(data) ->
{:ok, data}
{:ok, %Tesla.Env{status: 410}} ->
Logger.debug("Resource at #{url} is 410 Gone")
{:error, :http_gone}
{:ok, %Tesla.Env{status: 404}} ->
Logger.debug("Resource at #{url} is 404 Gone")
{:error, :http_not_found}
{:ok, %Tesla.Env{body: data}} when is_binary(data) ->
{:error, :content_not_json}
{:ok, %Tesla.Env{} = res} ->
Logger.debug("Resource returned bad HTTP code #{inspect(res)}")
{:error, :http_error}
{:error, err} ->
{:error, err}
end
if address_valid?(url) and url != on_behalf_of.url do
do_fetch(url, client)
else
{:error, :invalid_url}
end
@ -169,4 +150,38 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
%URI{host: host, scheme: scheme} = URI.parse(address)
is_valid_string(host) and is_valid_string(scheme)
end
defp actor_relay do
Relay.get_actor()
end
@spec do_fetch(String.t(), Tesla.Client.t()) ::
{:ok, map()}
| {:error,
:invalid_url | :http_gone | :http_error | :http_not_found | :content_not_json}
defp do_fetch(url, client) do
case ActivityPubClient.get(client, url) do
{:ok, %Tesla.Env{body: data, status: code}} when code in 200..299 and is_map(data) ->
Logger.debug("Found the following from ActivityPubClient fetch: #{inspect(data)}")
{:ok, data}
{:ok, %Tesla.Env{status: 410}} ->
Logger.debug("Resource at #{url} is 410 Gone")
{:error, :http_gone}
{:ok, %Tesla.Env{status: 404}} ->
Logger.debug("Resource at #{url} is 404 Gone")
{:error, :http_not_found}
{:ok, %Tesla.Env{body: data}} when is_binary(data) ->
{:error, :content_not_json}
{:ok, %Tesla.Env{} = res} ->
Logger.debug("Resource returned bad HTTP code #{inspect(res)}")
{:error, :http_error}
{:error, err} ->
{:error, err}
end
end
end

View file

@ -55,7 +55,7 @@ defmodule Mobilizon.Federation.ActivityPub.Refresher do
@type fetch_actor_errors :: ActivityPubActor.make_actor_errors() | fetch_collection_errors()
@spec fetch_group(String.t(), Actor.t()) :: :ok | {:error, fetch_actor_errors}
def fetch_group(group_url, %Actor{} = on_behalf_of) do
def fetch_group(group_url, %Actor{} = on_behalf_of) when is_binary(group_url) do
Logger.debug("Fetching group #{group_url}")
case ActivityPubActor.make_actor_from_url(group_url, on_behalf_of: on_behalf_of) do

View file

@ -23,7 +23,13 @@ defmodule Mobilizon.Federation.ActivityPub.Relay do
def init do
# Wait for everything to settle.
Process.sleep(1000 * 5)
get_actor()
relay = get_actor()
unless Regex.match?(~r/BEGIN RSA PRIVATE KEY/, relay.keys) do
{:ok, relay} = Actors.actor_key_rotation(relay)
end
relay
end
@spec get_actor() :: Actor.t() | no_return

View file

@ -12,6 +12,7 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
alias Mobilizon.Actors.Actor
alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor
alias Mobilizon.Federation.ActivityPub.Relay
require Logger
@ -94,13 +95,19 @@ defmodule Mobilizon.Federation.HTTPSignatures.Signature do
%{"keyId" => kid} = HTTPSignatures.signature_for_conn(conn)
actor_url = key_id_to_actor_url(kid)
Logger.debug("Refetching public key for #{actor_url}")
relay = Relay.get_actor()
# In this specific case we don't sign object fetches because
# this would cause infinite recursion when servers both need
# to fetch each other's keys
with {:ok, %Actor{} = actor} <-
ActivityPubActor.make_actor_from_url(actor_url, ignore_sign_object_fetches: true) do
get_actor_public_key(actor)
if actor_url == relay.url do
# Special case if ever it's our own actor fetching ourselves
get_actor_public_key(relay)
else
# In this specific case we don't sign object fetches because
# this would cause infinite recursion when servers both need
# to fetch each other's keys
with {:ok, %Actor{} = actor} <-
ActivityPubActor.make_actor_from_url(actor_url, ignore_sign_object_fetches: true) do
get_actor_public_key(actor)
end
end
end

View file

@ -31,6 +31,7 @@ defmodule Mobilizon.GraphQL.Schema do
import_types(Absinthe.Plug.Types)
import_types(Custom.UUID)
import_types(Custom.Point)
import_types(Custom.Timezone)
import_types(Schema.ActivityType)
import_types(Schema.UserType)

View file

@ -22,7 +22,7 @@ defmodule Mobilizon.GraphQL.Schema.AddressType do
field(:url, :string, description: "The address's URL")
field(:id, :id, description: "The address's ID")
field(:origin_id, :string, description: "The address's original ID from the provider")
field(:timezone, :string, description: "The (estimated) timezone of the location")
field(:timezone, :timezone, description: "The (estimated) timezone of the location")
field(:picture_info, :picture_info, description: "A picture associated with the address")
end
@ -75,7 +75,7 @@ defmodule Mobilizon.GraphQL.Schema.AddressType do
field(:url, :string, description: "The address's URL")
field(:id, :id, description: "The address's ID")
field(:origin_id, :string, description: "The address's original ID from the provider")
field(:timezone, :string, description: "The (estimated) timezone of the location")
field(:timezone, :timezone, description: "The (estimated) timezone of the location")
end
@desc """

View file

@ -43,7 +43,7 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
field(:upload_limits, :upload_limits, description: "The configuration for upload limits")
field(:timezones, list_of(:string), description: "The instance's available timezones")
field(:timezones, list_of(:timezone), description: "The instance's available timezones")
field(:features, :features, description: "The instance's features")
field(:restrictions, :restrictions, description: "The instance's restrictions")
field(:version, :string, description: "The instance's version")

View file

@ -0,0 +1,35 @@
defmodule Mobilizon.GraphQL.Schema.Custom.Timezone do
@moduledoc """
The timezone scalar type allows timezone ID strings to be passed in and out.
"""
use Absinthe.Schema.Notation
import Mobilizon.Web.Gettext, only: [dgettext: 3]
scalar :timezone, name: "Timezone" do
description("""
The `Timezone` scalar type represents a timezone identifier,
as registered in the IANA Time Zone Database.
""")
serialize(&encode/1)
parse(&decode/1)
end
@spec decode(Absinthe.Blueprint.Input.String.t()) :: {:ok, term} | :error
@spec decode(Absinthe.Blueprint.Input.Null.t()) :: {:ok, nil}
defp decode(%Absinthe.Blueprint.Input.String{value: value}) do
if Tzdata.zone_exists?(value),
do: {:ok, value},
else: {:error, dgettext("errors", "Timezone ID %{timezone} is invalid", timezone: value)}
end
defp decode(%Absinthe.Blueprint.Input.Null{}) do
{:ok, nil}
end
defp decode(_) do
:error
end
defp encode(value), do: value
end

View file

@ -250,7 +250,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
field(:show_start_time, :boolean, description: "Show event start time")
field(:show_end_time, :boolean, description: "Show event end time")
field(:timezone, :string, description: "The event's timezone")
field(:timezone, :timezone, description: "The event's timezone")
field(:hide_organizer_when_group_event, :boolean,
description:
@ -303,7 +303,7 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
field(:show_start_time, :boolean, description: "Show event start time")
field(:show_end_time, :boolean, description: "Show event end time")
field(:timezone, :string, description: "The event's timezone")
field(:timezone, :timezone, description: "The event's timezone")
field(:hide_organizer_when_group_event, :boolean,
description:

View file

@ -96,7 +96,7 @@ defmodule Mobilizon.GraphQL.Schema.Events.ParticipantType do
arg(:email, :string, description: "The anonymous participant's email")
arg(:message, :string, description: "The anonymous participant's message")
arg(:locale, :string, description: "The anonymous participant's locale")
arg(:timezone, :string, description: "The anonymous participant's timezone")
arg(:timezone, :timezone, description: "The anonymous participant's timezone")
middleware(Rajska.QueryAuthorization, permit: :all, rule: :"write:participation")
resolve(&Participant.actor_join_event/3)
end

View file

@ -220,7 +220,7 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
"""
object :user_settings do
meta(:authorize, :user)
field(:timezone, :string, description: "The timezone for this user")
field(:timezone, :timezone, description: "The timezone for this user")
field(:notification_on_day, :boolean,
description: "Whether this user will receive an email at the start of the day of an event."
@ -450,7 +450,7 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
@desc "Set user settings"
field :set_user_settings, :user_settings do
arg(:timezone, :string, description: "The timezone for this user")
arg(:timezone, :timezone, description: "The timezone for this user")
arg(:notification_on_day, :boolean,
description:

View file

@ -4,6 +4,7 @@ defmodule Mobilizon.GraphQL.Schema.Users.ActivitySetting do
"""
use Absinthe.Schema.Notation
alias Mobilizon.GraphQL.Resolvers.Users.ActivitySettings
alias Mobilizon.Users.ActivitySetting
object :activity_setting do
meta(:authorize, :user)
@ -21,8 +22,9 @@ defmodule Mobilizon.GraphQL.Schema.Users.ActivitySetting do
middleware(Rajska.QueryAuthorization,
permit: :user,
scope: false,
rule: :"write:user:setting:activity"
scope: ActivitySetting,
rule: :"write:user:setting:activity",
args: %{key: :key}
)
resolve(&ActivitySettings.upsert_user_activity_setting/3)

View file

@ -426,7 +426,7 @@ defmodule Mobilizon.Applications do
@spec prune_old_application_device_activations(pos_integer()) :: {non_neg_integer(), nil}
def prune_old_application_device_activations(lifetime) do
exp = DateTime.add(DateTime.utc_now(), -lifetime)
exp = DateTime.utc_now() |> DateTime.add(-lifetime) |> DateTime.to_unix()
ApplicationDeviceActivation
|> where([at], at.expires_in < ^exp)

View file

@ -1,7 +1,7 @@
defmodule Mobilizon.Mixfile do
use Mix.Project
@version "3.1.0"
@version "3.1.1"
def project do
[