forked from AkkomaGang/akkoma
Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop
This commit is contained in:
commit
7ac5f210ea
221 changed files with 863 additions and 197 deletions
|
@ -65,19 +65,21 @@ unit-testing:
|
|||
- mix ecto.migrate
|
||||
- mix coveralls --preload-modules
|
||||
|
||||
federated-testing:
|
||||
stage: test
|
||||
cache: *testing_cache_policy
|
||||
services:
|
||||
- name: minibikini/postgres-with-rum:12
|
||||
alias: postgres
|
||||
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
script:
|
||||
- mix deps.get
|
||||
- mix ecto.create
|
||||
- mix ecto.migrate
|
||||
- epmd -daemon
|
||||
- mix test --trace --only federated
|
||||
# Removed to fix CI issue. In this early state it wasn't adding much value anyway.
|
||||
# TODO Fix and reinstate federated testing
|
||||
# federated-testing:
|
||||
# stage: test
|
||||
# cache: *testing_cache_policy
|
||||
# services:
|
||||
# - name: minibikini/postgres-with-rum:12
|
||||
# alias: postgres
|
||||
# command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
|
||||
# script:
|
||||
# - mix deps.get
|
||||
# - mix ecto.create
|
||||
# - mix ecto.migrate
|
||||
# - epmd -daemon
|
||||
# - mix test --trace --only federated
|
||||
|
||||
unit-testing-rum:
|
||||
stage: test
|
||||
|
@ -280,6 +282,8 @@ docker:
|
|||
IMAGE_TAG_SLUG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
|
||||
IMAGE_TAG_LATEST: $CI_REGISTRY_IMAGE:latest
|
||||
IMAGE_TAG_LATEST_STABLE: $CI_REGISTRY_IMAGE:latest-stable
|
||||
DOCKER_BUILDX_URL: https://github.com/docker/buildx/releases/download/v0.4.1/buildx-v0.4.1.linux-amd64
|
||||
DOCKER_BUILDX_HASH: 71a7d01439aa8c165a25b59c44d3f016fddbd98b
|
||||
before_script: &before-docker
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
- docker pull $IMAGE_TAG_SLUG || true
|
||||
|
@ -287,10 +291,14 @@ docker:
|
|||
- export CI_VCS_REF=$CI_COMMIT_SHORT_SHA
|
||||
allow_failure: true
|
||||
script:
|
||||
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST .
|
||||
- docker push $IMAGE_TAG
|
||||
- docker push $IMAGE_TAG_SLUG
|
||||
- docker push $IMAGE_TAG_LATEST
|
||||
- mkdir -p /root/.docker/cli-plugins
|
||||
- wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
|
||||
- echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
|
||||
- chmod +x ~/.docker/cli-plugins/docker-buildx
|
||||
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||
- docker buildx create --name mbuilder --driver docker-container --use
|
||||
- docker buildx inspect --bootstrap
|
||||
- docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST .
|
||||
tags:
|
||||
- dind
|
||||
only:
|
||||
|
@ -305,10 +313,14 @@ docker-stable:
|
|||
before_script: *before-docker
|
||||
allow_failure: true
|
||||
script:
|
||||
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST_STABLE .
|
||||
- docker push $IMAGE_TAG
|
||||
- docker push $IMAGE_TAG_SLUG
|
||||
- docker push $IMAGE_TAG_LATEST_STABLE
|
||||
- mkdir -p /root/.docker/cli-plugins
|
||||
- wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
|
||||
- echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
|
||||
- chmod +x ~/.docker/cli-plugins/docker-buildx
|
||||
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||
- docker buildx create --name mbuilder --driver docker-container --use
|
||||
- docker buildx inspect --bootstrap
|
||||
- docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG -t $IMAGE_TAG_LATEST_STABLE .
|
||||
tags:
|
||||
- dind
|
||||
only:
|
||||
|
@ -323,9 +335,15 @@ docker-release:
|
|||
before_script: *before-docker
|
||||
allow_failure: true
|
||||
script:
|
||||
- docker build --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG .
|
||||
- docker push $IMAGE_TAG
|
||||
- docker push $IMAGE_TAG_SLUG
|
||||
script:
|
||||
- mkdir -p /root/.docker/cli-plugins
|
||||
- wget "${DOCKER_BUILDX_URL}" -O ~/.docker/cli-plugins/docker-buildx
|
||||
- echo "${DOCKER_BUILDX_HASH} /root/.docker/cli-plugins/docker-buildx" | sha1sum -c
|
||||
- chmod +x ~/.docker/cli-plugins/docker-buildx
|
||||
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
||||
- docker buildx create --name mbuilder --driver docker-container --use
|
||||
- docker buildx inspect --bootstrap
|
||||
- docker buildx build --platform linux/amd64,linux/arm/v7,linux/arm64/v8 --push --cache-from $IMAGE_TAG_SLUG --build-arg VCS_REF=$CI_VCS_REF --build-arg BUILD_DATE=$CI_JOB_TIMESTAMP -t $IMAGE_TAG -t $IMAGE_TAG_SLUG .
|
||||
tags:
|
||||
- dind
|
||||
only:
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
* [ ] Compile a changelog
|
||||
* [ ] Create an MR with an announcement to pleroma.social
|
||||
* [ ] Tag the release
|
||||
* [ ] Merge `stable` into `develop` (in case the fixes are already in develop, use `git merge -s ours --no-commit` and manually merge the changelogs)
|
||||
|
|
99
CHANGELOG.md
99
CHANGELOG.md
|
@ -3,22 +3,23 @@ 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/).
|
||||
|
||||
## [unreleased]
|
||||
## [2.1.0] - 2020-08-28
|
||||
|
||||
### Changed
|
||||
|
||||
- **Breaking:** The default descriptions on uploads are now empty. The old behavior (filename as default) can be configured, see the cheat sheet.
|
||||
- **Breaking:** Added the ObjectAgePolicy to the default set of MRFs. This will delist and strip the follower collection of any message received that is older than 7 days. This will stop users from seeing very old messages in the timelines. The messages can still be viewed on the user's page and in conversations. They also still trigger notifications.
|
||||
- **Breaking:** Elixir >=1.9 is now required (was >= 1.8)
|
||||
- **Breaking:** Configuration: `:auto_linker, :opts` moved to `:pleroma, Pleroma.Formatter`. Old config namespace is deprecated.
|
||||
- **Breaking:** Configuration: `:instance, welcome_user_nickname` moved to `:welcome, :direct_message, :sender_nickname`, `:instance, :welcome_message` moved to `:welcome, :direct_message, :message`. Old config namespace is deprecated.
|
||||
- **Breaking:** LDAP: Fallback to local database authentication has been removed for security reasons and lack of a mechanism to ensure the passwords are synchronized when LDAP passwords are updated.
|
||||
- **Breaking** Changed defaults for `:restrict_unauthenticated` so that when `:instance, :public` is set to `false` then all `:restrict_unauthenticated` items be effectively set to `true`. If you'd like to allow unauthenticated access to specific API endpoints on a private instance, please explicitly set `:restrict_unauthenticated` to non-default value in `config/prod.secret.exs`.
|
||||
- In Conversations, return only direct messages as `last_status`
|
||||
- Using the `only_media` filter on timelines will now exclude reblog media
|
||||
- MFR policy to set global expiration for all local Create activities
|
||||
- OGP rich media parser merged with TwitterCard
|
||||
- Configuration: `:instance, rewrite_policy` moved to `:mrf, policies`, `:instance, :mrf_transparency` moved to `:mrf, :transparency`, `:instance, :mrf_transparency_exclusions` moved to `:mrf, :transparency_exclusions`. Old config namespace is deprecated.
|
||||
- Configuration: `:media_proxy, whitelist` format changed to host with scheme (e.g. `http://example.com` instead of `example.com`). Domain format is deprecated.
|
||||
- **Breaking:** Configuration: `:instance, welcome_user_nickname` moved to `:welcome, :direct_message, :sender_nickname`, `:instance, :welcome_message` moved to `:welcome, :direct_message, :message`. Old config namespace is deprecated.
|
||||
- **Breaking:** LDAP: Fallback to local database authentication has been removed for security reasons and lack of a mechanism to ensure the passwords are synchronized when LDAP passwords are updated.
|
||||
- **Breaking** Changed defaults for `:restrict_unauthenticated` so that when `:instance, :public` is set to `false` then all `:restrict_unauthenticated` items be effectively set to `true`. If you'd like to allow unauthenticated access to specific API endpoints on a private instance, please explicitly set `:restrict_unauthenticated` to non-default value in `config/prod.secret.exs`.
|
||||
|
||||
<details>
|
||||
<summary>API Changes</summary>
|
||||
|
@ -26,33 +27,37 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- **Breaking:** Pleroma API: The routes to update avatar, banner and background have been removed.
|
||||
- **Breaking:** Image description length is limited now.
|
||||
- **Breaking:** Emoji API: changed methods and renamed routes.
|
||||
- **Breaking:** Notification Settings API for suppressing notifications has been simplified down to `block_from_strangers`.
|
||||
- **Breaking:** Notification Settings API option for hiding push notification contents has been renamed to `hide_notification_contents`.
|
||||
- MastodonAPI: Allow removal of avatar, banner and background.
|
||||
- Streaming: Repeats of a user's posts will no longer be pushed to the user's stream.
|
||||
- Mastodon API: Added `pleroma.metadata.fields_limits` to /api/v1/instance
|
||||
- Mastodon API: On deletion, returns the original post text.
|
||||
- Mastodon API: Add `pleroma.unread_count` to the Marker entity.
|
||||
- **Breaking:** Notification Settings API for suppressing notifications
|
||||
has been simplified down to `block_from_strangers`.
|
||||
- **Breaking:** Notification Settings API option for hiding push notification
|
||||
contents has been renamed to `hide_notification_contents`
|
||||
- Mastodon API: Added `pleroma.metadata.post_formats` to /api/v1/instance
|
||||
- Mastodon API (legacy): Allow query parameters for `/api/v1/domain_blocks`, e.g. `/api/v1/domain_blocks?domain=badposters.zone`
|
||||
- Mastodon API: Make notifications about statuses from muted users and threads read automatically
|
||||
- Pleroma API: `/api/pleroma/captcha` responses now include `seconds_valid` with an integer value.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Admin API Changes</summary>
|
||||
|
||||
- **Breaking** Changed relay `/api/pleroma/admin/relay` endpoints response format.
|
||||
- Status visibility stats: now can return stats per instance.
|
||||
|
||||
- Mix task to refresh counter cache (`mix pleroma.refresh_counter_cache`)
|
||||
|
||||
</details>
|
||||
|
||||
### Removed
|
||||
|
||||
- **Breaking:** removed `with_move` parameter from notifications timeline.
|
||||
|
||||
### Added
|
||||
|
||||
- Frontends: Add mix task to install frontends.
|
||||
- Frontends: Add configurable frontends for primary and admin fe.
|
||||
- Configuration: Added a blacklist for email servers.
|
||||
- Chats: Added `accepts_chat_messages` field to user, exposed in APIs and federation.
|
||||
- Chats: Added support for federated chats. For details, see the docs.
|
||||
|
@ -94,6 +99,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
</details>
|
||||
|
||||
### Fixed
|
||||
- Fix list pagination and other list issues.
|
||||
- Support pagination in conversations API
|
||||
- **Breaking**: SimplePolicy `:reject` and `:accept` allow deletions again
|
||||
- Fix follower/blocks import when nicknames starts with @
|
||||
|
@ -108,12 +114,80 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Emoji Packs could not be listed when instance was set to `public: false`
|
||||
- Fix whole_word always returning false on filter get requests
|
||||
- Migrations not working on OTP releases if the database was connected over ssl
|
||||
- Fix relay following
|
||||
|
||||
## [Unreleased (patch)]
|
||||
## [2.0.7] - 2020-06-13
|
||||
|
||||
### Security
|
||||
- Fix potential DoSes exploiting atom leaks in rich media parser and the `UserAllowListPolicy` MRF policy
|
||||
|
||||
### Fixed
|
||||
- CSP: not allowing images/media from every host when mediaproxy is disabled
|
||||
- CSP: not adding mediaproxy base url to image/media hosts
|
||||
- StaticFE missing the CSS file
|
||||
|
||||
### Upgrade notes
|
||||
|
||||
1. Restart Pleroma
|
||||
|
||||
## [2.0.6] - 2020-06-09
|
||||
|
||||
### Security
|
||||
- CSP: harden `image-src` and `media-src` when MediaProxy is used
|
||||
|
||||
### Fixed
|
||||
- AP C2S: Fix pagination in inbox/outbox
|
||||
- Various compilation errors on OTP 23
|
||||
- Mastodon API streaming: Repeats from muted threads not being filtered
|
||||
|
||||
### Changed
|
||||
- Various database performance improvements
|
||||
|
||||
### Upgrade notes
|
||||
1. Run database migrations (inside Pleroma directory):
|
||||
- OTP: `./bin/pleroma_ctl migrate`
|
||||
- From Source: `mix ecto.migrate`
|
||||
2. Restart Pleroma
|
||||
|
||||
## [2.0.5] - 2020-05-13
|
||||
|
||||
### Security
|
||||
- Fix possible private status leaks in Mastodon Streaming API
|
||||
|
||||
### Fixed
|
||||
- Crashes when trying to block a user if block federation is disabled
|
||||
- Not being able to start the instance without `erlang-eldap` installed
|
||||
- Users with bios over the limit getting rejected
|
||||
- Follower counters not being updated on incoming follow accepts
|
||||
|
||||
### Upgrade notes
|
||||
|
||||
1. Restart Pleroma
|
||||
|
||||
## [2.0.4] - 2020-05-10
|
||||
|
||||
### Security
|
||||
- AP C2S: Fix a potential DoS by creating nonsensical objects that break timelines
|
||||
|
||||
### Fixed
|
||||
- Peertube user lookups not working
|
||||
- `InsertSkeletonsForDeletedUsers` migration failing on some instances
|
||||
- Healthcheck reporting the number of memory currently used, rather than allocated in total
|
||||
- `InsertSkeletonsForDeletedUsers` failing on some instances
|
||||
- LDAP not being usable in OTP releases
|
||||
- Default apache configuration having tls chain issues
|
||||
|
||||
### Upgrade notes
|
||||
|
||||
#### Apache only
|
||||
|
||||
1. Remove the following line from your config:
|
||||
```
|
||||
SSLCertificateFile /etc/letsencrypt/live/${servername}/cert.pem
|
||||
```
|
||||
|
||||
#### Everyone
|
||||
|
||||
1. Restart Pleroma
|
||||
|
||||
## [2.0.3] - 2020-05-02
|
||||
|
||||
|
@ -137,7 +211,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Follow request notifications
|
||||
<details>
|
||||
<summary>API Changes</summary>
|
||||
|
||||
- Admin API: `GET /api/pleroma/admin/need_reboot`.
|
||||
</details>
|
||||
|
||||
|
@ -172,6 +245,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Static-FE: Fix remote posts not being sanitized
|
||||
|
||||
### Fixed
|
||||
=======
|
||||
- Rate limiter crashes when there is no explicitly specified ip in the config
|
||||
- 500 errors when no `Accept` header is present if Static-FE is enabled
|
||||
- Instance panel not being updated immediately due to wrong `Cache-Control` headers
|
||||
- Statuses posted with BBCode/Markdown having unncessary newlines in Pleroma-FE
|
||||
|
|
|
@ -674,7 +674,50 @@
|
|||
# With no frontend configuration, the bundled files from the `static` directory will
|
||||
# be used.
|
||||
#
|
||||
# config :pleroma, :frontends, primary: %{"name" => "pleroma", "ref" => "develop"}
|
||||
# config :pleroma, :frontends,
|
||||
# primary: %{"name" => "pleroma-fe", "ref" => "develop"},
|
||||
# admin: %{"name" => "admin-fe", "ref" => "stable"},
|
||||
# available: %{...}
|
||||
|
||||
config :pleroma, :frontends,
|
||||
available: %{
|
||||
"kenoma" => %{
|
||||
"name" => "kenoma",
|
||||
"git" => "https://git.pleroma.social/lambadalambda/kenoma",
|
||||
"build_url" =>
|
||||
"https://git.pleroma.social/lambadalambda/kenoma/-/jobs/artifacts/${ref}/download?job=build",
|
||||
"ref" => "master"
|
||||
},
|
||||
"pleroma-fe" => %{
|
||||
"name" => "pleroma-fe",
|
||||
"git" => "https://git.pleroma.social/pleroma/pleroma-fe",
|
||||
"build_url" =>
|
||||
"https://git.pleroma.social/pleroma/pleroma-fe/-/jobs/artifacts/${ref}/download?job=build",
|
||||
"ref" => "develop"
|
||||
},
|
||||
"fedi-fe" => %{
|
||||
"name" => "fedi-fe",
|
||||
"git" => "https://git.pleroma.social/pleroma/fedi-fe",
|
||||
"build_url" =>
|
||||
"https://git.pleroma.social/pleroma/fedi-fe/-/jobs/artifacts/${ref}/download?job=build",
|
||||
"ref" => "master"
|
||||
},
|
||||
"admin-fe" => %{
|
||||
"name" => "admin-fe",
|
||||
"git" => "https://git.pleroma.social/pleroma/admin-fe",
|
||||
"build_url" =>
|
||||
"https://git.pleroma.social/pleroma/admin-fe/-/jobs/artifacts/${ref}/download?job=build",
|
||||
"ref" => "develop"
|
||||
},
|
||||
"soapbox-fe" => %{
|
||||
"name" => "soapbox-fe",
|
||||
"git" => "https://gitlab.com/soapbox-pub/soapbox-fe",
|
||||
"build_url" =>
|
||||
"https://gitlab.com/soapbox-pub/soapbox-fe/-/jobs/artifacts/${ref}/download?job=build-production",
|
||||
"ref" => "v1.0.0",
|
||||
"build_dir" => "static"
|
||||
}
|
||||
}
|
||||
|
||||
config :pleroma, :web_cache_ttl,
|
||||
activity_pub: nil,
|
||||
|
|
|
@ -12,6 +12,55 @@
|
|||
compress: false
|
||||
]
|
||||
|
||||
installed_frontend_options = [
|
||||
%{
|
||||
key: "name",
|
||||
label: "Name",
|
||||
type: :string,
|
||||
description:
|
||||
"Name of the installed frontend. Valid config must include both `Name` and `Reference` values."
|
||||
},
|
||||
%{
|
||||
key: "ref",
|
||||
label: "Reference",
|
||||
type: :string,
|
||||
description:
|
||||
"Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values."
|
||||
}
|
||||
]
|
||||
|
||||
frontend_options = [
|
||||
%{
|
||||
key: "name",
|
||||
label: "Name",
|
||||
type: :string,
|
||||
description: "Name of the frontend."
|
||||
},
|
||||
%{
|
||||
key: "ref",
|
||||
label: "Reference",
|
||||
type: :string,
|
||||
description: "Reference of the frontend to be used."
|
||||
},
|
||||
%{
|
||||
key: "git",
|
||||
type: :string,
|
||||
description: "URL of the git repository of the frontend"
|
||||
},
|
||||
%{
|
||||
key: "build_url",
|
||||
type: :string,
|
||||
description:
|
||||
"Either an url to a zip file containing the frontend or a template to build it by inserting the `ref`. The string `${ref}` will be replaced by the configured `ref`.",
|
||||
example: "https://some.url/builds/${ref}.zip"
|
||||
},
|
||||
%{
|
||||
key: "build_dir",
|
||||
type: :string,
|
||||
description: "The directory inside the zip file "
|
||||
}
|
||||
]
|
||||
|
||||
config :pleroma, :config_description, [
|
||||
%{
|
||||
group: :pleroma,
|
||||
|
@ -3553,22 +3602,41 @@
|
|||
key: :primary,
|
||||
type: :map,
|
||||
description: "Primary frontend, the one that is served for all pages by default",
|
||||
children: [
|
||||
%{
|
||||
key: "name",
|
||||
label: "Name",
|
||||
type: :string,
|
||||
description:
|
||||
"Name of the installed primary frontend. Valid config must include both `Name` and `Reference` values."
|
||||
children: installed_frontend_options
|
||||
},
|
||||
%{
|
||||
key: "ref",
|
||||
label: "Reference",
|
||||
type: :string,
|
||||
key: :admin,
|
||||
type: :map,
|
||||
description: "Admin frontend",
|
||||
children: installed_frontend_options
|
||||
},
|
||||
%{
|
||||
key: :available,
|
||||
type: :map,
|
||||
description:
|
||||
"Reference of the installed primary frontend to be used. Valid config must include both `Name` and `Reference` values."
|
||||
"A map containing available frontends and parameters for their installation.",
|
||||
children: [
|
||||
frontend_options
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
group: :pleroma,
|
||||
key: Pleroma.Web.Preload,
|
||||
type: :group,
|
||||
description: "Preload-related settings",
|
||||
children: [
|
||||
%{
|
||||
key: :providers,
|
||||
type: {:list, :module},
|
||||
description: "List of preload providers to enable",
|
||||
suggestions: [
|
||||
Pleroma.Web.Preload.Providers.Instance,
|
||||
Pleroma.Web.Preload.Providers.User,
|
||||
Pleroma.Web.Preload.Providers.Timelines,
|
||||
Pleroma.Web.Preload.Providers.StatusNet
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -313,31 +313,53 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
|
|||
- On failure: `Not found`
|
||||
- On success: JSON array of user's latest statuses
|
||||
|
||||
## `GET /api/pleroma/admin/relay`
|
||||
|
||||
### List Relays
|
||||
|
||||
Params: none
|
||||
Response:
|
||||
|
||||
* On success: JSON array of relays
|
||||
|
||||
```json
|
||||
[
|
||||
{"actor": "https://example.com/relay", "followed_back": true},
|
||||
{"actor": "https://example2.com/relay", "followed_back": false}
|
||||
]
|
||||
```
|
||||
|
||||
## `POST /api/pleroma/admin/relay`
|
||||
|
||||
### Follow a Relay
|
||||
|
||||
- Params:
|
||||
- `relay_url`
|
||||
- Response:
|
||||
- On success: URL of the followed relay
|
||||
Params:
|
||||
|
||||
* `relay_url`
|
||||
|
||||
Response:
|
||||
|
||||
* On success: relay json object
|
||||
|
||||
```json
|
||||
{"actor": "https://example.com/relay", "followed_back": true}
|
||||
```
|
||||
|
||||
## `DELETE /api/pleroma/admin/relay`
|
||||
|
||||
### Unfollow a Relay
|
||||
|
||||
- Params:
|
||||
- `relay_url`
|
||||
- Response:
|
||||
- On success: URL of the unfollowed relay
|
||||
Params:
|
||||
|
||||
## `GET /api/pleroma/admin/relay`
|
||||
* `relay_url`
|
||||
|
||||
### List Relays
|
||||
Response:
|
||||
|
||||
- Params: none
|
||||
- Response:
|
||||
- On success: JSON array of relays
|
||||
* On success: URL of the unfollowed relay
|
||||
|
||||
```json
|
||||
{"https://example.com/relay"}
|
||||
```
|
||||
|
||||
## `POST /api/pleroma/admin/users/invite_token`
|
||||
|
||||
|
|
69
docs/administration/CLI_tasks/frontend.md
Normal file
69
docs/administration/CLI_tasks/frontend.md
Normal file
|
@ -0,0 +1,69 @@
|
|||
# Managing frontends
|
||||
|
||||
`mix pleroma.frontend install <frontend> [--ref <ref>] [--file <file>] [--build-url <build-url>] [--path <path>] [--build-dir <build-dir>]`
|
||||
|
||||
Frontend can be installed either from local zip file, or automatically downloaded from the web.
|
||||
|
||||
You can give all the options directly on the command like, but missing information will be filled out by looking at the data configured under `frontends.available` in the config files.
|
||||
|
||||
Currently known `<frontend>` values are:
|
||||
- [admin-fe](https://git.pleroma.social/pleroma/admin-fe)
|
||||
- [kenoma](http://git.pleroma.social/lambadalambda/kenoma)
|
||||
- [pleroma-fe](http://git.pleroma.social/pleroma/pleroma-fe)
|
||||
- [fedi-fe](https://git.pleroma.social/pleroma/fedi-fe)
|
||||
- [soapbox-fe](https://gitlab.com/soapbox-pub/soapbox-fe)
|
||||
|
||||
You can still install frontends that are not configured, see below.
|
||||
|
||||
## Example installations for a known frontend
|
||||
|
||||
For a frontend configured under the `available` key, it's enough to install it by name.
|
||||
|
||||
```sh tab="OTP"
|
||||
./bin/pleroma_ctl frontend install pleroma
|
||||
```
|
||||
|
||||
```sh tab="From Source"
|
||||
mix pleroma.frontend install pleroma
|
||||
```
|
||||
|
||||
This will download the latest build for the the pre-configured `ref` and install it. It can then be configured as the one of the served frontends in the config file (see `primary` or `admin`).
|
||||
|
||||
You can override any of the details. To install a pleroma build from a different url, you could do this:
|
||||
|
||||
```sh tab="OPT"
|
||||
./bin/pleroma_ctl frontend install pleroma --ref 2hu_edition --build-url https://example.org/raymoo.zip
|
||||
```
|
||||
|
||||
```sh tab="From Source"
|
||||
mix pleroma.frontend install pleroma --ref 2hu_edition --build-url https://example.org/raymoo.zip
|
||||
```
|
||||
|
||||
Similarly, you can also install from a local zip file.
|
||||
|
||||
```sh tab="OTP"
|
||||
./bin/pleroma_ctl frontend install pleroma --ref mybuild --file ~/Downloads/doomfe.zip
|
||||
```
|
||||
|
||||
```sh tab="From Source"
|
||||
mix pleroma.frontend install pleroma --ref mybuild --file ~/Downloads/doomfe.zip
|
||||
```
|
||||
|
||||
The resulting frontend will always be installed into a folder of this template: `${instance_static}/frontends/${name}/${ref}`
|
||||
|
||||
Careful: This folder will be completely replaced on installation
|
||||
|
||||
## Example installation for an unknown frontend
|
||||
|
||||
The installation process is the same, but you will have to give all the needed options on the commond line. For example:
|
||||
|
||||
```sh tab="OTP"
|
||||
./bin/pleroma_ctl frontend install gensokyo --ref master --build-url https://gensokyo.2hu/builds/marisa.zip
|
||||
```
|
||||
|
||||
```sh tab="From Source"
|
||||
mix pleroma.frontend install gensokyo --ref master --build-url https://gensokyo.2hu/builds/marisa.zip
|
||||
```
|
||||
|
||||
If you don't have a zip file but just want to install a frontend from a local path, you can simply copy the files over a folder of this template: `${instance_static}/frontends/${name}/${ref}`
|
||||
|
|
@ -18,9 +18,10 @@ su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate"
|
|||
|
||||
1. Go to the working directory of Pleroma (default is `/opt/pleroma`)
|
||||
2. Run `git pull`. This pulls the latest changes from upstream.
|
||||
3. Run `mix deps.get`. This pulls in any new dependencies.
|
||||
3. Run `mix deps.get` [^1]. This pulls in any new dependencies.
|
||||
4. Stop the Pleroma service.
|
||||
5. Run `mix ecto.migrate`[^1]. This task performs database migrations, if there were any.
|
||||
5. Run `mix ecto.migrate` [^1] [^2]. This task performs database migrations, if there were any.
|
||||
6. Start the Pleroma service.
|
||||
|
||||
[^1]: Prefix with `MIX_ENV=prod` to run it using the production config file.
|
||||
[^1]: Depending on which install guide you followed (for example on Debian/Ubuntu), you want to run `mix` tasks as `pleroma` user by adding `sudo -Hu pleroma` before the command.
|
||||
[^2]: Prefix with `MIX_ENV=prod` to run it using the production config file.
|
||||
|
|
|
@ -6,11 +6,11 @@ Feel free to contact us to be added to this list!
|
|||
### Roma for Desktop
|
||||
- Homepage: <https://www.pleroma.com/#desktopApp>
|
||||
- Source Code: <https://github.com/roma-apps/roma-desktop>
|
||||
- Platforms: Windows, Mac, (Linux?)
|
||||
- Platforms: Windows, Mac, Linux
|
||||
- Features: Streaming Ready
|
||||
|
||||
### Social
|
||||
- Source Code: <https://gitlab.gnome.org/BrainBlasted/Social>
|
||||
- Source Code: <https://gitlab.gnome.org/World/Social>
|
||||
- Contact: [@brainblasted@social.libre.fi](https://social.libre.fi/users/brainblasted)
|
||||
- Platforms: Linux (GNOME)
|
||||
- Note(2019-01-28): Not at a pre-alpha stage yet
|
||||
|
@ -48,16 +48,9 @@ Feel free to contact us to be added to this list!
|
|||
- Platforms: Android
|
||||
- Features: No Streaming, Emoji Reactions, Text Formatting, FE Stickers
|
||||
|
||||
### Nekonium
|
||||
- Homepage: [F-Droid Repository](https://repo.gdgd.jp.net/), [Google Play](https://play.google.com/store/apps/details?id=com.apps.nekonium), [Amazon](https://www.amazon.co.jp/dp/B076FXPRBC/)
|
||||
- Source: <https://gogs.gdgd.jp.net/lin/nekonium>
|
||||
- Contact: [@lin@pleroma.gdgd.jp.net](https://pleroma.gdgd.jp.net/users/lin)
|
||||
- Platforms: Android
|
||||
- Features: Streaming Ready
|
||||
|
||||
### Fedi
|
||||
- Homepage: <https://www.fediapp.com/>
|
||||
- Source Code: Proprietary, but free
|
||||
- Source Code: Proprietary, but gratis
|
||||
- Platforms: iOS, Android
|
||||
- Features: Pleroma-specific features like Reactions
|
||||
|
||||
|
@ -70,9 +63,9 @@ Feel free to contact us to be added to this list!
|
|||
|
||||
### Twidere
|
||||
- Homepage: <https://twidere.mariotaku.org/>
|
||||
- Source Code: <https://github.com/TwidereProject/Twidere-Android/>, <https://github.com/TwidereProject/Twidere-iOS/>
|
||||
- Source Code: <https://github.com/TwidereProject/Twidere-Android/>
|
||||
- Contact: <me@mariotaku.org>
|
||||
- Platform: Android, iOS
|
||||
- Platform: Android
|
||||
- Features: No Streaming
|
||||
|
||||
### Indigenous
|
||||
|
@ -89,11 +82,6 @@ Feel free to contact us to be added to this list!
|
|||
- Contact: [@gcupc@glitch.social](https://glitch.social/users/gcupc)
|
||||
- Features: No Streaming
|
||||
|
||||
### Feather
|
||||
- Source Code: <https://github.com/kaniini/feather>
|
||||
- Contact: [@kaniini@pleroma.site](https://pleroma.site/kaniini)
|
||||
- Features: No Streaming
|
||||
|
||||
### Halcyon
|
||||
- Source Code: <https://notabug.org/halcyon-suite/halcyon>
|
||||
- Contact: [@halcyon@social.csswg.org](https://social.csswg.org/users/halcyon)
|
||||
|
@ -107,6 +95,15 @@ Feel free to contact us to be added to this list!
|
|||
- Features: No Streaming
|
||||
|
||||
### Sengi
|
||||
- Homepage: <https://nicolasconstant.github.io/sengi/>
|
||||
- Source Code: <https://github.com/NicolasConstant/sengi>
|
||||
- Contact: [@sengi_app@mastodon.social](https://mastodon.social/users/sengi_app)
|
||||
- Note(2019-01-28): The development is currently in a early stage.
|
||||
|
||||
### DashFE
|
||||
- Source Code: <https://notabug.org/daisuke/DashboardFE>
|
||||
- Contact: [@dashfe@stereophonic.space](https://stereophonic.space/users/dashfe)
|
||||
|
||||
### BloatFE
|
||||
- Source Code: <https://git.freesoftwareextremist.com/bloat/>
|
||||
- Contact: [@r@freesoftwareextremist.com](https://freesoftwareextremist.com/users/r)
|
||||
- Features: Does not requires JavaScript
|
||||
|
|
|
@ -87,7 +87,7 @@ To add configuration to your config file, you can copy it from the base config.
|
|||
direct_message: [
|
||||
enabled: true,
|
||||
sender_nickname: "lain",
|
||||
message: "Hi, @username! Welcome on board!"
|
||||
message: "Hi! Welcome on board!"
|
||||
],
|
||||
email: [
|
||||
enabled: true,
|
||||
|
@ -1070,11 +1070,11 @@ Control favicons for instances.
|
|||
|
||||
Frontends in Pleroma are swappable - you can specify which one to use here.
|
||||
|
||||
For now, you can set a frontend with the key `primary` and the options of `name` and `ref`. This will then make Pleroma serve the frontend from a folder constructed by concatenating the instance static path, `frontends` and the name and ref.
|
||||
You can set a frontends for the key `primary` and `admin` and the options of `name` and `ref`. This will then make Pleroma serve the frontend from a folder constructed by concatenating the instance static path, `frontends` and the name and ref.
|
||||
|
||||
The key `primary` refers to the frontend that will be served by default for general requests. In the future, other frontends like the admin frontend will also be configurable here.
|
||||
The key `primary` refers to the frontend that will be served by default for general requests. The key `admin` refers to the frontend that will be served at the `/pleroma/admin` path.
|
||||
|
||||
If you don't set anything here, the bundled frontend will be used.
|
||||
If you don't set anything here, the bundled frontends will be used.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -1083,6 +1083,10 @@ config :pleroma, :frontends,
|
|||
primary: %{
|
||||
"name" => "pleroma",
|
||||
"ref" => "stable"
|
||||
},
|
||||
admin: %{
|
||||
"name" => "admin",
|
||||
"ref" => "develop"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
140
lib/mix/tasks/pleroma/frontend.ex
Normal file
140
lib/mix/tasks/pleroma/frontend.ex
Normal file
|
@ -0,0 +1,140 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.Frontend do
|
||||
use Mix.Task
|
||||
|
||||
import Mix.Pleroma
|
||||
|
||||
@shortdoc "Manages bundled Pleroma frontends"
|
||||
|
||||
@moduledoc File.read!("docs/administration/CLI_tasks/frontend.md")
|
||||
|
||||
def run(["install", "none" | _args]) do
|
||||
shell_info("Skipping frontend installation because none was requested")
|
||||
"none"
|
||||
end
|
||||
|
||||
def run(["install", frontend | args]) do
|
||||
log_level = Logger.level()
|
||||
Logger.configure(level: :warn)
|
||||
start_pleroma()
|
||||
|
||||
{options, [], []} =
|
||||
OptionParser.parse(
|
||||
args,
|
||||
strict: [
|
||||
ref: :string,
|
||||
static_dir: :string,
|
||||
build_url: :string,
|
||||
build_dir: :string,
|
||||
file: :string
|
||||
]
|
||||
)
|
||||
|
||||
instance_static_dir =
|
||||
with nil <- options[:static_dir] do
|
||||
Pleroma.Config.get!([:instance, :static_dir])
|
||||
end
|
||||
|
||||
cmd_frontend_info = %{
|
||||
"name" => frontend,
|
||||
"ref" => options[:ref],
|
||||
"build_url" => options[:build_url],
|
||||
"build_dir" => options[:build_dir]
|
||||
}
|
||||
|
||||
config_frontend_info = Pleroma.Config.get([:frontends, :available, frontend], %{})
|
||||
|
||||
frontend_info =
|
||||
Map.merge(config_frontend_info, cmd_frontend_info, fn _key, config, cmd ->
|
||||
# This only overrides things that are actually set
|
||||
cmd || config
|
||||
end)
|
||||
|
||||
ref = frontend_info["ref"]
|
||||
|
||||
unless ref do
|
||||
raise "No ref given or configured"
|
||||
end
|
||||
|
||||
dest =
|
||||
Path.join([
|
||||
instance_static_dir,
|
||||
"frontends",
|
||||
frontend,
|
||||
ref
|
||||
])
|
||||
|
||||
fe_label = "#{frontend} (#{ref})"
|
||||
|
||||
tmp_dir = Path.join(dest, "tmp")
|
||||
|
||||
with {_, :ok} <-
|
||||
{:download_or_unzip, download_or_unzip(frontend_info, tmp_dir, options[:file])},
|
||||
shell_info("Installing #{fe_label} to #{dest}"),
|
||||
:ok <- install_frontend(frontend_info, tmp_dir, dest) do
|
||||
File.rm_rf!(tmp_dir)
|
||||
shell_info("Frontend #{fe_label} installed to #{dest}")
|
||||
|
||||
Logger.configure(level: log_level)
|
||||
else
|
||||
{:download_or_unzip, _} ->
|
||||
shell_info("Could not download or unzip the frontend")
|
||||
|
||||
_e ->
|
||||
shell_info("Could not install the frontend")
|
||||
end
|
||||
end
|
||||
|
||||
defp download_or_unzip(frontend_info, temp_dir, file) do
|
||||
if file do
|
||||
with {:ok, zip} <- File.read(Path.expand(file)) do
|
||||
unzip(zip, temp_dir)
|
||||
end
|
||||
else
|
||||
download_build(frontend_info, temp_dir)
|
||||
end
|
||||
end
|
||||
|
||||
def unzip(zip, dest) do
|
||||
with {:ok, unzipped} <- :zip.unzip(zip, [:memory]) do
|
||||
File.rm_rf!(dest)
|
||||
File.mkdir_p!(dest)
|
||||
|
||||
Enum.each(unzipped, fn {filename, data} ->
|
||||
path = filename
|
||||
|
||||
new_file_path = Path.join(dest, path)
|
||||
|
||||
new_file_path
|
||||
|> Path.dirname()
|
||||
|> File.mkdir_p!()
|
||||
|
||||
File.write!(new_file_path, data)
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defp download_build(frontend_info, dest) do
|
||||
shell_info("Downloading pre-built bundle for #{frontend_info["name"]}")
|
||||
url = String.replace(frontend_info["build_url"], "${ref}", frontend_info["ref"])
|
||||
|
||||
with {:ok, %{status: 200, body: zip_body}} <-
|
||||
Pleroma.HTTP.get(url, [], timeout: 120_000, recv_timeout: 120_000) do
|
||||
unzip(zip_body, dest)
|
||||
else
|
||||
e -> {:error, e}
|
||||
end
|
||||
end
|
||||
|
||||
defp install_frontend(frontend_info, source, dest) do
|
||||
from = frontend_info["build_dir"] || "dist"
|
||||
File.mkdir_p!(dest)
|
||||
File.cp_r!(Path.join([source, from]), dest)
|
||||
:ok
|
||||
end
|
||||
end
|
|
@ -35,10 +35,16 @@ def run(["unfollow", target]) do
|
|||
def run(["list"]) do
|
||||
start_pleroma()
|
||||
|
||||
with {:ok, list} <- Relay.list(true) do
|
||||
list |> Enum.each(&shell_info(&1))
|
||||
with {:ok, list} <- Relay.list() do
|
||||
Enum.each(list, &print_relay_url/1)
|
||||
else
|
||||
{:error, e} -> shell_error("Error while fetching relay subscription list: #{inspect(e)}")
|
||||
end
|
||||
end
|
||||
|
||||
defp print_relay_url(%{followed_back: false} = relay) do
|
||||
shell_info("#{relay.actor} - no Accept received (relay didn't follow back)")
|
||||
end
|
||||
|
||||
defp print_relay_url(relay), do: shell_info(relay.actor)
|
||||
end
|
||||
|
|
|
@ -264,4 +264,12 @@ defp validate_following_id_follower_id_inequality(%Changeset{} = changeset) do
|
|||
end
|
||||
end)
|
||||
end
|
||||
|
||||
@spec following_ap_ids(User.t()) :: [String.t()]
|
||||
def following_ap_ids(%User{} = user) do
|
||||
user
|
||||
|> following_query()
|
||||
|> select([r, u], u.ap_id)
|
||||
|> Repo.all()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,7 @@ defmodule Pleroma.Notification do
|
|||
alias Pleroma.Repo
|
||||
alias Pleroma.ThreadMute
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
alias Pleroma.Web.Push
|
||||
alias Pleroma.Web.Streamer
|
||||
|
@ -441,6 +442,7 @@ def create_notification(%Activity{} = activity, %User{} = user, do_send \\ true)
|
|||
|> Multi.insert(:notification, %Notification{
|
||||
user_id: user.id,
|
||||
activity: activity,
|
||||
seen: mark_as_read?(activity, user),
|
||||
type: type_from_activity(activity)
|
||||
})
|
||||
|> Marker.multi_set_last_read_id(user, "notifications")
|
||||
|
@ -634,6 +636,11 @@ def skip?(:filtered, activity, user) do
|
|||
|
||||
def skip?(_, _, _), do: false
|
||||
|
||||
def mark_as_read?(activity, target_user) do
|
||||
user = Activity.user_actor(activity)
|
||||
User.mutes_user?(target_user, user) || CommonAPI.thread_muted?(target_user, activity)
|
||||
end
|
||||
|
||||
def for_user_and_activity(user, activity) do
|
||||
from(n in __MODULE__,
|
||||
where: n.user_id == ^user.id,
|
||||
|
|
|
@ -30,6 +30,7 @@ def init(opts) do
|
|||
opts
|
||||
|> Keyword.put(:from, "__unconfigured_frontend_static_plug")
|
||||
|> Plug.Static.init()
|
||||
|> Map.put(:frontend_type, opts[:frontend_type])
|
||||
end
|
||||
|
||||
def call(conn, opts) do
|
||||
|
|
|
@ -7,6 +7,8 @@ defmodule Pleroma.Plugs.RemoteIp do
|
|||
This is a shim to call [`RemoteIp`](https://git.pleroma.social/pleroma/remote_ip) but with runtime configuration.
|
||||
"""
|
||||
|
||||
import Plug.Conn
|
||||
|
||||
@behaviour Plug
|
||||
|
||||
@headers ~w[
|
||||
|
@ -26,11 +28,12 @@ defmodule Pleroma.Plugs.RemoteIp do
|
|||
|
||||
def init(_), do: nil
|
||||
|
||||
def call(conn, _) do
|
||||
def call(%{remote_ip: original_remote_ip} = conn, _) do
|
||||
config = Pleroma.Config.get(__MODULE__, [])
|
||||
|
||||
if Keyword.get(config, :enabled, false) do
|
||||
RemoteIp.call(conn, remote_ip_opts(config))
|
||||
%{remote_ip: new_remote_ip} = conn = RemoteIp.call(conn, remote_ip_opts(config))
|
||||
assign(conn, :remote_ip_found, original_remote_ip != new_remote_ip)
|
||||
else
|
||||
conn
|
||||
end
|
||||
|
|
|
@ -247,6 +247,13 @@ def unquote(:"#{outgoing_relation_target}_ap_ids")(user, restrict_deactivated? \
|
|||
end
|
||||
end
|
||||
|
||||
defdelegate following_count(user), to: FollowingRelationship
|
||||
defdelegate following(user), to: FollowingRelationship
|
||||
defdelegate following?(follower, followed), to: FollowingRelationship
|
||||
defdelegate following_ap_ids(user), to: FollowingRelationship
|
||||
defdelegate get_follow_requests(user), to: FollowingRelationship
|
||||
defdelegate search(query, opts \\ []), to: User.Search
|
||||
|
||||
@doc """
|
||||
Dumps Flake Id to SQL-compatible format (16-byte UUID).
|
||||
E.g. "9pQtDGXuq4p3VlcJEm" -> <<0, 0, 1, 110, 179, 218, 42, 92, 213, 41, 44, 227, 95, 213, 0, 0>>
|
||||
|
@ -372,8 +379,6 @@ def restrict_deactivated(query) do
|
|||
from(u in query, where: u.deactivated != ^true)
|
||||
end
|
||||
|
||||
defdelegate following_count(user), to: FollowingRelationship
|
||||
|
||||
defp truncate_fields_param(params) do
|
||||
if Map.has_key?(params, :fields) do
|
||||
Map.put(params, :fields, Enum.map(params[:fields], &truncate_field/1))
|
||||
|
@ -868,8 +873,6 @@ def follow_all(follower, followeds) do
|
|||
set_cache(follower)
|
||||
end
|
||||
|
||||
defdelegate following(user), to: FollowingRelationship
|
||||
|
||||
def follow(%User{} = follower, %User{} = followed, state \\ :follow_accept) do
|
||||
deny_follow_blocked = Config.get([:user, :deny_follow_blocked])
|
||||
|
||||
|
@ -923,8 +926,6 @@ defp do_unfollow(%User{} = follower, %User{} = followed) do
|
|||
end
|
||||
end
|
||||
|
||||
defdelegate following?(follower, followed), to: FollowingRelationship
|
||||
|
||||
@doc "Returns follow state as Pleroma.FollowingRelationship.State value"
|
||||
def get_follow_state(%User{} = follower, %User{} = following) do
|
||||
following_relationship = FollowingRelationship.get(follower, following)
|
||||
|
@ -1189,8 +1190,6 @@ def get_friends_ids(user, page \\ nil) do
|
|||
|> Repo.all()
|
||||
end
|
||||
|
||||
defdelegate get_follow_requests(user), to: FollowingRelationship
|
||||
|
||||
def increase_note_count(%User{} = user) do
|
||||
User
|
||||
|> where(id: ^user.id)
|
||||
|
@ -2163,8 +2162,6 @@ def get_ap_ids_by_nicknames(nicknames) do
|
|||
|> Repo.all()
|
||||
end
|
||||
|
||||
defdelegate search(query, opts \\ []), to: User.Search
|
||||
|
||||
defp put_password_hash(
|
||||
%Ecto.Changeset{valid?: true, changes: %{password: password}} = changeset
|
||||
) do
|
||||
|
|
|
@ -1344,9 +1344,8 @@ def fetch_and_prepare_user_from_ap_id(ap_id) do
|
|||
end
|
||||
|
||||
def maybe_handle_clashing_nickname(data) do
|
||||
nickname = data[:nickname]
|
||||
|
||||
with %User{} = old_user <- User.get_by_nickname(nickname),
|
||||
with nickname when is_binary(nickname) <- data[:nickname],
|
||||
%User{} = old_user <- User.get_by_nickname(nickname),
|
||||
{_, false} <- {:ap_id_comparison, data[:ap_id] == old_user.ap_id} do
|
||||
Logger.info(
|
||||
"Found an old user for #{nickname}, the old ap id is #{old_user.ap_id}, new one is #{
|
||||
|
@ -1360,7 +1359,7 @@ def maybe_handle_clashing_nickname(data) do
|
|||
else
|
||||
{:ap_id_comparison, true} ->
|
||||
Logger.info(
|
||||
"Found an old user for #{nickname}, but the ap id #{data[:ap_id]} is the same as the new user. Race condition? Not changing anything."
|
||||
"Found an old user for #{data[:nickname]}, but the ap id #{data[:ap_id]} is the same as the new user. Race condition? Not changing anything."
|
||||
)
|
||||
|
||||
_ ->
|
||||
|
|
|
@ -215,7 +215,7 @@ def announce(actor, object, options \\ []) do
|
|||
|
||||
to =
|
||||
cond do
|
||||
actor.ap_id == Relay.relay_ap_id() ->
|
||||
actor.ap_id == Relay.ap_id() ->
|
||||
[actor.follower_address]
|
||||
|
||||
public? ->
|
||||
|
|
|
@ -10,19 +10,13 @@ defmodule Pleroma.Web.ActivityPub.Relay do
|
|||
alias Pleroma.Web.CommonAPI
|
||||
require Logger
|
||||
|
||||
@relay_nickname "relay"
|
||||
@nickname "relay"
|
||||
|
||||
def get_actor do
|
||||
actor =
|
||||
relay_ap_id()
|
||||
|> User.get_or_create_service_actor_by_ap_id(@relay_nickname)
|
||||
@spec ap_id() :: String.t()
|
||||
def ap_id, do: "#{Pleroma.Web.Endpoint.url()}/#{@nickname}"
|
||||
|
||||
actor
|
||||
end
|
||||
|
||||
def relay_ap_id do
|
||||
"#{Pleroma.Web.Endpoint.url()}/relay"
|
||||
end
|
||||
@spec get_actor() :: User.t() | nil
|
||||
def get_actor, do: User.get_or_create_service_actor_by_ap_id(ap_id(), @nickname)
|
||||
|
||||
@spec follow(String.t()) :: {:ok, Activity.t()} | {:error, any()}
|
||||
def follow(target_instance) do
|
||||
|
@ -61,34 +55,38 @@ def publish(%Activity{data: %{"type" => "Create"}} = activity) do
|
|||
|
||||
def publish(_), do: {:error, "Not implemented"}
|
||||
|
||||
@spec list(boolean()) :: {:ok, [String.t()]} | {:error, any()}
|
||||
def list(with_not_accepted \\ false) do
|
||||
@spec list() :: {:ok, [%{actor: String.t(), followed_back: boolean()}]} | {:error, any()}
|
||||
def list do
|
||||
with %User{} = user <- get_actor() do
|
||||
accepted =
|
||||
user
|
||||
|> User.following()
|
||||
|> Enum.map(fn entry -> URI.parse(entry).host end)
|
||||
|> Enum.uniq()
|
||||
|> following()
|
||||
|> Enum.map(fn actor -> %{actor: actor, followed_back: true} end)
|
||||
|
||||
list =
|
||||
if with_not_accepted do
|
||||
without_accept =
|
||||
user
|
||||
|> Pleroma.Activity.following_requests_for_actor()
|
||||
|> Enum.map(fn a -> URI.parse(a.data["object"]).host <> " (no Accept received)" end)
|
||||
|> Enum.map(fn activity -> %{actor: activity.data["object"], followed_back: false} end)
|
||||
|> Enum.uniq()
|
||||
|
||||
accepted ++ without_accept
|
||||
else
|
||||
accepted
|
||||
end
|
||||
|
||||
{:ok, list}
|
||||
{:ok, accepted ++ without_accept}
|
||||
else
|
||||
error -> format_error(error)
|
||||
end
|
||||
end
|
||||
|
||||
@spec following() :: [String.t()]
|
||||
def following do
|
||||
get_actor()
|
||||
|> following()
|
||||
end
|
||||
|
||||
defp following(user) do
|
||||
user
|
||||
|> User.following_ap_ids()
|
||||
|> Enum.uniq()
|
||||
end
|
||||
|
||||
defp format_error({:error, error}), do: format_error(error)
|
||||
|
||||
defp format_error(error) do
|
||||
|
|
|
@ -39,7 +39,7 @@ def follow(%{assigns: %{user: admin}, body_params: %{relay_url: target}} = conn,
|
|||
target: target
|
||||
})
|
||||
|
||||
json(conn, target)
|
||||
json(conn, %{actor: target, followed_back: target in Relay.following()})
|
||||
else
|
||||
_ ->
|
||||
conn
|
||||
|
|
|
@ -27,8 +27,7 @@ def index_operation do
|
|||
properties: %{
|
||||
relays: %Schema{
|
||||
type: :array,
|
||||
items: %Schema{type: :string},
|
||||
example: ["lain.com", "mstdn.io"]
|
||||
items: relay()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -43,19 +42,9 @@ def follow_operation do
|
|||
operationId: "AdminAPI.RelayController.follow",
|
||||
security: [%{"oAuth" => ["write:follows"]}],
|
||||
parameters: admin_api_params(),
|
||||
requestBody:
|
||||
request_body("Parameters", %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
relay_url: %Schema{type: :string, format: :uri}
|
||||
}
|
||||
}),
|
||||
requestBody: request_body("Parameters", relay_url()),
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Status", "application/json", %Schema{
|
||||
type: :string,
|
||||
example: "http://mastodon.example.org/users/admin"
|
||||
})
|
||||
200 => Operation.response("Status", "application/json", relay())
|
||||
}
|
||||
}
|
||||
end
|
||||
|
@ -67,13 +56,7 @@ def unfollow_operation do
|
|||
operationId: "AdminAPI.RelayController.unfollow",
|
||||
security: [%{"oAuth" => ["write:follows"]}],
|
||||
parameters: admin_api_params(),
|
||||
requestBody:
|
||||
request_body("Parameters", %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
relay_url: %Schema{type: :string, format: :uri}
|
||||
}
|
||||
}),
|
||||
requestBody: request_body("Parameters", relay_url()),
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Status", "application/json", %Schema{
|
||||
|
@ -83,4 +66,29 @@ def unfollow_operation do
|
|||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp relay do
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
actor: %Schema{
|
||||
type: :string,
|
||||
example: "https://example.com/relay"
|
||||
},
|
||||
followed_back: %Schema{
|
||||
type: :boolean,
|
||||
description: "Is relay followed back by this actor?"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp relay_url do
|
||||
%Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
relay_url: %Schema{type: :string, format: :uri}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -465,7 +465,7 @@ def remove_mute(user, activity) do
|
|||
end
|
||||
|
||||
def thread_muted?(%User{id: user_id}, %{data: %{"context" => context}})
|
||||
when is_binary("context") do
|
||||
when is_binary(context) do
|
||||
ThreadMute.exists?(user_id, context)
|
||||
end
|
||||
|
||||
|
|
|
@ -39,6 +39,18 @@ defmodule Pleroma.Web.Endpoint do
|
|||
}
|
||||
)
|
||||
|
||||
plug(Plug.Static.IndexHtml, at: "/pleroma/admin/")
|
||||
|
||||
plug(Pleroma.Plugs.FrontendStatic,
|
||||
at: "/pleroma/admin",
|
||||
frontend_type: :admin,
|
||||
gzip: true,
|
||||
cache_control_for_etags: @static_cache_control,
|
||||
headers: %{
|
||||
"cache-control" => @static_cache_control
|
||||
}
|
||||
)
|
||||
|
||||
# Serve at "/" the static files from "priv/static" directory.
|
||||
#
|
||||
# You should set gzip to true if you are running phoenix.digest
|
||||
|
@ -56,8 +68,6 @@ defmodule Pleroma.Web.Endpoint do
|
|||
}
|
||||
)
|
||||
|
||||
plug(Plug.Static.IndexHtml, at: "/pleroma/admin/")
|
||||
|
||||
plug(Plug.Static,
|
||||
at: "/pleroma/admin/",
|
||||
from: {:pleroma, "priv/static/adminfe/"}
|
||||
|
|
|
@ -182,11 +182,10 @@ def list(%{assigns: %{user: user}} = conn, %{list_id: id} = params) do
|
|||
with %Pleroma.List{title: _title, following: following} <- Pleroma.List.get(id, user) do
|
||||
params =
|
||||
params
|
||||
|> Map.new(fn {key, value} -> {to_string(key), value} end)
|
||||
|> Map.put("type", "Create")
|
||||
|> Map.put("blocking_user", user)
|
||||
|> Map.put("user", user)
|
||||
|> Map.put("muting_user", user)
|
||||
|> Map.put(:type, "Create")
|
||||
|> Map.put(:blocking_user, user)
|
||||
|> Map.put(:user, user)
|
||||
|> Map.put(:muting_user, user)
|
||||
|
||||
# we must filter the following list for the user to avoid leaking statuses the user
|
||||
# does not actually have permission to see (for more info, peruse security issue #270).
|
||||
|
|
|
@ -149,7 +149,9 @@ def index(%{assigns: %{user: %{id: user_id} = user}} = conn, _params) do
|
|||
from(c in Chat,
|
||||
where: c.user_id == ^user_id,
|
||||
where: c.recipient not in ^blocked_ap_ids,
|
||||
order_by: [desc: c.updated_at]
|
||||
order_by: [desc: c.updated_at],
|
||||
inner_join: u in User,
|
||||
on: u.ap_id == c.recipient
|
||||
)
|
||||
|> Repo.all()
|
||||
|
||||
|
|
|
@ -149,6 +149,18 @@ def find_lrdd_template(domain) do
|
|||
end
|
||||
end
|
||||
|
||||
defp get_address_from_domain(domain, encoded_account) when is_binary(domain) do
|
||||
case find_lrdd_template(domain) do
|
||||
{:ok, template} ->
|
||||
String.replace(template, "{uri}", encoded_account)
|
||||
|
||||
_ ->
|
||||
"https://#{domain}/.well-known/webfinger?resource=#{encoded_account}"
|
||||
end
|
||||
end
|
||||
|
||||
defp get_address_from_domain(_, _), do: nil
|
||||
|
||||
@spec finger(String.t()) :: {:ok, map()} | {:error, any()}
|
||||
def finger(account) do
|
||||
account = String.trim_leading(account, "@")
|
||||
|
@ -163,16 +175,8 @@ def finger(account) do
|
|||
|
||||
encoded_account = URI.encode("acct:#{account}")
|
||||
|
||||
address =
|
||||
case find_lrdd_template(domain) do
|
||||
{:ok, template} ->
|
||||
String.replace(template, "{uri}", encoded_account)
|
||||
|
||||
_ ->
|
||||
"https://#{domain}/.well-known/webfinger?resource=#{encoded_account}"
|
||||
end
|
||||
|
||||
with response <-
|
||||
with address when is_binary(address) <- get_address_from_domain(domain, encoded_account),
|
||||
response <-
|
||||
HTTP.get(
|
||||
address,
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
|
|||
def project do
|
||||
[
|
||||
app: :pleroma,
|
||||
version: version("2.0.50"),
|
||||
version: version("2.1.50"),
|
||||
elixir: "~> 1.9",
|
||||
elixirc_paths: elixirc_paths(Mix.env()),
|
||||
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
|
||||
|
|
8
mix.lock
8
mix.lock
|
@ -42,8 +42,8 @@
|
|||
"ex_machina": {:hex, :ex_machina, "2.4.0", "09a34c5d371bfb5f78399029194a8ff67aff340ebe8ba19040181af35315eabb", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "a20bc9ddc721b33ea913b93666c5d0bdca5cbad7a67540784ae277228832d72c"},
|
||||
"ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"},
|
||||
"excoveralls": {:hex, :excoveralls, "0.13.1", "b9f1697f7c9e0cfe15d1a1d737fb169c398803ffcbc57e672aa007e9fd42864c", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "b4bb550e045def1b4d531a37fb766cbbe1307f7628bf8f0414168b3f52021cce"},
|
||||
"fast_html": {:hex, :fast_html, "2.0.1", "e126c74d287768ae78c48938da6711164517300d108a78f8a38993df8d588335", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "bdd6f8525c95ad391a4f10d9a1b3da4cea94078ec8638487aa8c24015ad9393a"},
|
||||
"fast_sanitize": {:hex, :fast_sanitize, "0.2.0", "004b40d5bbecda182b6fdba762a51fffd3501e689e8eafe196e1a97eb0caf733", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "11fcb37f26d272a3a2aff861872bf100be4eeacea69505908b8cdbcea5b0813a"},
|
||||
"fast_html": {:hex, :fast_html, "2.0.2", "1fabc408b2baa965cf6399a48796326f2721b21b397a3c667bb3bb88fb9559a4", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "f077e2c1597a6e2678e6cacc64f456a6c6024eb4240092c46d4212496dc59aba"},
|
||||
"fast_sanitize": {:hex, :fast_sanitize, "0.2.1", "3302421a988992b6cae08e68f77069e167ff116444183f3302e3c36017a50558", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bcd2c54e328128515edd1a8fb032fdea7e5581672ba161fc5962d21ecee92502"},
|
||||
"flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"},
|
||||
"floki": {:hex, :floki, "0.27.0", "6b29a14283f1e2e8fad824bc930eaa9477c462022075df6bea8f0ad811c13599", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "583b8c13697c37179f1f82443bcc7ad2f76fbc0bf4c186606eebd658f7f2631b"},
|
||||
"gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"},
|
||||
|
@ -68,7 +68,7 @@
|
|||
"makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
|
||||
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
|
||||
"mime": {:hex, :mime, "1.4.0", "5066f14944b470286146047d2f73518cf5cca82f8e4815cf35d196b58cf07c47", [:mix], [], "hexpm", "75fa42c4228ea9a23f70f123c74ba7cece6a03b1fd474fe13f6a7a85c6ea4ff6"},
|
||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
|
||||
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
|
||||
"mock": {:hex, :mock, "0.3.5", "feb81f52b8dcf0a0d65001d2fec459f6b6a8c22562d94a965862f6cc066b5431", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "6fae404799408300f863550392635d8f7e3da6b71abdd5c393faf41b131c8728"},
|
||||
|
@ -87,7 +87,7 @@
|
|||
"phoenix_html": {:hex, :phoenix_html, "2.14.2", "b8a3899a72050f3f48a36430da507dd99caf0ac2d06c77529b1646964f3d563e", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "58061c8dfd25da5df1ea0ca47c972f161beb6c875cd293917045b92ffe1bf617"},
|
||||
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm", "1f13f9f0f3e769a667a6b6828d29dec37497a082d195cc52dbef401a9b69bf38"},
|
||||
"phoenix_swoosh": {:hex, :phoenix_swoosh, "0.3.0", "2acfa0db038a7649e0a4614eee970e6ed9a39d191ccd79a03583b51d0da98165", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.0", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "b8bbae4b59a676de6b8bd8675eda37bc8b4424812ae429d6fdcb2b039e00003b"},
|
||||
"plug": {:hex, :plug, "1.10.3", "c9cebe917637d8db0e759039cc106adca069874e1a9034fd6e3fdd427fd3c283", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "01f9037a2a1de1d633b5a881101e6a444bcabb1d386ca1e00bb273a1f1d9d939"},
|
||||
"plug": {:hex, :plug, "1.10.4", "41eba7d1a2d671faaf531fa867645bd5a3dce0957d8e2a3f398ccff7d2ef017f", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad1e233fe73d2eec56616568d260777b67f53148a999dc2d048f4eb9778fe4a0"},
|
||||
"plug_cowboy": {:hex, :plug_cowboy, "2.3.0", "149a50e05cb73c12aad6506a371cd75750c0b19a32f81866e1a323dda9e0e99d", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bc595a1870cef13f9c1e03df56d96804db7f702175e4ccacdb8fc75c02a7b97e"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"},
|
||||
"plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"},
|
||||
|
|
Binary file not shown.
BIN
priv/static/adminfe/chunk-0171.aa11eafe.css
Normal file
BIN
priv/static/adminfe/chunk-0171.aa11eafe.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-0598.d8f2b478.css
Normal file
BIN
priv/static/adminfe/chunk-0598.d8f2b478.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-0f09.66ca2a61.css
Normal file
BIN
priv/static/adminfe/chunk-0f09.66ca2a61.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-19e2.934ad654.css
Normal file
BIN
priv/static/adminfe/chunk-19e2.934ad654.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-28f8.0aae6427.css
Normal file
BIN
priv/static/adminfe/chunk-28f8.0aae6427.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-3221.0ef79c67.css
Normal file
BIN
priv/static/adminfe/chunk-3221.0ef79c67.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-39ad.ba67c97f.css
Normal file
BIN
priv/static/adminfe/chunk-39ad.ba67c97f.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-3ba2.63b1228d.css
Normal file
BIN
priv/static/adminfe/chunk-3ba2.63b1228d.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-4eb4.b72d16c3.css
Normal file
BIN
priv/static/adminfe/chunk-4eb4.b72d16c3.css
Normal file
Binary file not shown.
Binary file not shown.
BIN
priv/static/adminfe/chunk-565e.8c036a6e.css
Normal file
BIN
priv/static/adminfe/chunk-565e.8c036a6e.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-68ea.81e11186.css
Normal file
BIN
priv/static/adminfe/chunk-68ea.81e11186.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-6e81.7e5babfc.css
Normal file
BIN
priv/static/adminfe/chunk-6e81.7e5babfc.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-6e8c.ef26acfd.css
Normal file
BIN
priv/static/adminfe/chunk-6e8c.ef26acfd.css
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
priv/static/adminfe/chunk-7503.cc089ee4.css
Normal file
BIN
priv/static/adminfe/chunk-7503.cc089ee4.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-7c6b.b529c720.css
Normal file
BIN
priv/static/adminfe/chunk-7c6b.b529c720.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-97e2.9f9fab0f.css
Normal file
BIN
priv/static/adminfe/chunk-97e2.9f9fab0f.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-9a72.786caeb3.css
Normal file
BIN
priv/static/adminfe/chunk-9a72.786caeb3.css
Normal file
Binary file not shown.
BIN
priv/static/adminfe/chunk-d892.56863b19.css
Normal file
BIN
priv/static/adminfe/chunk-d892.56863b19.css
Normal file
Binary file not shown.
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.1abbc9b8.css rel=stylesheet><link href=chunk-libs.5cf7f50a.css rel=stylesheet><link href=app.61bb0915.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.ba9393f3.js></script><script type=text/javascript src=static/js/chunk-elementUI.2de79b84.js></script><script type=text/javascript src=static/js/chunk-libs.76802be9.js></script><script type=text/javascript src=static/js/app.86bfcdf3.js></script></body></html>
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.40545a1f.css rel=stylesheet><link href=chunk-libs.0380664d.css rel=stylesheet><link href=app.07a1f8db.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.04c4fa2f.js></script><script type=text/javascript src=static/js/chunk-elementUI.8e5c404c.js></script><script type=text/javascript src=static/js/chunk-libs.f842b12e.js></script><script type=text/javascript src=static/js/app.1df22cde.js></script></body></html>
|
BIN
priv/static/adminfe/static/js/app.1df22cde.js
Normal file
BIN
priv/static/adminfe/static/js/app.1df22cde.js
Normal file
Binary file not shown.
BIN
priv/static/adminfe/static/js/app.1df22cde.js.map
Normal file
BIN
priv/static/adminfe/static/js/app.1df22cde.js.map
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
priv/static/adminfe/static/js/chunk-0171.9e927b8a.js.map
Normal file
BIN
priv/static/adminfe/static/js/chunk-0171.9e927b8a.js.map
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
priv/static/adminfe/static/js/chunk-565e.e1555105.js.map
Normal file
BIN
priv/static/adminfe/static/js/chunk-565e.e1555105.js.map
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
priv/static/adminfe/static/js/chunk-6e8c.2aa335e0.js
Normal file
BIN
priv/static/adminfe/static/js/chunk-6e8c.2aa335e0.js
Normal file
Binary file not shown.
BIN
priv/static/adminfe/static/js/chunk-6e8c.2aa335e0.js.map
Normal file
BIN
priv/static/adminfe/static/js/chunk-6e8c.2aa335e0.js.map
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
priv/static/adminfe/static/js/chunk-7503.278e0031.js.map
Normal file
BIN
priv/static/adminfe/static/js/chunk-7503.278e0031.js.map
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue