diff --git a/js/.env.dist b/js/.env.dist new file mode 100644 index 000000000..30dde71ce --- /dev/null +++ b/js/.env.dist @@ -0,0 +1,3 @@ +API_HOST=event.tcit.fr +API_ORIGIN=https://event.tcit.fr +API_PATH=/api/v1 diff --git a/js/.gitignore b/js/.gitignore index 912d2e707..03808dce1 100644 --- a/js/.gitignore +++ b/js/.gitignore @@ -22,3 +22,5 @@ yarn-error.log* *.njsproj *.sln *.sw* + +.env diff --git a/js/package-lock.json b/js/package-lock.json index 1e9742d76..ee0cf7f8b 100644 --- a/js/package-lock.json +++ b/js/package-lock.json @@ -4449,6 +4449,21 @@ "is-obj": "^1.0.0" } }, + "dotenv": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", + "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==", + "dev": true + }, + "dotenv-webpack": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/dotenv-webpack/-/dotenv-webpack-1.5.5.tgz", + "integrity": "sha1-NEEJTwTTBLYRnmtyUk5i+zJS9fI=", + "dev": true, + "requires": { + "dotenv": "^5.0.1" + } + }, "duplexify": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", diff --git a/js/package.json b/js/package.json index 05050f963..6e6c5ef49 100644 --- a/js/package.json +++ b/js/package.json @@ -23,6 +23,7 @@ "vuex-i18n": "^1.10.5" }, "devDependencies": { + "dotenv-webpack": "^1.5.5", "@vue/cli-plugin-babel": "^3.0.0-beta.10", "@vue/cli-plugin-e2e-nightwatch": "^3.0.0-beta.10", "@vue/cli-plugin-eslint": "^3.0.0-beta.10", diff --git a/js/src/App.vue b/js/src/App.vue index 29a117912..5460d0431 100644 --- a/js/src/App.vue +++ b/js/src/App.vue @@ -61,7 +61,7 @@ add - © Thomas Citharel {{ new Date().getFullYear() }} - Made with API Platform & VueJS & Vuetify with some love and some weeks + © Thomas Citharel {{ new Date().getFullYear() }} - Made with Elixir, Phoenix & VueJS & Vuetify with some love and some weeks { if (response.ok) return response; diff --git a/js/src/auth/index.js b/js/src/auth/index.js index 98a064f35..b6a8d8eff 100644 --- a/js/src/auth/index.js +++ b/js/src/auth/index.js @@ -1,10 +1,10 @@ -import { API_HOST, API_PATH } from '../api/_entrypoint'; +import { API_ORIGIN, API_PATH } from '../api/_entrypoint'; // URL and endpoint constants -const LOGIN_URL = `${API_HOST}${API_PATH}/login`; -const SIGNUP_URL = `${API_HOST}${API_PATH}/users/`; -const CHECK_AUTH = `${API_HOST}${API_PATH}/user/`; -const REFRESH_TOKEN = `${API_HOST}${API_PATH}/token/refresh`; +const LOGIN_URL = `${API_ORIGIN}${API_PATH}/login`; +const SIGNUP_URL = `${API_ORIGIN}${API_PATH}/users/`; +const CHECK_AUTH = `${API_ORIGIN}${API_PATH}/user/`; +const REFRESH_TOKEN = `${API_ORIGIN}${API_PATH}/token/refresh`; export default { diff --git a/js/src/components/Account/Account.vue b/js/src/components/Account/Account.vue index f320450e6..6476cd540 100644 --- a/js/src/components/Account/Account.vue +++ b/js/src/components/Account/Account.vue @@ -10,7 +10,7 @@ chevron_left - + edit @@ -33,9 +33,9 @@ - {{ account.display_name }} - @{{ account.username }}@{{ account.server.address }} - + {{ actor.display_name }} + @{{ actor.username }}@{{ actor.server.address }} + @@ -74,10 +74,10 @@ - + Participated at - + - + Organized events - + response.json()) .then((response) => { - this.account = response.data; + this.actor = response.data; this.loading = false; - console.log(this.account); + console.log(this.actor); }) } } diff --git a/js/src/components/Event/Create.vue b/js/src/components/Event/Create.vue index 1897f4532..bc9eadf09 100644 --- a/js/src/components/Event/Create.vue +++ b/js/src/components/Event/Create.vue @@ -1,195 +1,201 @@ - + Create a new event - - Basic Informations - Title and description - - - - - - - + + + Basic Informations + Title and description + + + Date and place + + Extra informations + + + + + - - - - - - - - - - - - - Next - - Date and place - - Event starts at: - - - Event ends at: - - + + + + + + + + + Next + + + Event starts at: + + + Event ends at: + + - - - Next - - Extra informations - - - - + + + Next + + + + + + Create event @@ -240,7 +246,7 @@ participants: [], }, categories: [], - tags: [{ name: 'test' }, { name: 'montag' }], + tags: [], tagsToSend: [], tagsFetched: [], }; @@ -259,13 +265,13 @@ this.event.seats = parseInt(this.event.seats, 10); this.tagsToSend.forEach((tag) => { this.event.tags.push({ - name: tag, + title: tag, // '@type': 'Tag', }); }); this.event.category_id = this.event.category.id; - this.event.organizer_account_id = this.$store.state.user.account.id; - this.event.participants = [this.$store.state.user.account.id]; + this.event.organizer_actor_id = this.$store.state.user.actor.id; + this.event.participants = [this.$store.state.user.actor.id]; this.event.price = parseFloat(this.event.price); if (this.id === undefined) { @@ -283,6 +289,7 @@ this.$router.push({name: 'Event', params: {id: data.id}}); }); } + this.event.tags = []; }, fetchCategories() { eventFetch('/categories', this.$store) diff --git a/js/src/components/Event/Event.vue b/js/src/components/Event/Event.vue index 3fccb3394..f65c2b931 100644 --- a/js/src/components/Event/Event.vue +++ b/js/src/components/Event/Event.vue @@ -11,7 +11,7 @@ chevron_left - + edit @@ -22,7 +22,7 @@ Download - + Delete @@ -54,8 +54,8 @@ Organisateur {{ event.organizer.username }} - - + + - {{ account.username }} + {{ actor.username }} - Join - Leave + Join + Leave Delete @@ -97,7 +97,8 @@ loading: true, error: false, event: { - id: this.id, + name: this.name, + slug: this.slug, title: '', description: '', organizer: { @@ -111,11 +112,11 @@ methods: { deleteEvent() { const router = this.$router; - eventFetch(`/events/${this.id}`, this.$store, { method: 'DELETE' }) + eventFetch(`/events/${this.name}/${this.slug}`, this.$store, { method: 'DELETE' }) .then(() => router.push({'name': 'EventList'})); }, fetchData() { - eventFetch(`/events/${this.id}`, this.$store) + eventFetch(`/events/${this.name}/${this.slug}`, this.$store) .then(response => response.json()) .then((data) => { this.loading = false; @@ -129,21 +130,21 @@ }); }, joinEvent() { - eventFetch(`/events/${this.id}/join`, this.$store) + eventFetch(`/events/${this.name}/${this.slug}/join`, this.$store) .then(response => response.json()) .then((data) => { console.log(data); }); }, leaveEvent() { - eventFetch(`/events/${this.id}/leave`, this.$store) + eventFetch(`/events/${this.name}/${this.slug}/leave`, this.$store) .then(response => response.json()) .then((data) => { console.log(data); }); }, downloadIcsEvent() { - eventFetch('/events/' + this.event.id + '/ics', this.$store, {responseType: 'arraybuffer'}) + eventFetch(`/events/${this.name}/${this.slug}/ics`, this.$store, {responseType: 'arraybuffer'}) .then((response) => response.text()) .then(response => { const blob = new Blob([response],{type: 'text/calendar'}); @@ -156,7 +157,16 @@ }) }, }, - props: ['id'], + props: { + name: { + type: String, + required: true, + }, + slug: { + type: String, + required: true + }, + }, created() { this.fetchData(); }, diff --git a/js/src/components/Event/EventList.vue b/js/src/components/Event/EventList.vue index 7972fdb1e..366370d26 100644 --- a/js/src/components/Event/EventList.vue +++ b/js/src/components/Event/EventList.vue @@ -28,12 +28,12 @@ {{ event.description }} - Organisé par {{ event.organizer.username }} + Organisé par {{ event.organizer.username }} Share - Explore - Delete + Explore + Delete @@ -98,16 +98,16 @@ this.events = response.data; }); }, - deleteEvent(id) { + deleteEvent(event) { const router = this.$router; - eventFetch('/events/' + id, this.$store, {'method': 'DELETE'}) + eventFetch(`/events/${event.organizer.username}/${event.slug}`, this.$store, {'method': 'DELETE'}) .then(() => router.push('/events')); }, - viewEvent(id) { - this.$router.push({ name: 'Event', params: { id } }) + viewEvent(event) { + this.$router.push({ name: 'Event', params: { name: event.organizer.username, slug: event.slug } }) }, downloadIcsEvent(event) { - eventFetch('/events/' + event.id + '/export', this.$store, {responseType: 'arraybuffer'}) + eventFetch(`/events/${event.organizer.username}/${event.slug}/export`, this.$store, {responseType: 'arraybuffer'}) .then((response) => response.text()) .then(response => { const blob = new Blob([response],{type: 'text/calendar'}); diff --git a/js/src/components/Group/Group.vue b/js/src/components/Group/Group.vue index 9fc268406..0b68fba8f 100644 --- a/js/src/components/Group/Group.vue +++ b/js/src/components/Group/Group.vue @@ -73,7 +73,7 @@ Membres - + stars @@ -88,7 +88,7 @@ - {{ groupAccount.account.username }} + {{ groupAccount.actor.username }} diff --git a/js/src/components/Home.vue b/js/src/components/Home.vue index f8afcf142..077bdbb23 100644 --- a/js/src/components/Home.vue +++ b/js/src/components/Home.vue @@ -50,7 +50,7 @@ export default { }, computed: { displayed_name: function() { - return this.$store.state.user.account.display_name === null ? this.$store.state.user.account.username : this.$store.state.user.account.display_name + return this.$store.state.user.actor.display_name === null ? this.$store.state.user.actor.username : this.$store.state.user.actor.display_name }, }, methods: { diff --git a/js/src/components/NavBar.vue b/js/src/components/NavBar.vue index cdc74fa10..33e40af37 100644 --- a/js/src/components/NavBar.vue +++ b/js/src/components/NavBar.vue @@ -58,7 +58,7 @@ - {{ this.displayed_name }} + {{ this.displayed_name }} @@ -97,7 +97,7 @@ }, computed: { displayed_name: function() { - return this.$store.state.user.account.display_name === null ? this.$store.state.user.account.username : this.$store.state.user.account.display_name + return this.$store.state.user.actor.display_name === null ? this.$store.state.user.actor.username : this.$store.state.user.actor.display_name }, }, methods: { diff --git a/js/src/router/index.js b/js/src/router/index.js index 02e0be052..c71bd8c4d 100644 --- a/js/src/router/index.js +++ b/js/src/router/index.js @@ -33,13 +33,6 @@ const router = new Router({ component: EventList, meta: { requiredAuth: false }, }, - { - path: '/events/:id(\\d+)', - name: 'Event', - component: Event, - props: true, - meta: { requiredAuth: false }, - }, { path: '/events/create', name: 'CreateEvent', @@ -84,14 +77,7 @@ const router = new Router({ meta: { requiredAuth: false }, }, { - path: '/accounts/:id(\\d+)', - name: 'Account', - component: Account, - props: true, - meta: { requiredAuth: false }, - }, - { - path: '/group', + path: '/groups', name: 'GroupList', component: GroupList, meta: { requiredAuth: false }, @@ -103,12 +89,26 @@ const router = new Router({ meta: { requiredAuth: true }, }, { - path: '/group/:id', + path: '/~:name', name: 'Group', component: Group, props: true, meta: { requiredAuth: false }, }, + { + path: '/@:name', + name: 'Account', + component: Account, + props: true, + meta: { requiredAuth: false }, + }, + { + path: '/@:name/:slug', + name: 'Event', + component: Event, + props: true, + meta: { requiredAuth: false }, + }, { path: "*", name: 'PageNotFound', component: PageNotFound, diff --git a/js/vue.config.js b/js/vue.config.js index 4c158214c..e0f24a3cd 100644 --- a/js/vue.config.js +++ b/js/vue.config.js @@ -1,11 +1,11 @@ -//const Dotenv = require('dotenv-webpack'); +const Dotenv = require('dotenv-webpack'); module.exports = { lintOnSave: false, compiler: true, configureWebpack: { plugins: [ - //new Dotenv(), + new Dotenv(), ], }, }; diff --git a/lib/eventos/actors/actor.ex b/lib/eventos/actors/actor.ex index 3d7d0fc09..2e5371095 100644 --- a/lib/eventos/actors/actor.ex +++ b/lib/eventos/actors/actor.ex @@ -62,7 +62,7 @@ defmodule Eventos.Actors.Actor do field :preferred_username, :string field :public_key, :string field :private_key, :string - field :manually_approves_followers, :boolean + field :manually_approves_followers, :boolean, default: false field :suspended, :boolean, default: false many_to_many :followers, Actor, join_through: Follower has_many :organized_events, Event, [foreign_key: :organizer_actor_id] @@ -92,7 +92,7 @@ defmodule Eventos.Actors.Actor do changes = %Actor{} |> Ecto.Changeset.cast(params, [:url, :outbox_url, :inbox_url, :following_url, :followers_url, :type, :name, :domain, :summary, :preferred_username, :public_key, :manually_approves_followers]) - |> validate_required([:url, :outbox_url, :inbox_url, :following_url, :followers_url, :type, :name, :domain, :summary, :preferred_username, :public_key, :manually_approves_followers]) + |> validate_required([:url, :outbox_url, :inbox_url, :type, :name, :domain, :summary, :preferred_username, :public_key]) |> unique_constraint(:preferred_username, name: :actors_preferred_username_domain_index) |> validate_length(:summary, max: 5000) |> validate_length(:preferred_username, max: 100) @@ -101,21 +101,6 @@ defmodule Eventos.Actors.Actor do Logger.debug("Remote actor creation") Logger.debug(inspect changes) changes - # if changes.valid? do - # case changes.changes[:info]["source_data"] do - # %{"followers" => followers} -> - # changes - # |> put_change(:follower_address, followers) - # - # _ -> - # followers = User.ap_followers(%User{nickname: changes.changes[:nickname]}) - # - # changes - # |> put_change(:follower_address, followers) - # end - # else - # changes - # end end def get_or_fetch_by_url(url) do diff --git a/lib/eventos/actors/actors.ex b/lib/eventos/actors/actors.ex index 0b442428a..27aa9bb20 100644 --- a/lib/eventos/actors/actors.ex +++ b/lib/eventos/actors/actors.ex @@ -150,10 +150,6 @@ defmodule Eventos.Actors do defp blank?(n), do: n def insert_or_update_actor(data) do - data = - data - |> Map.put(:name, blank?(data[:preferred_username]) || data[:name]) - cs = Actor.remote_actor_creation(data) Repo.insert(cs, on_conflict: [set: [public_key: data.public_key]], conflict_target: [:preferred_username, :domain]) end @@ -207,6 +203,19 @@ defmodule Eventos.Actors do Repo.one from a in Actor, where: a.preferred_username == ^name and is_nil(a.domain) end + def get_local_actor_by_name_with_everything(name) do + actor = Repo.one from a in Actor, where: a.preferred_username == ^name and is_nil(a.domain) + Repo.preload(actor, :organized_events) + end + + def get_actor_by_name_with_everything(name) do + actor = case String.split(name, "@") do + [name] -> Repo.one from a in Actor, where: a.preferred_username == ^name and is_nil(a.domain) + [name, domain] -> Repo.one from a in Actor, where: a.preferred_username == ^name and a.domain == ^domain + end + Repo.preload(actor, :organized_events) + end + def get_or_fetch_by_url(url) do if actor = get_actor_by_url(url) do actor diff --git a/lib/eventos/events/event.ex b/lib/eventos/events/event.ex index ab9752ba9..4abae88ce 100644 --- a/lib/eventos/events/event.ex +++ b/lib/eventos/events/event.ex @@ -32,7 +32,7 @@ defmodule Eventos.Events.Event do """ use Ecto.Schema import Ecto.Changeset - alias Eventos.Events.{Event, Participant, Request, Tag, Category, Session, Track} + alias Eventos.Events.{Event, Participant, Tag, Category, Session, Track} alias Eventos.Events.Event.TitleSlug alias Eventos.Actors.Actor alias Eventos.Addresses.Address @@ -55,7 +55,6 @@ defmodule Eventos.Events.Event do many_to_many :tags, Tag, join_through: "events_tags" belongs_to :category, Category many_to_many :participants, Actor, join_through: Participant - has_many :event_request, Request has_many :tracks, Track has_many :sessions, Session belongs_to :address, Address diff --git a/lib/eventos/events/events.ex b/lib/eventos/events/events.ex index 94ba1e3ed..d245979ff 100644 --- a/lib/eventos/events/events.ex +++ b/lib/eventos/events/events.ex @@ -20,7 +20,8 @@ defmodule Eventos.Events do """ def list_events do - Repo.all(Event) + events = Repo.all(Event) + Repo.preload(events, [:organizer_actor]) end def get_events_for_actor(%Actor{id: actor_id} = _actor, page \\ 1, limit \\ 10) do @@ -94,12 +95,17 @@ defmodule Eventos.Events do @spec get_event_full_by_name_and_slug!(String.t, String.t) :: Event.t def get_event_full_by_name_and_slug!(name, slug) do - event = Repo.one( - from e in Event, - join: a in Actor, - on: a.id == e.organizer_actor_id and a.name == ^name, - where: e.slug == ^slug - ) + query = case String.split(name, "@") do + [name, domain] -> from e in Event, + join: a in Actor, + on: a.id == e.organizer_actor_id and a.preferred_username == ^name and a.domain == ^domain, + where: e.slug == ^slug + [name] -> from e in Event, + join: a in Actor, + on: a.id == e.organizer_actor_id and a.preferred_username == ^name and is_nil(a.domain), + where: e.slug == ^slug + end + event = Repo.one(query) Repo.preload(event, [:organizer_actor, :category, :sessions, :tracks, :tags, :participants, :address]) end diff --git a/lib/eventos_web/controllers/account_controller.ex b/lib/eventos_web/controllers/account_controller.ex deleted file mode 100644 index 85ee39020..000000000 --- a/lib/eventos_web/controllers/account_controller.ex +++ /dev/null @@ -1,41 +0,0 @@ -defmodule EventosWeb.ActorController do - @moduledoc """ - Controller for Actors - """ - use EventosWeb, :controller - - alias Eventos.Actors - alias Eventos.Actors.Actor - - action_fallback EventosWeb.FallbackController - - def index(conn, _params) do - actors = Actors.list_actors() - render(conn, "index.json", actors: actors) - end - - def show(conn, %{"id" => id}) do - actor = Actors.get_actor_with_everything!(id) - render(conn, "show.json", actor: actor) - end - - def update(conn, %{"id" => id, "actor" => actor_params}) do - actor = Actors.get_actor!(id) - - with {:ok, %Actor{} = actor} <- Actors.update_actor(actor, actor_params) do - render(conn, "show.json", actor: actor) - end - end - - def delete(conn, %{"id" => id_str}) do - {id, _} = Integer.parse(id_str) - if Guardian.Plug.current_resource(conn).actor.id == id do - actor = Actors.get_actor!(id) - with {:ok, %Actor{}} <- Actors.delete_actor(actor) do - send_resp(conn, :no_content, "") - end - else - send_resp(conn, 401, "") - end - end -end diff --git a/lib/eventos_web/controllers/actor_controller.ex b/lib/eventos_web/controllers/actor_controller.ex new file mode 100644 index 000000000..b37c6c21e --- /dev/null +++ b/lib/eventos_web/controllers/actor_controller.ex @@ -0,0 +1,50 @@ +defmodule EventosWeb.ActorController do + @moduledoc """ + Controller for Actors + """ + use EventosWeb, :controller + + alias Eventos.Actors + alias Eventos.Actors.Actor + alias Eventos.Service.ActivityPub + + action_fallback EventosWeb.FallbackController + + def index(conn, _params) do + actors = Actors.list_actors() + render(conn, "index.json", actors: actors) + end + + def show(conn, %{"name" => name}) do + actor = Actors.get_actor_by_name_with_everything(name) + render(conn, "show.json", actor: actor) + end + + def search(conn, %{"name" => name}) do + with {:ok, actor} <- ActivityPub.make_actor_from_nickname(name) do + render(conn, "acccount_basic.json", actor: actor) + else + {:error, err} -> json(conn, err) + end + end + + def update(conn, %{"name" => name, "actor" => actor_params}) do + actor = Actors.get_local_actor_by_name(name) + + with {:ok, %Actor{} = actor} <- Actors.update_actor(actor, actor_params) do + render(conn, "show.json", actor: actor) + end + end + +# def delete(conn, %{"id" => id_str}) do +# {id, _} = Integer.parse(id_str) +# if Guardian.Plug.current_resource(conn).actor.id == id do +# actor = Actors.get_actor!(id) +# with {:ok, %Actor{}} <- Actors.delete_actor(actor) do +# send_resp(conn, :no_content, "") +# end +# else +# send_resp(conn, 401, "") +# end +# end +end diff --git a/lib/eventos_web/controllers/event_controller.ex b/lib/eventos_web/controllers/event_controller.ex index 1da9ba84a..08882b5bf 100644 --- a/lib/eventos_web/controllers/event_controller.ex +++ b/lib/eventos_web/controllers/event_controller.ex @@ -35,28 +35,27 @@ defmodule EventosWeb.EventController do end end - def show(conn, %{"id" => id}) do - event = Events.get_event_full!(id) + def show(conn, %{"username" => username, "slug" => slug}) do + event = Events.get_event_full_by_name_and_slug!(username, slug) render(conn, "show.json", event: event) end - def export_to_ics(conn, %{"id" => id}) do - event = id - |> Events.get_event!() + def export_to_ics(conn, %{"username" => username, "slug" => slug}) do + event = Events.get_event_full_by_name_and_slug!(username, slug) |> ICalendar.export_event() send_resp(conn, 200, event) end - def update(conn, %{"id" => id, "event" => event_params}) do - event = Events.get_event!(id) + def update(conn, %{"username" => username, "slug" => slug, "event" => event_params}) do + event = Events.get_event_full_by_name_and_slug!(username, slug) with {:ok, %Event{} = event} <- Events.update_event(event, event_params) do render(conn, "show_simple.json", event: event) end end - def delete(conn, %{"id" => id}) do - event = Events.get_event!(id) + def delete(conn, %{"username" => username, "slug" => slug}) do + event = Events.get_event_full_by_name_and_slug!(username, slug) with {:ok, %Event{}} <- Events.delete_event(event) do send_resp(conn, :no_content, "") end diff --git a/lib/eventos_web/router.ex b/lib/eventos_web/router.ex index 8850952f8..b49c3ad6b 100644 --- a/lib/eventos_web/router.ex +++ b/lib/eventos_web/router.ex @@ -38,12 +38,16 @@ defmodule EventosWeb.Router do post "/users", UserController, :register post "/login", UserSessionController, :sign_in #resources "/groups", GroupController, only: [:index, :show] - resources "/events", EventController, only: [:index, :show] + get "/events", EventController, :index + get "/events/:username/:slug", EventController, :show + get "/events/:username/:slug/ics", EventController, :export_to_ics + get "/events/:username/:slug/tracks", TrackController, :show_tracks_for_event + get "/events/:username/:slug/sessions", SessionController, :show_sessions_for_event resources "/comments", CommentController, only: [:show] - get "/events/:id/ics", EventController, :export_to_ics - get "/events/:id/tracks", TrackController, :show_tracks_for_event - get "/events/:id/sessions", SessionController, :show_sessions_for_event - resources "/actors", ActorController, only: [:index, :show] + + get "/actors", ActorController, :index + get "/actors/search/:name", ActorController, :search + get "/actors/:name", ActorController, :show resources "/tags", TagController, only: [:index, :show] resources "/categories", CategoryController, only: [:index, :show] resources "/sessions", SessionController, only: [:index, :show] @@ -61,8 +65,11 @@ defmodule EventosWeb.Router do get "/user", UserController, :show_current_actor post "/sign-out", UserSessionController, :sign_out resources "/users", UserController, except: [:new, :edit, :show] - resources "/actors", ActorController, except: [:new, :edit] - resources "/events", EventController + patch "/actors/:name", ActorController, :update + post "/events", EventController, :create + patch "/events/:username/:slug", EventController, :update + put "/events/:username/:slug", EventController, :update + delete "/events/:username/:slug", EventController, :delete resources "/comments", CommentController, except: [:new, :edit] #post "/events/:id/request", EventRequestController, :create_for_event resources "/participant", ParticipantController diff --git a/lib/eventos_web/views/account_view.ex b/lib/eventos_web/views/actor_view.ex similarity index 79% rename from lib/eventos_web/views/account_view.ex rename to lib/eventos_web/views/actor_view.ex index 51a4d7474..a58d0fdf6 100644 --- a/lib/eventos_web/views/account_view.ex +++ b/lib/eventos_web/views/actor_view.ex @@ -19,10 +19,10 @@ defmodule EventosWeb.ActorView do def render("acccount_basic.json", %{actor: actor}) do %{id: actor.id, - username: actor.username, + username: actor.preferred_username, domain: actor.domain, - display_name: actor.display_name, - description: actor.description, + display_name: actor.name, + description: actor.summary, # public_key: actor.public_key, suspended: actor.suspended, url: actor.url, @@ -31,14 +31,14 @@ defmodule EventosWeb.ActorView do def render("actor.json", %{actor: actor}) do %{id: actor.id, - username: actor.username, + username: actor.preferred_username, domain: actor.domain, - display_name: actor.display_name, - description: actor.description, + display_name: actor.name, + description: actor.summary, # public_key: actor.public_key, suspended: actor.suspended, url: actor.url, - organized_events: render_many(actor.organized_events, EventView, "event_simple.json") + organized_events: render_many(actor.organized_events, EventView, "event_for_actor.json") } end end diff --git a/lib/eventos_web/views/event_view.ex b/lib/eventos_web/views/event_view.ex index 3bfe03023..70b859f2c 100644 --- a/lib/eventos_web/views/event_view.ex +++ b/lib/eventos_web/views/event_view.ex @@ -17,12 +17,23 @@ defmodule EventosWeb.EventView do %{data: render_one(event, EventView, "event.json")} end + def render("event_for_actor.json", %{event: event}) do + %{id: event.id, + title: event.title, + slug: event.slug + } + end + def render("event_simple.json", %{event: event}) do %{id: event.id, title: event.title, + slug: event.slug, description: event.description, begins_on: event.begins_on, ends_on: event.ends_on, + organizer: %{ + username: event.organizer_actor.preferred_username + }, } end @@ -33,7 +44,6 @@ defmodule EventosWeb.EventView do begins_on: event.begins_on, ends_on: event.ends_on, organizer: render_one(event.organizer_actor, ActorView, "acccount_basic.json"), - group: render_one(event.organizer_group, GroupView, "group_basic.json"), participants: render_many(event.participants, ActorView, "show_basic.json"), address: render_one(event.address, AddressView, "address.json"), } diff --git a/lib/service/activity_pub/activity_pub.ex b/lib/service/activity_pub/activity_pub.ex index cd5360650..9d33677f9 100644 --- a/lib/service/activity_pub/activity_pub.ex +++ b/lib/service/activity_pub/activity_pub.ex @@ -241,6 +241,11 @@ defmodule Eventos.Service.ActivityPub do "type" => "Image", "url" => [%{"href" => data["image"]["url"]}] } + name = if String.trim(data["name"]) === "" do + data["preferredUsername"] + else + data["name"] + end user_data = %{ url: data["id"], @@ -250,7 +255,7 @@ defmodule Eventos.Service.ActivityPub do "banner" => banner }, avatar: avatar, - name: data["name"], + name: name, preferred_username: data["preferredUsername"], follower_address: data["followers"], summary: data["summary"], @@ -269,7 +274,7 @@ defmodule Eventos.Service.ActivityPub do end @spec fetch_public_activities_for_actor(Actor.t, integer(), integer()) :: list() - def fetch_public_activities_for_actor(%Actor{} = actor, page \\ 10, limit \\ 1) do + def fetch_public_activities_for_actor(%Actor{} = actor, page \\ 10, limit \\ 10) do {:ok, events, total} = Events.get_events_for_actor(actor, page, limit) activities = Enum.map(events, fn event -> {:ok, activity} = event_to_activity(event) diff --git a/lib/service/web_finger/web_finger.ex b/lib/service/web_finger/web_finger.ex index 364c39654..50532888c 100644 --- a/lib/service/web_finger/web_finger.ex +++ b/lib/service/web_finger/web_finger.ex @@ -80,8 +80,9 @@ defmodule Eventos.Service.WebFinger do address = "http://#{domain}/.well-known/webfinger?resource=acct:#{actor}" - with response <- HTTPoison.get(address, [Accept: "application/json"],follow_redirect: true), - {:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <- response do + Logger.debug(inspect address) + with response <- HTTPoison.get!(address, [Accept: "application/json, application/activity+json, application/jrd+json"],follow_redirect: true), + %{status_code: status_code, body: body} when status_code in 200..299 <- response do {:ok, doc} = Jason.decode(body) webfinger_from_json(doc) else diff --git a/priv/repo/migrations/20180517100700_move_from_account_to_actor.exs b/priv/repo/migrations/20180517100700_move_from_account_to_actor.exs index 2efe98c83..81b4822af 100644 --- a/priv/repo/migrations/20180517100700_move_from_account_to_actor.exs +++ b/priv/repo/migrations/20180517100700_move_from_account_to_actor.exs @@ -26,11 +26,11 @@ defmodule Eventos.Repo.Migrations.MoveFromAccountToActor do alter table("actors") do add :inbox_url, :string add :outbox_url, :string - add :following_url, :string - add :followers_url, :string - add :shared_inbox_url, :string + add :following_url, :string, null: true + add :followers_url, :string, null: true + add :shared_inbox_url, :string, null: false, default: "" add :type, :actor_type - add :manually_approves_followers, :boolean + add :manually_approves_followers, :boolean, default: false modify :name, :string, null: true modify :preferred_username, :string, null: false end @@ -49,6 +49,8 @@ defmodule Eventos.Repo.Migrations.MoveFromAccountToActor do end rename table("comments"), :account_id, to: :actor_id + + rename table("users"), :account_id, to: :actor_id end def down do @@ -91,6 +93,8 @@ defmodule Eventos.Repo.Migrations.MoveFromAccountToActor do rename table("comments"), :actor_id, to: :account_id + rename table("users"), :actor_id, to: :account_id + drop index("accounts", [:preferred_username, :domain], name: :actors_preferred_username_domain_index) drop table("followers")
{{ event.description }}
Organisé par {{ event.organizer.username }}