diff --git a/.env.template b/.env.template new file mode 100644 index 000000000..e49bfb2b3 --- /dev/null +++ b/.env.template @@ -0,0 +1,25 @@ +# Database settings +POSTGRES_USER=mobilizon +POSTGRES_PASSWORD=changethis +POSTGRES_DB=mobilizon +POSTGRES_PORT=5432 + +# Instance configuration +MOBILIZON_INSTANCE_REGISTRATIONS_OPEN=false +MOBILIZON_INSTANCE_NAME=My Mobilizon Instance +MOBILIZON_INSTANCE_HOST=mobilizon.lan +MOBILIZON_INSTANCE_PORT=4000 + +MOBILIZON_INSTANCE_SECRET_KEY_BASE=changethis +MOBILIZON_INSTANCE_SECRET_KEY=changethis + +MOBILIZON_INSTANCE_EMAIL=noreply@mobilizon.lan +MOBILIZON_REPLY_EMAIL=contact@mobilizon.lan + +# Email settings +MOBILIZON_SMTP_SERVER=localhost +MOBILIZON_SMTP_PORT=25 +MOBILIZON_SMTP_HOSTNAME=localhost +MOBILIZON_SMTP_USERNAME=noreply@mobilizon.lan +MOBILIZON_SMTP_PASSWORD=password +MOBILIZON_SMTP_SSL=false diff --git a/.gitignore b/.gitignore index fb8ad471f..b4b15332c 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ release/ docker/production/.env test-junit-report.xml js/junit.xml +.env \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4aec00d19..28f6f4443 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -235,7 +235,7 @@ package-app: only: - tags@framasoft/mobilizon artifacts: - expire_in: never + expire_in: 30 days paths: - release diff --git a/.sobelow-skips b/.sobelow-skips index 70978cfa5..28a98366b 100644 --- a/.sobelow-skips +++ b/.sobelow-skips @@ -7,4 +7,5 @@ 155A1FB53DE39EC8EFCFD7FB94EA823D 73B351E4CB3AF715AD450A085F5E6304 BBACD7F0BACD4A6D3010C26604671692 -6D4D4A4821B93BCFAC9CDBB367B34C4B \ No newline at end of file +6D4D4A4821B93BCFAC9CDBB367B34C4B +5674F0D127852889ED0132DC2F442AAB \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d4ebbe30..04a77beb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,69 @@ 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). +## 1.3.0 - 2021-08-12 + +### Added + +- **Allow remote group moderators to edit group events and posts** +- **Allow events to hold metadata information, either preconfigured (live video URL, price details, accessibility informations,…), either through a free key/value form.** Metadata concerning live video feeds linking to PeerTube, YouTube & Twitch will benefit from iframe integration. +- Add the possibility to create profiles and groups from CLI +- Add the possibility to create a profile at the same time when creating an user from CLI +- Add the possibility to create users with LDAP provider from CLI +- Added back support for Docker-compose based development +- Added rel=canonical and meta robots noindex tags to public pages from remote groups, in order to avoid them being indexed by Google +- Allow members-restricted posts to be viewable by instance moderators (for moderation purposes) +- Added a filter to resize pictures bigger than 1920x1080 +- Allow to deny registration by email or email domain +- Added missing index on participants url +- Added a loading wheel to show that events are loading on some views + +### Changed + +- Made server only listen on IPv4 in the install template +- Improve identity picker to have a fixed height and allow filtering between your identities and group contacts +- Leaflet map controls (zoom/locate) are now translatable +- Show exactly 12 events on the Explore page + +### Fixed + +- Fixed links contained in event & post description that didn't open in new tabs +- Add back missing RSS/ical links on public group pages +- Fixed links to Framacolibri forum +- Fixed drafts and restricted visibility events & posts listed on group page +- Fixed notification page on Safari +- Fixed profile edition +- Fixed Feed Token recreation +- Fixed media cleaner job +- Fixed english being always used as a language instead of the default one set when the request has no `Accept-Language` header (such as Google index bots) +- Fixed Ecto validation errors not being translated and interpolated +- Fixed `lang` attribute not being properly set with the language currently used +- Fixed federated posts having wrong visibility setting +- Fixed unused CSS filter on homepage rendering wrong on Webkit +- Fixed handling SSL being already started in LDAP connection +- Fixed an Apollo cache issue when registrering your first profile +- Fixed the Docker image missing ca-certificates +- Fixed missing pagination on Explore page featured events +- Fixed broken popup warning when editing an event +- Fixed GraphQL Playground (again) +- Fixed Coordinates mixmatch between latitude and longitude in iCalendar export and federation +- Fixed token refreshment issues +- Fixed search from 404 page + + +### Translations + +- Catalan +- Chinese (Traditional) +- Finnish +- French +- Gaelic +- Galician +- German +- Indonesian +- Russian +- Spanish + ## 1.2.3 - 2021-07-02 ### Changed diff --git a/Dockerfile b/Dockerfile index 01cde6868..0c80b83da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -FROM bitwalker/alpine-elixir:latest +FROM elixir:alpine -RUN apk add --no-cache inotify-tools postgresql-client yarn file make gcc libc-dev argon2 imagemagick cmake build-base libwebp-tools bash ncurses +RUN apk add --no-cache inotify-tools postgresql-client yarn file make gcc libc-dev argon2 imagemagick cmake build-base libwebp-tools bash ncurses git RUN mix local.hex --force && mix local.rebar --force diff --git a/Makefile b/Makefile index c939bfdc6..f0eb6eff6 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,13 @@ init: @bash docker/message.sh "start" make start +setup: stop + @bash docker/message.sh "Compiling everything" + docker-compose run --rm api bash -c 'mix deps.get; yarn --cwd "js"; yarn --cwd "js" build:pictures; mix ecto.create; mix ecto.migrate' +migrate: + docker-compose run --rm api mix ecto.migrate +logs: + docker-compose logs -f start: stop @bash docker/message.sh "starting Mobilizon with docker" docker-compose up -d api diff --git a/config/config.exs b/config/config.exs index 2924abe68..e77f1d336 100644 --- a/config/config.exs +++ b/config/config.exs @@ -18,6 +18,7 @@ config :mobilizon, :instance, hostname: "localhost", registrations_open: true, registration_email_allowlist: [], + registration_email_denylist: [], languages: [], default_language: "fr", demo: false, @@ -65,9 +66,11 @@ config :mime, :types, %{ config :mobilizon, Mobilizon.Web.Upload, uploader: Mobilizon.Web.Upload.Uploader.Local, filters: [ - Mobilizon.Web.Upload.Filter.Dedupe, Mobilizon.Web.Upload.Filter.AnalyzeMetadata, - Mobilizon.Web.Upload.Filter.Optimize + Mobilizon.Web.Upload.Filter.Resize, + Mobilizon.Web.Upload.Filter.Optimize, + Mobilizon.Web.Upload.Filter.BlurHash, + Mobilizon.Web.Upload.Filter.Dedupe ], allow_list_mime_types: ["image/gif", "image/jpeg", "image/png", "image/webp"], link_name: true, diff --git a/config/dev.exs b/config/dev.exs index 23e63beb0..660e6dd58 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -1,21 +1,15 @@ import Config -# For development, we disable any cache and enable -# debugging and code reloading. -# -# The watchers configuration can be used to run external -# watchers to your application. For example, we use it -# with brunch.io to recompile .js and .css sources. config :mobilizon, Mobilizon.Web.Endpoint, http: [ - ip: {127, 0, 0, 1}, - port: 4000 + port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_HOST_PORT", "4000")) ], url: [ host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.local"), - port: 80, + port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_HOST_PORT", "80")), scheme: "http" ], + secret_key_base: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY_BASE", "changethis"), debug_errors: true, code_reloader: true, check_origin: false, @@ -91,6 +85,9 @@ config :mobilizon, :instance, registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN") == "true", groups: true +config :mobilizon, Mobilizon.Web.Auth.Guardian, + secret_key: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY", "changethis") + # config :mobilizon, :activitypub, sign_object_fetches: false config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "uploads" diff --git a/config/docker.exs b/config/docker.exs index 50252737a..dec3d28ee 100644 --- a/config/docker.exs +++ b/config/docker.exs @@ -2,7 +2,7 @@ import Config -listen_ip = System.get_env("MOBILIZON_INSTANCE_LISTEN_IP", "::") +listen_ip = System.get_env("MOBILIZON_INSTANCE_LISTEN_IP", "127.0.0.1") listen_ip = case listen_ip |> to_charlist() |> :inet.parse_address() do diff --git a/docker-compose.yml b/docker-compose.yml index 8726415ba..9b75aad9a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,14 @@ -version: "3" - +version: "3.2" services: postgres: container_name: mobilizon_db restart: unless-stopped - image: postgis/postgis:13-3.0 + image: postgis/postgis environment: - POSTGRES_PASSWORD: postgres - POSTGRES_DB: mobilizon_dev + - POSTGRES_USER + - POSTGRES_PASSWORD + - POSTGRES_DB + - POSTGRES_PORT volumes: - pgdata:/var/lib/postgresql/data api: @@ -17,29 +18,24 @@ services: volumes: - ".:/app" ports: - - "4000:4000" + - 4000:4000 depends_on: - postgres environment: MIX_ENV: "dev" DOCKER: "true" MOBILIZON_INSTANCE_NAME: My Mobilizon Instance - MOBILIZON_INSTANCE_HOST: mobilizon.me + MOBILIZON_INSTANCE_HOST: localhost + MOBILIZON_INSTANCE_HOST_PORT: 4000 + MOBILIZON_INSTANCE_PORT: 4000 MOBILIZON_INSTANCE_EMAIL: noreply@mobilizon.me MOBILIZON_INSTANCE_REGISTRATIONS_OPEN: "true" - MOBILIZON_DATABASE_PASSWORD: postgres - MOBILIZON_DATABASE_USERNAME: postgres - MOBILIZON_DATABASE_DBNAME: mobilizon_dev + MOBILIZON_DATABASE_PASSWORD: ${POSTGRES_PASSWORD} + MOBILIZON_DATABASE_USERNAME: ${POSTGRES_USER} + MOBILIZON_DATABASE_DBNAME: ${POSTGRES_DB} MOBILIZON_DATABASE_HOST: postgres - command: > - sh -c "cd js && - yarn install && - cd ../ && - mix deps.get && - mix compile && - mix ecto.create && - mix ecto.migrate && - mix phx.server" + MOBILIZON_DATABASE_PORT: ${POSTGRES_PORT} + command: sh -c "mix phx.server" volumes: pgdata: .: diff --git a/docker/production/Dockerfile b/docker/production/Dockerfile index 46447aaf8..5d09d0b9c 100644 --- a/docker/production/Dockerfile +++ b/docker/production/Dockerfile @@ -45,7 +45,7 @@ LABEL org.opencontainers.image.title="mobilizon" \ org.opencontainers.image.revision=$VCS_REF \ org.opencontainers.image.created=$BUILD_DATE -RUN apk add --no-cache openssl ncurses-libs file postgresql-client libgcc libstdc++ imagemagick +RUN apk add --no-cache openssl ca-certificates ncurses-libs file postgresql-client libgcc libstdc++ imagemagick RUN mkdir -p /app/uploads && chown nobody:nobody /app/uploads RUN mkdir -p /etc/mobilizon && chown nobody:nobody /etc/mobilizon diff --git a/js/package.json b/js/package.json index bbecc39af..084bd09d1 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "mobilizon", - "version": "1.2.3", + "version": "1.3.0", "private": true, "scripts": { "serve": "vue-cli-service serve", @@ -29,7 +29,7 @@ "@tiptap/extension-underline": "^2.0.0-beta.7", "@tiptap/starter-kit": "^2.0.0-beta.37", "@tiptap/vue-2": "^2.0.0-beta.21", - "@vue/apollo-option": "^4.0.0-alpha.11", + "@vue/apollo-option": "4.0.0-alpha.11", "apollo-absinthe-upload-link": "^1.5.0", "blurhash": "^1.1.3", "buefy": "^0.9.0", @@ -72,14 +72,14 @@ "@types/prosemirror-view": "^1.11.4", "@typescript-eslint/eslint-plugin": "^4.18.0", "@typescript-eslint/parser": "^4.18.0", - "@vue/cli-plugin-babel": "~5.0.0-beta.2", - "@vue/cli-plugin-e2e-cypress": "~5.0.0-beta.2", - "@vue/cli-plugin-eslint": "~5.0.0-beta.2", - "@vue/cli-plugin-pwa": "~5.0.0-beta.2", - "@vue/cli-plugin-router": "~5.0.0-beta.2", - "@vue/cli-plugin-typescript": "~5.0.0-beta.2", - "@vue/cli-plugin-unit-jest": "~5.0.0-beta.2", - "@vue/cli-service": "~5.0.0-beta.2", + "@vue/cli-plugin-babel": "~5.0.0-beta.3", + "@vue/cli-plugin-e2e-cypress": "~5.0.0-beta.3", + "@vue/cli-plugin-eslint": "~5.0.0-beta.3", + "@vue/cli-plugin-pwa": "~5.0.0-beta.3", + "@vue/cli-plugin-router": "~5.0.0-beta.3", + "@vue/cli-plugin-typescript": "~5.0.0-beta.3", + "@vue/cli-plugin-unit-jest": "~5.0.0-beta.3", + "@vue/cli-service": "~5.0.0-beta.3", "@vue/eslint-config-prettier": "^6.0.0", "@vue/eslint-config-typescript": "^7.0.0", "@vue/test-utils": "^1.1.0", @@ -89,10 +89,11 @@ "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-vue": "^7.6.0", "flush-promises": "^1.0.2", + "jest": "^26.6.3", "jest-junit": "^12.0.0", "mock-apollo-client": "^1.1.0", "prettier": "^2.2.1", - "prettier-eslint": "^12.0.0", + "prettier-eslint": "^13.0.0", "sass": "^1.34.1", "sass-loader": "^12.0.0", "ts-jest": "^26.5.3", @@ -101,5 +102,8 @@ "vue-jest": "^4.0.1", "vue-template-compiler": "^2.6.11", "webpack-cli": "^4.7.0" + }, + "resolutions": { + "webpack": "5.44.0" } } diff --git a/js/public/img/fediverse_monochrome.svg b/js/public/img/fediverse_monochrome.svg new file mode 100644 index 000000000..ada84802c --- /dev/null +++ b/js/public/img/fediverse_monochrome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/js/public/img/peertube_monochrome.svg b/js/public/img/peertube_monochrome.svg new file mode 100644 index 000000000..90a90f6f6 --- /dev/null +++ b/js/public/img/peertube_monochrome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/js/public/img/sign_language_monochrome.svg b/js/public/img/sign_language_monochrome.svg new file mode 100644 index 000000000..33256bedf --- /dev/null +++ b/js/public/img/sign_language_monochrome.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/js/src/apollo/utils.ts b/js/src/apollo/utils.ts index 917936c3a..84ba969e9 100644 --- a/js/src/apollo/utils.ts +++ b/js/src/apollo/utils.ts @@ -56,7 +56,7 @@ export const typePolicies: TypePolicies = { }, Person: { fields: { - organizedEvents: pageLimitPagination(), + organizedEvents: paginatedLimitPagination(), participations: paginatedLimitPagination(["eventId"]), memberships: paginatedLimitPagination(["group"]), }, @@ -104,6 +104,11 @@ export async function refreshAccessToken( const refreshToken = localStorage.getItem(AUTH_REFRESH_TOKEN); + if (!refreshToken) { + console.debug("Refresh token not found"); + return false; + } + console.log("Refreshing access token."); try { @@ -118,6 +123,7 @@ export async function refreshAccessToken( return true; } catch (err) { + console.debug("Failed to refresh token"); return false; } } @@ -165,12 +171,13 @@ function doMerge( args: Record | null ): Array { const merged = existing && Array.isArray(existing) ? existing.slice(0) : []; + const previous = incoming && Array.isArray(incoming) ? incoming.slice(0) : []; let res; if (args) { // Assume an page of 1 if args.page omitted. const { page = 1, limit = 10 } = args; - for (let i = 0; i < incoming.length; ++i) { - merged[(page - 1) * limit + i] = incoming[i]; + for (let i = 0; i < previous.length; ++i) { + merged[(page - 1) * limit + i] = previous[i]; } res = merged; } else { @@ -178,7 +185,7 @@ function doMerge( // to receive any arguments, so you might prefer to throw an // exception here, instead of recovering by appending incoming // onto the existing array. - res = [...merged, ...incoming]; + res = [...merged, ...previous]; // eslint-disable-next-line no-underscore-dangle res = uniqBy(res, (elem: any) => elem.__ref); } diff --git a/js/src/components/Editor.vue b/js/src/components/Editor.vue index f0b5a0eac..3e6491b76 100644 --- a/js/src/components/Editor.vue +++ b/js/src/components/Editor.vue @@ -250,7 +250,9 @@ export default class EditorComponent extends Vue { Mention.configure(MentionOptions), CustomImage, Underline, - Link, + Link.configure({ + HTMLAttributes: { target: "_blank", rel: "noopener noreferrer ugc" }, + }), CharacterCount.configure({ limit: this.maxSize, }), diff --git a/js/src/components/Event/EventBanner.vue b/js/src/components/Event/EventBanner.vue index 1e82f0c38..5e653725d 100644 --- a/js/src/components/Event/EventBanner.vue +++ b/js/src/components/Event/EventBanner.vue @@ -5,6 +5,7 @@ diff --git a/js/src/components/Event/EventMetadataBlock.vue b/js/src/components/Event/EventMetadataBlock.vue index be72e52bf..48ab50fbf 100644 --- a/js/src/components/Event/EventMetadataBlock.vue +++ b/js/src/components/Event/EventMetadataBlock.vue @@ -2,7 +2,18 @@

{{ title }}

- + + + + +

@@ -36,6 +47,13 @@ div.eventMetadataBlock { &.padding-left { padding: 0 20px; + + a { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } } } } diff --git a/js/src/components/Event/EventMetadataItem.vue b/js/src/components/Event/EventMetadataItem.vue new file mode 100644 index 000000000..9a950b860 --- /dev/null +++ b/js/src/components/Event/EventMetadataItem.vue @@ -0,0 +1,140 @@ + + + diff --git a/js/src/components/Event/EventMetadataList.vue b/js/src/components/Event/EventMetadataList.vue new file mode 100644 index 000000000..b6b863e77 --- /dev/null +++ b/js/src/components/Event/EventMetadataList.vue @@ -0,0 +1,209 @@ + + diff --git a/js/src/components/Event/EventMetadataSidebar.vue b/js/src/components/Event/EventMetadataSidebar.vue new file mode 100644 index 000000000..af567ee76 --- /dev/null +++ b/js/src/components/Event/EventMetadataSidebar.vue @@ -0,0 +1,450 @@ + + + diff --git a/js/src/components/Event/Integrations/Etherpad.vue b/js/src/components/Event/Integrations/Etherpad.vue new file mode 100644 index 000000000..afba2f326 --- /dev/null +++ b/js/src/components/Event/Integrations/Etherpad.vue @@ -0,0 +1,38 @@ + + + diff --git a/js/src/components/Event/Integrations/JitsiMeet.vue b/js/src/components/Event/Integrations/JitsiMeet.vue new file mode 100644 index 000000000..2bee04aab --- /dev/null +++ b/js/src/components/Event/Integrations/JitsiMeet.vue @@ -0,0 +1,38 @@ + + + diff --git a/js/src/components/Event/Integrations/PeerTube.vue b/js/src/components/Event/Integrations/PeerTube.vue new file mode 100644 index 000000000..db4ccaed2 --- /dev/null +++ b/js/src/components/Event/Integrations/PeerTube.vue @@ -0,0 +1,55 @@ + + + diff --git a/js/src/components/Event/Integrations/Twitch.vue b/js/src/components/Event/Integrations/Twitch.vue new file mode 100644 index 000000000..a89f740c4 --- /dev/null +++ b/js/src/components/Event/Integrations/Twitch.vue @@ -0,0 +1,56 @@ + + + diff --git a/js/src/components/Event/Integrations/YouTube.vue b/js/src/components/Event/Integrations/YouTube.vue new file mode 100644 index 000000000..2dc188691 --- /dev/null +++ b/js/src/components/Event/Integrations/YouTube.vue @@ -0,0 +1,56 @@ + + + diff --git a/js/src/components/Event/OrganizerPicker.vue b/js/src/components/Event/OrganizerPicker.vue index c9d8baf45..2a6368fd9 100644 --- a/js/src/components/Event/OrganizerPicker.vue +++ b/js/src/components/Event/OrganizerPicker.vue @@ -1,11 +1,14 @@ @@ -1396,60 +1217,6 @@ div.sidebar { top: 50px; padding: 1rem; } - - div.address-wrapper { - display: flex; - flex: 1; - flex-wrap: wrap; - - div.address { - flex: 1; - - .map-show-button { - cursor: pointer; - } - - address { - font-style: normal; - flex-wrap: wrap; - display: flex; - justify-content: flex-start; - - span.addressDescription { - text-overflow: ellipsis; - white-space: nowrap; - flex: 1 0 auto; - min-width: 100%; - max-width: 4rem; - overflow: hidden; - } - - :not(.addressDescription) { - flex: 1; - min-width: 100%; - } - } - } - } - - span.online-address { - display: flex; - } - } - - ::v-deep .metadata-organized-by { - .v-popover.popover .trigger { - width: 100%; - .media-content { - width: calc(100% - 32px - 1rem); - max-width: 80vw; - - p.has-text-grey-dark { - text-overflow: ellipsis; - overflow: hidden; - } - } - } } div.event-description-comments { @@ -1541,29 +1308,6 @@ a.participations-link { font-size: 1rem; } -.map-modal { - .modal-card-head { - justify-content: flex-end; - button.delete { - margin-right: 1rem; - } - } - - section.map { - height: calc(100% - 8rem); - width: calc(100% - 20px); - } - - section.map-footer { - p.address { - margin: 1rem auto; - } - div.buttons { - justify-content: center; - } - } -} - .no-border { border: 0; cursor: auto; diff --git a/js/src/views/Group/Group.vue b/js/src/views/Group/Group.vue index cbe3e0caf..97c6e8290 100644 --- a/js/src/views/Group/Group.vue +++ b/js/src/views/Group/Group.vue @@ -1,7 +1,7 @@ @@ -470,10 +474,10 @@ {{ $t("Upcoming events") }}
{{ $t("View all events") }}
{{ $t("Latest posts") }} -
+
@@ -507,7 +511,7 @@ - ![ - MemberRole.REJECTED, - MemberRole.NOT_APPROVED, - MemberRole.INVITED, - ].includes(membership.role) - ) - .map(({ parent: { id } }) => id); - } - @Watch("isCurrentActorAGroupMember") refetchGroupData(): void { this.$apollo.queries.group.refetch(); } - get isCurrentActorAGroupMember(): boolean { - return ( - this.groupMemberships !== undefined && - this.groupMemberships.includes(this.group.id) - ); - } - get isCurrentActorARejectedGroupMember(): boolean { return ( this.person && @@ -877,6 +864,30 @@ export default class Group extends mixins(GroupMixin) { this.config.anonymous.reports.allowed) ); } + + get organizedEvents(): Paginate { + return { + total: this.group.organizedEvents.total, + elements: this.group.organizedEvents.elements.filter((event: IEvent) => { + if (this.previewPublic) { + return !event.draft; // TODO when events get visibility access add visibility constraint like below for posts + } + return true; + }), + }; + } + + get posts(): Paginate { + return { + total: this.group.posts.total, + elements: this.group.posts.elements.filter((post: IPost) => { + if (this.previewPublic) { + return !(post.draft || post.visibility == PostVisibility.PRIVATE); + } + return true; + }), + }; + } }