Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • coverage-stable
  • develop
  • feature/ability-to-add-custom-tags
  • feature/add-metrics-exporter-settings
  • feature/dynamic-settings-rendering
  • feature/fetchs-list-of-tabs
  • feature/media-preview-proxy
  • feature/post-pagination
  • feature/render-settings-dynamically
  • feature/settings-rollback
  • feature/update-styles
  • release/2.5.0
  • release/2.6
  • remove-workers
  • renovate/autoprefixer-10.x
  • renovate/babel-eslint-replacement
  • renovate/babel-loader-8.x
  • renovate/babel-monorepo
  • renovate/element-ui-2.x
  • renovate/sass-1.x
  • renovate/vue-monorepo
  • renovate/vue-test-utils-1.x
  • renovate/vue-test-utils-2.x
  • renovate/vuex-3.x
  • revert-fd9f0542
  • stable
  • 1.2.0
  • 2.4.0
  • 2.5.0
  • v2.0.2
  • v2.1.0
  • v2.2.0
32 results

Target

Select target project
No results found
Select Git revision
  • develop
  • display-name-emoji-packs
  • feature/add-new-user-filters
  • feature/edit-tags-manually
  • feature/update-styles
  • master
  • release/2.0.3
  • release/2.1.0
  • remove-ssh-gopher
  • 1.2.0
  • v2.0.2
  • v2.1.0
12 results
Show changes

Commits on Source 1688

1,588 additional commits have been omitted to prevent performance issues.
486 files
+ 36965
13891
Compare changes
  • Side-by-side
  • Inline

Files

+20 −7
Original line number Diff line number Diff line
{
  "presets": [
    ["env", {
      "modules": false,
    [
      "@babel/preset-env", {
        "modules": "auto",
        "targets": {
          "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
        }
    }],
    "stage-2"
      }
    ],
    "@vue/babel-preset-jsx"
  ],
  "plugins": [
    "@babel/plugin-transform-runtime",
    "@babel/plugin-syntax-dynamic-import"
  ],
  "plugins": ["transform-vue-jsx", "transform-runtime"]
  "env": {
    "development":{
      "plugins": ["dynamic-import-node-babel-7"]
    },
    "test":{
      "plugins": ["dynamic-import-node-babel-7"]
    }
  }
}

.dockerignore

0 → 100644
+32 −0
Original line number Diff line number Diff line
# SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
# SPDX-License-Identifier: AGPL-3.0-only

# block everything
**

# allowed files
!AGPL-3
!CHANGELOG.md
!README.md
!.babelrc
!.eslintignore
!.eslintrc.js
!.postcssrc.js
!favicon.ico
!index.html
!package.json
!yarn.lock

# allowed subdirectories
!/build/**
!/config/**
!/docker/**
!/public/**
!/static/**
!/src/**

# blocked subdirectory files
**/*.log
**/*~
**/.DS_Store
**/Thumbs.db
+3 −0
Original line number Diff line number Diff line
# SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
# SPDX-License-Identifier: MIT

# http://editorconfig.org
root = true

+3 −0
Original line number Diff line number Diff line
# SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
# SPDX-License-Identifier: MIT

build/*.js
config/*.js
src/assets
+20 −17
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

module.exports = {
  root: true,
  parser: 'babel-eslint',
  parserOptions: {
    parser: 'babel-eslint',
    sourceType: 'module'
  },
  env: {
@@ -9,22 +15,19 @@ module.exports = {
    node: true,
    es6: true,
  },
  extends: 'eslint:recommended',
  // required to lint *.vue files
  plugins: [
    'html'
  ],
  // check if imports actually resolve
  'settings': {
    'import/resolver': {
      'webpack': {
        'config': 'build/webpack.base.conf.js'
      }
    }
  },
  extends: ['plugin:vue/recommended', 'eslint:recommended'],

  // add your custom rules here
  //it is base on https://github.com/vuejs/eslint-config-vue
  'rules': {
  rules: {
    "vue/max-attributes-per-line": [2, {
      "singleline": 10,
      "multiline": {
        "max": 1,
        "allowFirstLine": false
      }
    }],
    "vue/name-property-casing": ["error", "PascalCase"],
    'accessor-pairs': 2,
    'arrow-spacing': [2, {
      'before': true,
@@ -144,7 +147,8 @@ module.exports = {
    'no-unsafe-finally': 2,
    'no-unused-vars': [2, {
      'vars': 'all',
      'args': 'none'
      'args': 'none',
      'ignoreRestSiblings': true
    }],
    'no-useless-call': 2,
    'no-useless-computed-key': 2,
@@ -196,4 +200,3 @@ module.exports = {
    'array-bracket-spacing': [2, 'never']
  }
}
+8 −0
Original line number Diff line number Diff line
# SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
# SPDX-License-Identifier: AGPL-3.0-only

.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
**/*.log

test/unit/coverage
test/e2e/reports
@@ -18,3 +25,4 @@ selenium-debug.log
*.sln

package-lock.json
coverage/

.gitlab-ci.yml

0 → 100644
+57 −0
Original line number Diff line number Diff line
# SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
# SPDX-License-Identifier: AGPL-3.0-only

image: node:20-alpine

variables: &global_variables
  DOCKER_DRIVER: overlay2
  DOCKER_HOST: unix:///var/run/docker.sock

cache: &global_cache_policy
  key: '$CI_COMMIT_SHORT_SHA'
  policy: pull-push
  paths:
    - node_modules/
    - build

stages:
  - build
  - test

build:
  stage: build
  before_script: &before-build
    - apk --no-cache add git python3 build-base
  script:
    - yarn
    - yarn build:prod
  artifacts: &release-artifacts
    name: "admin-fe-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA"
    paths:
      - dist/

lint:
  stage: test
  before_script: &before-yarn
    - apk --no-cache add git python3 build-base
    - yarn
  cache:
    key: '$CI_COMMIT_SHORT_SHA'
    policy: pull
  script:
    - yarn lint

test:
  stage: test
  before_script: *before-yarn
  cache:
    key: '$CI_COMMIT_SHORT_SHA'
    policy: pull
  script:
    - yarn test --coverage
  coverage: '/^Lines *: *([^ ]*%) [^%]*$/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
+6 −1
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

// https://github.com/michael-ciniawsky/postcss-load-config

module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {}

.reuse/dep5

0 → 100644
+9 −0
Original line number Diff line number Diff line
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://git.pleroma.social/pleroma/admin-fe/

# Grabbed from tiptap@1.29.6
# See https://github.com/ueberdosis/tiptap/blob/tiptap%401.29.6/LICENSE.md
# and https://github.com/ueberdosis/tiptap/tree/tiptap%401.29.6/examples/assets/images/icons
Files: src/icons/svg/tiptap-*.svg
Copyright: 2020 überdosis GbR
License: MIT

.tool-versions

0 → 100644
+2 −0
Original line number Diff line number Diff line
yarn 1.22.19
nodejs 20.14.0
+3 −0
Original line number Diff line number Diff line
# SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
# SPDX-License-Identifier: MIT

language: node_js
node_js: stable
script: npm run test

CHANGELOG.md

0 → 100644
+248 −0
Original line number Diff line number Diff line
<!--
SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
-->

# Changelog

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

### Added

### Changed

### Fixed
- The Service account type has been renamed to Bot so it's consistent with the termoniology used by most fediverse software.

## [2.5.0] - 2022-12-21

### Added
- Support for fine-grained privileges

### Added
- Support for fine-grained privileges

### Fixed
- Crash when parsing tuples in Settings
- Broken parsing of Settings

## [2.4.0] - 2021-08-01

### Added

- Evicting and banning objects from the MediaProxy cache is disabled if MediaProxy is disabled on the Settings tab. Add ability to enable MediaProxy and Invalidation from MediaProxy tab.
- Allow to upload the custom Terms of Service and Instance Panel HTML pages via Admin API
- Add Report show page and link Moderation log references to the respective reports
- Add Unconfimed filter for Users table
- Filter users by actor type: Person, Bot or Application
- Add ability to configure Media Preview Proxy, User Backup, Websocket based federation and Pleroma.Web.Endpoint.MetricsExporter settings
- Mobile and Tablet UI for Single Report show page
- Ability to set rules and conditions for rendering settings (e.g. `:proxy_remote` setting is hidden if `:uploader` setting is set to `Pleroma.Uploaders.Local`)
- Ability to install new frontends from the Frontend tab in the Settings section

### Changed

- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
- **Breaking**: AdminAPI changed User field `approval_pending` to `is_approved`
- **Breaking**: AdminAPI changed User field `deactivated` to `is_active`
- Hide Tag actions on Users tab if MRF TagPolicy is disabled. Add ability to enable TagPolicy from Moderation menu
- Move `:restrict_unauthenticated` settings from Authentication tab to Instance tab
- Replace regular inputs with textareas for setting welcome messages in the Settings section
- Remove Websocket based federation settings
- Move Settings tab navigation from the tabbed menu to the main sidebar menu. A separate route is created for each tab.
- Move Emoji packs configuration to the Emoji tab in the Settings section
- 401 and 404 error pages updated
- Remove unused components

### Fixed

- Fix depricatied action names in Reports, move actions that manage users from Reports to reports module
- Allow using underscores and hyphens in new account's usernames
- Fix wrapping `:icons` setting and parsing tuples in settings with key `:headers`
- Update keys for Pleroma.Web.Plugs.RemoteIp and PurgeExpiredActivity settings
- Update switching between local and remote emoji packs panels: the panel with the pack's metadata will be closed when another panel is opened
- Fix displaying messages for multiple errors
## [2.2] - 2020-11-18

### Added

- Ability to configure Media Preview Proxy settings on MediaProxy tab

### Fixed

- Update keys for PurgeExpiredActivity and RemoteIp settings
- Fix wrapping `:icons` setting and parsing tuples in settings with key `:headers`

## [2.1] - 2020-08-26

### Added

- Create `/statuses/:id` route that shows single status
- Add link to the user's account in Pleroma on the user's profile page
- On Reports page add links to reported account and the author of the report 
- In Notes add link to the note author's profile page 
- In Moderation log add link to the actor's profile page
- Support pagination of local emoji packs and files
- Add MRF Activity Expiration setting
- Add ability to disable multi-factor authentication for a user
- Add ability to configure Invalidation settings on MediaProxy tab
- Ability to configure `S3` settings on Upload tab, `Pleroma.Web.ApiSpec.CastAndValidate` and `:modules` settings on Other tab, `:pools`, `:connections_pool` and `:hackney_pools` settings on Job Queue tab, `:restrict_unauthenticated` settings on Authentication tab, `:favicons` and `:welcome` settings on Instance tab, `:frontends` and `Pleroma.Web.Preload` settings on Frontend tab
- Show number of open reports in Sidebar Menu
- Add confirmation message when deleting a user
- Add new MediaProxy Cache Tab with ability to manually evict and ban objects from the Pleroma MediaProxy cache
- Allow managing user's actor_type field via Admin API

### Changed

- Statuses count changes when an instance is selected and shows the amount of statuses from an originating instance
- Add a confirmation dialog window when Remove button is clicked on the Settings page
- Disable tab on the Settings page if there are no settings on this tab that can be changed in Admin FE
- Settings that can't be altered in Admin FE are removed: HTTP Signatures settings, Federation publisher modules and Oban Repo
- When rendering user's profile, statuses, reports and notes check if required properties exist
- Remove ability to moderate users that don't have valid nicknames
- Displays both labels and description in the header of group of settiings
- Ability to add custom values in Pleroma.Upload.Filter.Mogrify setting in the following format: '{"implode", "1"}'
- Change types of the following settings: ':groups', ':replace', ':federated_timeline_removal', ':reject', ':match_actor'. Update functions that parses and wraps settings data according to this change.
- Move rendering Crontab setting from a separate component to EditableKeyword component
- Show only those MRF settings that have been enabled in MRF Policies setting
- Move Auto Linker settings to Link Formatter Tab as its configuration was moved to :pleroma, Pleroma.Formatter
- Active and Local filters are applied by default on the Users tab
- Update Emoji Packs API to support special chars in pack names

### Fixed

- Send `true` and `false` as booleans if they are values of single selects on the Settings page
- Fix sorting users on Users page if there is an acount with missing nickname or ID
- Add new type of settings: `['string', 'image']`. Render Image upload Input depending on the type of setting, not its key
- Fix displaying `Pending` tag and filtering by Pending Approval status
- Fix following and unfollowing relays from Admin-FE, update mobile UI
- Support special chars in Emoji packs names

## [2.0.3] - 2020-04-29

### Added

- Link settings that enable registrations and invites
- Ability to upload logo, background, default user avatar, instance thumbnail, and NSFW hiding images

### Changed

- Put Instance Reboot button on all pages of admin-fe
- Make Instance Reboot button's positon fixed on Settings page
- Update jest and babel-jest
- Generate an invite link when an invite token has been generated
- Put labels on top of inputs in mobile version
- Shorten suggestions for a series of select inputs: Rewrite policy, Pleroma Authenticator, Captcha Method, Mailer adapter, Metadata providers, Rich Media parsers, TTL setters, Scrub policy, Uploader, Filters and Federation publisher modules

### Fixed

- Disable Invites tab when invites are disabled on BE

## [2.0.2] - 2020-04-01

### Added

- Ability to see local statuses in Statuses by instance section
- Ability to configure Oban.Cron settings and settings for notifications streamer
- Settings search
- Ability to set user's password and email on user's page
- Display status count by scope on Statuses page

### Changed

- Link to Pleroma docs when a non-admin user tries to log in 

### Fixed

- Fix parsing tuples in Pleroma.Upload.Filter.Mogrify and Pleroma.Emails.Mailer settings
- Fix settings submit button position on wide screens when sidebar menu is open
- Updates links for downloading remote emoji packs
- Fix parsing emails that have symbols in it

## [2.0] - 2020-02-27

### Added

- Optimistic update for actions in users module and fetching users after api function finished its execution
- Relay management
- Ability to fetch all statuses from a given instance
- Ability to confirm users' emails and resend confirmation emails
- Report notes
- Ability to moderate users on the statuses page
- Ability to moderate user on the user's page
- Ability to remove setting's updated value and set it back to initial value
- Ability to restart an application when settings that require instance reboot were changed
- Mobile and Tablet UI for all sections

### Changed

- **breaking** PleromaFE login feature relies on `admin` scope presence in PleromaFE token (older versions of PleromaFE don't support it)
- `mailerEnabled` must be set to `true` in order to require password reset (password reset currently only works via email)
- Render inputs for configuring settings based on description that comes from the BE
- Remove fetching initial data for configuring server settings
- Actions in users module (ActivateUsers, AddRight, DeactivateUsers, DeleteRight, DeleteUsers) now accept an array of users instead of one user
- Leave dropdown menu open after clicking an action
- Display checkboxes in status card and fetch statuses only when status card was rendered from Statuses by instance page
- Move statuses by instance state from local state to store state

### Fixed

- Show checkmarks when tag is applied
- Reports update (also, now it's optimistic)
- Remove duplicated success message
- Fix styles for Statuses by instance page
- Fix styles for Reports section
- Fix listing remote emoji

## [1.2.0] - 2019-09-27

### Added

- Emoji pack configuration
- Statuses page: fetch all statuses from a given instance
- Ability to require user's password reset
– Ability to track admin/moderator actions, a.k.a. "the moderation log"

## [1.1.0] - 2019-09-15

### Added

- adds ability to configure new settings (UploadS3 bucket namespace, Rate limit for Activity pub routes, Email notifications settings, MRF Vocabulary, user bio and name length and others)
- adds ability to disable certain features (settings/reports/invites)
- adds sign in via PleromaFE
- adds ability to generate invite tokens and list them on a separate tab
- adds ability to invite users via email
- adds ability to reset users passwords
- adds tests for invites and resetting password

### Changed

- removes "Dashboard" from dropdown menu
- makes all single selects clearable and allow to enter custom values in all multiple selects
- removes legacy activitypub accept_blocks setting

### Fixed

- converts maps and structs to JS objects, not array of tuples when wrapping config
- changes type of IP value from string to number
- updates error handling for users and invites modules

## [1.0.1] - 2019-08-15

### Fixed

- fixes inputs for renders_errors and rewrite_policy settings
- removes unnecessary computed properties
- enables source maps for production build

## [1.0.0] - 2019-08-14

Starting this changelog, for now we have:

- User management system
- Reports management
- Pleroma configuration (unstable)

Dockerfile

0 → 100644
+41 −0
Original line number Diff line number Diff line
# SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
# SPDX-License-Identifier: AGPL-3.0-only

FROM node:16-alpine as build

COPY . .

RUN apk --no-cache add git && \
    npm install && \
    npm run build:prod

FROM nginx:mainline-alpine

LABEL maintainer="ops@pleroma.social" \
    org.opencontainers.image.title="pleroma-adminfe" \
    org.opencontainers.image.description="Pleroma-adminfe for Docker" \
    org.opencontainers.image.authors="ops@pleroma.social" \
    org.opencontainers.image.vendor="pleroma.social" \
    org.opencontainers.image.documentation="https://git.pleroma.social/pleroma/pleroma-adminfe" \
    org.opencontainers.image.licenses="AGPL-3.0" \
    org.opencontainers.image.url="https://pleroma.social" \
    org.opencontainers.image.revision=$VCS_REF \
    org.opencontainers.image.created=$BUILD_DATE


ARG DATA=/usr/share/nginx/html

COPY --from=build /dist/ ${DATA}

COPY ./docker/docker-entrypoint.sh /usr/local/bin/

COPY ./docker/nginx.conf.tpl /etc/nginx/nginx.conf.tpl

RUN apk add --no-cache gettext

EXPOSE 80

ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]

CMD exec nginx -g 'daemon off;'

LICENSE

deleted100644 → 0
+0 −21
Original line number Diff line number Diff line
MIT License

Copyright (c) 2017-present PanJiaChen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

LICENSES/MIT.txt

0 → 100644
+9 −0
Original line number Diff line number Diff line
MIT License

Copyright (c) <year> <copyright holders>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+58 −119
Original line number Diff line number Diff line
<p align="center">
  <img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg">
</p>
# Pleroma AdminFE

<p align="center">
	<a href="https://github.com/vuejs/vue">
		<img src="https://img.shields.io/badge/vue-2.5.10-brightgreen.svg" alt="vue">
	</a>
	<a href="https://github.com/ElemeFE/element">
		<img src="https://img.shields.io/badge/element--ui-2.0.8-brightgreen.svg" alt="element-ui">
	</a>
	<a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow">
		<img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status">
	</a>
	<a href="https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE">
		<img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license">
	</a>
	<a href="https://github.com/PanJiaChen/vue-element-admin/releases">
		<img src="https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg" alt="GitHub release">
	</a>
</p>
![screenshot](./public/index.png)

English | [简体中文](./README.zh-CN.md)
## About

## Introduction
Admin UI for pleroma instance owners.

`vue-element-admin` is a production-ready solution for admin interfaces. Based on [Vue.js](https://github.com/vuejs/vue) and use the UI Toolkit -- [element](https://github.com/ElemeFE/element). `vue-element-admin` is a magical vue admin, it based on the newest development stack of vue, built-in i18n solution, typical templates for enterprise applications, lots of awesome features. It helps you build a large complex Single-Page Applications. I believe whatever your needs are, this project will help you.
### Branches

- [Preview](http://panjiachen.github.io/vue-element-admin)
There are two main branches here:

- [Documentation](https://panjiachen.github.io/vue-element-admin-site/#/)
- `develop`: ongoing work and all merge requests go here, *unstable*
- `stable`: after `develop` is stabilized it is merged to `stable`, *stable*, allegedly

- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
### Features

- [Donate](https://panjiachen.github.io/vue-element-admin-site/#/donate)
1. User administration: grant roles to users (admin/moderator), deactivate/delete as well as force their statuses to have NSFW tag, strip media and many more
1. Invites management: generate invite tokens & send invites via email
1. Moderation log: track moderator/admin actions
1. Settings: configure your pleroma instance via friendly (hopefully) UI
1. Emoji packs: configure your emoji packs

**vue-element-admin is a admin interfaces integration solution, which is not suitable for secondary development as a base template.**
You can have any combination of these features (i.e. you can disable anything, but user administration, see "Disabling features" section below).

 - Base template recommends using: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)  
 - Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
## Usage

**Note: This project uses element-ui@2.0.0+ version, so the minimum compatible vue@2.5.0+**
### Bundled

## Preparation
AdminFE is bundled with Pleroma, i.e. you can just visit `https://your.instance/pleroma/admin/` to try it out.

You need to install [node](http://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](http://es6.ruanyifeng.com/)[vue](https://cn.vuejs.org/index.html)[vuex](https://vuex.vuejs.org/zh-cn/)[vue-router](https://router.vuejs.org/zh-cn/)[element-ui](https://github.com/ElemeFE/element). All data requests for this project are simulated using [Mock.js](https://github.com/nuysoft/Mock). It would be helpful if you have pre-existing knowledge on those.
### Development

 **This project is not a scaffolding and is more of an integrated solution.**
To run AdminFE locally execute

 **This project does not support low version browsers (e.g. IE). Please add polyfill yourself if you need them.**

 <p align="center">
  <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
</p>

## Features
```
- Login / Logout
- Permission authentication
- Multi-environment build
- Dynamic sidebar (supports multi-level routing)
- Dynamic breadcrumb
- I18n
- Customizable theme
- Tags-view(Tab page Support right-click operation)
- Rich text editor
- Markdown editor
- JSON editor
- Screenfull
- Drag and drop list
- Svg Sprite
- Dashboard
- Mock data
- Echarts
- Clipboard
- 401/404 error page
- Error log
- Export excel
- Export zip
- Front-end visualization excel
- Tree Table
- Table example
- Dynamictable example
- Drag and drop table example
- Inline edit table example
- Form example
- Two-step login
- SplitPane
- Dropzone
- Sticky
- CountTo
- Markdown to html
```
# install dependencies
npm install -g yarn
yarn

## Getting started

```bash
# clone the project
git clone https://github.com/PanJiaChen/vue-element-admin.git

# install dependency
npm install

# develop
npm run dev
# run AdminFE locally
yarn dev
```

This will automatically open http://localhost:9527.
### Build

## Build
```bash
# build for test environment
npm run build:sit
To compile everything for production run

# build for production environment
npm run build:prod
```
# install dependencies
npm install -g yarn
yarn

## Advanced
```bash
# --report to build with bundle size analytics
npm run build:prod --report
# compile everything for production
yarn build:prod
```

# --preview to start a server in local to preview
npm run build:prod --preview
This will build admin-fe into `dist` folder, which you will need to upload to your server and/or point your webserver of choice to.

# lint code
npm run lint
#### Disabling features

# auto fix
npm run lint -- --fix
```
You can disable certain AdminFE features, like reports or settings by modifying `config/prod.env.js` env variable `DISABLED_FEATURES`, e.g. if you want to compile AdminFE without "Settings" you'll need to set it to: `DISABLED_FEATURES: '["settings"]'`.

Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/#/deploy) for more information
Features, that can be disabled:

## Changelog
Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
- reports: `DISABLED_FEATURES: '["reports"]'`
- invites: `DISABLED_FEATURES: '["invites"]'`
- moderation log: `DISABLED_FEATURES: '["moderationLog"]'`
- settings: `DISABLED_FEATURES: '["settings"]'`
- emoji packs: `DISABLED_FEATURES: '["emojiPacks"]'`

## Online Demo
[Preview](http://panjiachen.github.io/vue-element-admin)
Of course, you can disable multiple features just by adding to the array, e.g. `DISABLED_FEATURES: '["emojiPacks", "settings"]'` will have both emoji packs and settings disabled.

## Donate
If you find this project useful, you can buy author a glass of juice :tropical_drink:
Users administration cannot be disabled.

![donate](https://wpimg.wallstcn.com/bd273f0d-83a0-4ef2-92e1-9ac8ed3746b9.png)
## Changelog

[Paypal Me](https://www.paypal.me/panfree23)
Detailed changes for each release are documented in the [CHANGELOG](./CHANGELOG.md).

[Buy me a coffee](https://www.buymeacoffee.com/Pan)
## Browsers support

## License
Modern browsers and Internet Explorer 10+.

[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions

Copyright (c) 2017-present PanJiaChen
## Copyright
```
Copyright 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
SPDX-License-Identifier: MIT
Copyright 2019-2022 Pleroma Authors <https://pleroma.social>
SPDX-License-Identifier: AGPL-3.0-only
```

README.zh-CN.md

deleted100644 → 0
+0 −166
Original line number Diff line number Diff line
<p align="center">
  <img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg">
</p>

<p align="center">
	<a href="https://github.com/vuejs/vue">
		<img src="https://img.shields.io/badge/vue-2.5.10-brightgreen.svg" alt="vue">
	</a>
	<a href="https://github.com/ElemeFE/element">
		<img src="https://img.shields.io/badge/element--ui-2.0.8-brightgreen.svg" alt="element-ui">
	</a>
	<a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow">
		<img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Build Status">
	</a>
	<a href="https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE">
		<img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license">
	</a>
	<a href="https://github.com/PanJiaChen/vue-element-admin/releases">
		<img src="https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg" alt="GitHub release">
	</a>
</p>

简体中文 | [English](./README.md)

## 简介

`vue-element-admin` 是一个后台集成解决方案,它基于 [Vue.js](https://github.com/vuejs/vue)[element](https://github.com/ElemeFE/element)。它使用了最新的前端技术栈,内置了i18国际化解决方案,动态路由,权限验证等很多功能特性,相信不管你的需求是什么,本项目都能帮助到你。

- [在线访问](http://panjiachen.github.io/vue-element-admin)

- [使用文档](https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/)

- [Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)

- [Donate](https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/donate)

**本项目的定位是后台集成方案,不适合当基础模板来开发。**
 - 模板建议使用: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)  
 - 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)

**注意:该项目使用 element-ui@2.0.0+ 版本,所以最低兼容 vue@2.5.0+**

## 前序准备

你的本地环境需要安装 [node](http://nodejs.org/)[git](https://git-scm.com/)。我们的技术栈基于 [ES2015+](http://es6.ruanyifeng.com/)[vue](https://cn.vuejs.org/index.html)[vuex](https://vuex.vuejs.org/zh-cn/)[vue-router](https://router.vuejs.org/zh-cn/) and [element-ui](https://github.com/ElemeFE/element),所有的请求数据都使用[Mock.js](https://github.com/nuysoft/Mock)模拟,提前了解和学习这些知识会对使用本项目有很大的帮助。

同时配套一个系列的教程文章,如何从零构建后一个完整的后台项目,建议大家先看完这些文章再来实践本项目
 - [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
 - [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
 - [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
 - [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
 - [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
 - [手摸手,带你优雅的使用 icon](https://juejin.im/post/59bb864b5188257e7a427c09)

 响应需求,开了一个qq群 `591724180` 方便大家交流

 或者加入该群主 **[圈子](https://jianshiapp.com/circles/1209)** 楼主会经常分享一些技术相关的东西

 **如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr**

 **本项目并不是一个脚手架,更倾向于是一个集成解决方案**

 **该项目不支持低版本浏览器(如ie),有需求请自行添加polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**

 <p align="center">
  <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
</p>

## 功能
```
- 登录/注销
- 权限验证
- 多环境发布
- 动态侧边栏(支持多级路由)
- 动态面包屑
- 国际化多语言
- 多种动态换肤
- 快捷导航(标签页)
- 富文本编辑器
- Markdown编辑器
- JSON编辑器
- Screenfull全屏
- 列表拖拽
- Svg Sprite 图标
- Dashboard
- 本地mock数据
- Echarts 图表
- Clipboard(剪贴复制)
- 401/404错误页面
- 错误日志
- 导出excel
- 导出zip
- 前端可视化excel
- 树形table
- Table example
- 动态table example
- 拖拽table example
- 内联编辑table example
- Form example
- 二步登录
- SplitPane
- Dropzone
- Sticky
- CountTo
- Markdown2html
```

## 开发
```bash
# 克隆项目
git clone https://github.com/PanJiaChen/vue-element-admin.git

# 安装依赖
npm install
   
# 建议不要用cnpm安装 会有各种诡异的bug 可以通过如下操作解决 npm 下载速度慢的问题
npm install --registry=https://registry.npm.taobao.org

# 启动服务
npm run dev
```
浏览器访问 http://localhost:9527

## 发布
```bash
# 构建测试环境
npm run build:sit

# 构建生成环境
npm run build:prod
```

## 其它
```bash
# --report to build with bundle size analytics
npm run build:prod --report

# --preview to start a server in local to preview
npm run build:prod --preview

# lint code
npm run lint

# auto fix
npm run lint -- --fix
```

更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/#/zh-cn/deploy)

## Changelog
Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).

## Online Demo
[在线 Demo](http://panjiachen.github.io/vue-element-admin)

## Donate
如果你觉得这个项目帮助到了你,你可以帮作者买一杯果汁表示鼓励 :tropical_drink:
![donate](https://panjiachen.github.io/donate/donation.png)

[Paypal Me](https://www.paypal.me/panfree23)

## License

[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)

Copyright (c) 2017-present PanJiaChen
+43 −25
Original line number Diff line number Diff line
'use strict'
require('./check-versions')()
// SPDX-FileCopyrightText: 2017-2018 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: 2022 Pleroma Authors <https://pleroma.social>

'use strict'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const server = require('pushstate-server')
var connect = require('connect')
var serveStatic = require('serve-static')

var spinner = ora('building for '+ process.env.env_config+ ' environment...' )
const spinner = ora(
  'building for ' + process.env.env_config + ' environment...'
)
spinner.start()

rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
@@ -18,31 +24,43 @@ rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  webpack(webpackConfig, (err, stats) => {
    spinner.stop()
    if (err) throw err
    process.stdout.write(stats.toString({
    process.stdout.write(
      stats.toString({
        colors: true,
        modules: false,
        children: false,
        chunks: false,
        chunkModules: false
    }) + '\n\n')
      }) + '\n\n'
    )

    if (stats.hasErrors()) {
      console.log(chalk.red('  Build failed with errors.\n'))
      console.log(' Build failed with errors.\n')
      process.exit(1)
    }

    console.log(chalk.cyan('  Build complete.\n'))
    console.log(chalk.yellow(
    console.log(' Build complete.\n')
    console.log(
        ' Tip: built files are meant to be served over an HTTP server.\n' +
      '  Opening index.html over file:// won\'t work.\n'
    ))
          " Opening index.html over file:// won't work.\n"
    )

    if (process.env.npm_config_preview) {
      server.start({
          port: 9526,
          directory: './dist',
          file: '/index.html'
      });
      console.log('> Listening at ' +  'http://localhost:9526' + '\n')
      const port = 9526
      const host = 'http://localhost:' + port
      const basePath = config.build.assetsPublicPath
      const app = connect()

      app.use(
        basePath,
        serveStatic('./dist', {
          index: ['index.html', '/']
        })
      )

      app.listen(port, function() {
        console.log(`> Listening at  http://localhost:${port}${basePath}`)
      })
    }
  })
})

build/check-versions.js

deleted100644 → 0
+0 −54
Original line number Diff line number Diff line
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')

function exec (cmd) {
  return require('child_process').execSync(cmd).toString().trim()
}

const versionRequirements = [
  {
    name: 'node',
    currentVersion: semver.clean(process.version),
    versionRequirement: packageConfig.engines.node
  }
]

if (shell.which('npm')) {
  versionRequirements.push({
    name: 'npm',
    currentVersion: exec('npm --version'),
    versionRequirement: packageConfig.engines.npm
  })
}

module.exports = function () {
  const warnings = []

  for (let i = 0; i < versionRequirements.length; i++) {
    const mod = versionRequirements[i]

    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
      warnings.push(mod.name + ': ' +
        chalk.red(mod.currentVersion) + ' should be ' +
        chalk.green(mod.versionRequirement)
      )
    }
  }

  if (warnings.length) {
    console.log('')
    console.log(chalk.yellow('To use this template, you must update following to modules:'))
    console.log()

    for (let i = 0; i < warnings.length; i++) {
      const warning = warnings[i]
      console.log('  ' + warning)
    }

    console.log()
    process.exit(1)
  }
}
+34 −39
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2018 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const packageConfig = require('../package.json')

exports.assetsPath = function(_path) {
  const assetsSubDirectory = process.env.NODE_ENV === 'production'
  const assetsSubDirectory =
    process.env.NODE_ENV === 'production'
      ? config.build.assetsSubDirectory
      : config.dev.assetsSubDirectory

@@ -31,7 +38,21 @@ exports.cssLoaders = function (options) {

  // generate loader string to be used with extract text plugin
  function generateLoaders(loader, loaderOptions) {
    const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
    const loaders = []

    // Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
      loaders.push(MiniCssExtractPlugin.loader)
    } else {
      loaders.push('vue-style-loader')
    }

    loaders.push(cssLoader)

    if (options.usePostCSS) {
      loaders.push(postcssLoader)
    }

    if (loader) {
      loaders.push({
@@ -42,24 +63,16 @@ exports.cssLoaders = function (options) {
      })
    }

    // Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader'
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    return loaders
  }
  }

  // https://vue-loader.vuejs.org/en/configurations/extract-css.html
  return {
    css: generateLoaders(),
    postcss: generateLoaders(),
    less: generateLoaders('less'),
    sass: generateLoaders('sass', { indentedSyntax: true }),
    sass: generateLoaders('sass', {
      indentedSyntax: true
    }),
    scss: generateLoaders('sass'),
    stylus: generateLoaders('stylus'),
    styl: generateLoaders('stylus')
@@ -81,21 +94,3 @@ exports.styleLoaders = function (options) {

  return output
}

exports.createNotifierCallback = () => {
  const notifier = require('node-notifier')

  return (severity, errors) => {
    if (severity !== 'error') return

    const error = errors[0]
    const filename = error.file && error.file.split('!').pop()

    notifier.notify({
      title: packageConfig.name,
      message: severity + ': ' + error.name,
      subtitle: filename || '',
      icon: path.join(__dirname, 'logo.png')
    })
  }
}
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2018 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT

'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
  ? config.build.productionSourceMap
  : config.dev.cssSourceMap

module.exports = {
  loaders: utils.cssLoaders({
    sourceMap: sourceMapEnabled,
    extract: isProduction
  }),
  cssSourceMap: sourceMapEnabled,
  cacheBusting: config.dev.cacheBusting,
  transformToRequire: {
    video: ['src', 'poster'],
    source: 'src',
    img: 'src',
    image: 'xlink:href'
  }
  //You can set the vue-loader configuration by yourself.
}
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2018 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const { VueLoaderPlugin } = require('vue-loader')
const vueLoaderConfig = require('./vue-loader.conf')

function resolve(dir) {
@@ -27,15 +34,16 @@ module.exports = {
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
    publicPath:
      process.env.NODE_ENV === 'production'
        ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
        : config.dev.assetsPublicPath,
    hashFunction: 'sha512'
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      '@': resolve('src')
    }
  },
  module: {
@@ -49,7 +57,11 @@ module.exports = {
      {
        test: /\.js$/,
        loader: 'babel-loader?cacheDirectory',
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
        include: [
          resolve('src'),
          resolve('test'),
          resolve('node_modules/webpack-dev-server/client')
        ]
      },
      {
        test: /\.svg$/,
@@ -60,32 +72,24 @@ module.exports = {
        }
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        test: /\.(png|jpe?g|gif)(\?.*)?$/,
        loader: 'file-loader',
        exclude: [resolve('src/icons')],
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        loader: 'file-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  },
  plugins: [new VueLoaderPlugin()],
  node: {
    // prevent webpack from injecting useless setImmediate polyfill because Vue
    // source contains it (although only uses it if it's native).
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2018 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

'use strict'
const path = require('path')
const utils = require('./utils')
@@ -6,8 +12,6 @@ const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')

function resolve(dir) {
  return path.join(__dirname, '..', dir)
@@ -16,9 +20,15 @@ function resolve (dir) {
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)

const devEnv = require('../config/dev.env')

const devWebpackConfig = merge(baseWebpackConfig, {
  mode: 'development',
  module: {
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
    rules: utils.styleLoaders({
      sourceMap: config.dev.cssSourceMap,
      usePostCSS: true
    })
  },
  // cheap-module-eval-source-map is faster for development
  devtool: config.dev.devtool,
@@ -35,11 +45,13 @@ const devWebpackConfig = merge(baseWebpackConfig, {
    overlay: config.dev.errorOverlay
      ? { warnings: false, errors: true }
      : false,
    publicPath: config.dev.assetsPublicPath,
    publicPath: devEnv.ASSETS_PUBLIC_PATH,
    proxy: config.dev.proxyTable,
    quiet: true, // necessary for FriendlyErrorsPlugin
    watchOptions: {
      poll: config.dev.poll,
      poll: config.dev.poll
    },
    headers: {
      'content-security-policy': "base-uri 'self'; frame-ancestors 'none'; img-src 'self' data: https: http:; media-src 'self' https:; style-src 'self' 'unsafe-inline'; font-src 'self'; manifest-src 'self'; script-src 'self';"
    }
  },
  plugins: [
@@ -47,42 +59,20 @@ const devWebpackConfig = merge(baseWebpackConfig, {
      'process.env': require('../config/dev.env')
    }),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
    new webpack.NoEmitOnErrorsPlugin(),
    // https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true,
      favicon: resolve('favicon.ico'),
      title: 'vue-element-admin',
      path: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
      title: 'Admin FE',
      templateParameters: {
        BASE_URL: devEnv.ASSETS_PUBLIC_PATH + config.dev.assetsSubDirectory,
      },
    }),
  ]
})

module.exports = new Promise((resolve, reject) => {
  portfinder.basePort = process.env.PORT || config.dev.port
  portfinder.getPort((err, port) => {
    if (err) {
      reject(err)
    } else {
      // publish the new Port, necessary for e2e tests
      process.env.PORT = port
      // add port to devServer config
      devWebpackConfig.devServer.port = port

      // Add FriendlyErrorsPlugin
      devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
        compilationSuccessInfo: {
          messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
        },
        onErrors: config.dev.notifyOnErrors
        ? utils.createNotifierCallback()
        : undefined
      }))

  resolve(devWebpackConfig)
    }
  })
})
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2018 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

'use strict'
const path = require('path')
const utils = require('./utils')
@@ -5,10 +11,9 @@ const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

function resolve(dir) {
@@ -17,7 +22,12 @@ function resolve (dir) {

const env = require('../config/' + process.env.env_config + '.env')

// For NamedChunksPlugin
const seen = new Set()
const nameLength = 4

const webpackConfig = merge(baseWebpackConfig, {
  mode: 'production',
  module: {
    rules: utils.styleLoaders({
      sourceMap: config.build.productionSourceMap,
@@ -28,37 +38,18 @@ const webpackConfig = merge(baseWebpackConfig, {
  devtool: config.build.productionSourceMap ? config.build.devtool : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
    filename: utils.assetsPath('js/[name].[chunkhash:8].js'),
    chunkFilename: utils.assetsPath('js/[name].[chunkhash:8].js')
  },
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new UglifyJsPlugin({
      uglifyOptions: {
        compress: {
          warnings: false
        }
      },
      sourceMap: config.build.productionSourceMap,
      parallel: true
    }),
    // extract css into its own file
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].[contenthash].css'),
      // Setting the following option to `false` will not extract CSS from codesplit chunks.
      // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
      // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
      allChunks: false,
    }),
    // Compress extracted CSS. We are using this plugin so that possible
    // duplicated CSS from different components can be deduped.
    new OptimizeCSSPlugin({
      cssProcessorOptions: config.build.productionSourceMap
        ? { safe: true, map: { inline: false } }
        : { safe: true }
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash:8].css',
      chunkFilename: '[name].[contenthash:8].css'
    }),
    // generate dist index.html with correct asset hash for caching.
    // you can customize output by editing /index.html
@@ -68,85 +59,82 @@ const webpackConfig = merge(baseWebpackConfig, {
      template: 'index.html',
      inject: true,
      favicon: resolve('favicon.ico'),
      title: 'vue-element-admin',
      path: config.build.assetsPublicPath + config.build.assetsSubDirectory,
      title: 'Admin FE',
      templateParameters: {
        BASE_URL: env.ASSETS_PUBLIC_PATH + config.build.assetsSubDirectory,
      },
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    // keep module.id stable when vender modules does not change
    new webpack.HashedModuleIdsPlugin(),
    // enable scope hoisting
    new webpack.optimize.ModuleConcatenationPlugin(),
    // split vendor js into its own file
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks (module) {
        // any required modules inside node_modules are extracted to vendor
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
      // default sort mode uses toposort which cannot handle cyclic deps
      // in certain cases, and in webpack 4, chunk order in HTML doesn't
      // matter anyway
    }),
    // extract webpack runtime and module manifest to its own file in order to
    // prevent vendor hash from being updated whenever app bundle is updated
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      minChunks: Infinity
    }),
    // This instance extracts shared chunks from code splitted chunks and bundles them
    // in a separate chunk, similar to the vendor chunk
    // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
    new webpack.optimize.CommonsChunkPlugin({
      name: 'app',
      async: 'vendor-async',
      children: true,
      minChunks: 3
    }),
    // split echarts into its own file
    new webpack.optimize.CommonsChunkPlugin({
      async: 'echarts',
      minChunks(module) {
        var context = module.context;
        return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
    // keep chunk.id stable when chunk has no name
    new webpack.NamedChunksPlugin(chunk => {
      if (chunk.name) {
        return chunk.name
      }
    }),
    // split xlsx into its own file
    new webpack.optimize.CommonsChunkPlugin({
      async: 'xlsx',
      minChunks(module) {
        var context = module.context;
        return context && (context.indexOf('xlsx') >= 0);
      const modules = Array.from(chunk.modulesIterable)
      if (modules.length > 1) {
        const hash = require('hash-sum')
        const joinedHash = hash(modules.map(m => m.id).join('_'))
        let len = nameLength
        while (seen.has(joinedHash.substr(0, len))) len++
        seen.add(joinedHash.substr(0, len))
        return `chunk-${joinedHash.substr(0, len)}`
      } else {
        return modules[0].id
      }
    }),
     // split codemirror into its own file
     new webpack.optimize.CommonsChunkPlugin({
      async: 'codemirror',
      minChunks(module) {
        var context = module.context;
        return context && (context.indexOf('codemirror') >= 0);
    // keep module.id stable when vender modules does not change
    new webpack.HashedModuleIdsPlugin(),
  ],
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        libs: {
          name: 'chunk-libs',
          test: /[\\/]node_modules[\\/]/,
          priority: 10,
          chunks: 'initial' // 只打包初始时依赖的第三方
        },
        elementUI: {
          name: 'chunk-elementUI', // 单独将 elementUI 拆包
          priority: 20, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
          test: /[\\/]node_modules[\\/]element-ui[\\/]/
        },
        commons: {
          name: 'chunk-commons',
          test: resolve('src/components'), // 可自定义拓展你的规则
          minChunks: 3, // 最小公用次数
          priority: 5,
          reuseExistingChunk: true
        }
    }),

    // copy custom static assets
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../static'),
        to: config.build.assetsSubDirectory,
        ignore: ['.*']
      }
    ])
    },
    runtimeChunk: 'single',
    minimizer: [
      new UglifyJsPlugin({
        uglifyOptions: {
          mangle: {
            safari10: true
          }
        },
        sourceMap: config.build.productionSourceMap,
        cache: true,
        parallel: true
      }),
      // Compress extracted CSS. We are using this plugin so that possible
      // duplicated CSS from different components can be deduped.
      new OptimizeCSSAssetsPlugin()
    ]
  }
})

if (config.build.productionGzip) {
@@ -154,12 +142,9 @@ if (config.build.productionGzip) {

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
        '\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
@@ -167,9 +152,4 @@ if (config.build.productionGzip) {
  )
}

if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

module.exports = {
  NODE_ENV: '"development"',
  ENV_CONFIG: '"dev"',
	BASE_API: '"https://api-dev"'
  DISABLED_FEATURES: '[""]',
  ASSETS_PUBLIC_PATH: '/'
}
+28 −17
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

'use strict'
// Template version: 1.2.6
// see http://vuejs-templates.github.io/webpack for documentation.
@@ -6,14 +12,16 @@ const path = require('path')

module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    // assetsPublicPath: '', // To configure assetsPublicPath set ASSETS_PUBLIC_PATH in dev/prod.env.js
    proxyTable: {},

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST

    // can be overwritten by process.env.HOST
    // if you want dev by ip, please set host: '0.0.0.0'
    host: 'localhost',
    port: 9527, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: true,
    errorOverlay: true,
@@ -33,19 +41,14 @@ module.exports = {
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: '#cheap-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,
    devtool: 'cheap-source-map',

    // CSS Sourcemaps off by default because relative paths are "buggy"
    // with this option, according to the CSS-Loader README
    // (https://github.com/webpack/css-loader#sourcemaps)
    // In our experience, they generally work as expected,
    // just be aware of this issue when enabling this option.
    cssSourceMap: false,
    cssSourceMap: false
  },

  build: {
@@ -56,16 +59,21 @@ module.exports = {
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',

    // you can set by youself according to actual condition
    assetsPublicPath: './',
    /**
     * You can set by youself according to actual condition
     * You will need to set this if you plan to deploy your site under a sub path,
     * for example GitHub pages. If you plan to deploy your site to https://foo.github.io/bar/,
     * then assetsPublicPath should be set to "/bar/".
     * In most cases please use '/' !!!
     */
    // assetsPublicPath: '', // To configure assetsPublicPath set ASSETS_PUBLIC_PATH in dev/prod.env.js

    /**
     * Source Maps
     */

    productionSourceMap: false,
    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',
    devtool: 'source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
@@ -76,8 +84,11 @@ module.exports = {

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // `npm run build:prod --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
    bundleAnalyzerReport: process.env.npm_config_report || false,

    // `npm run build:prod --generate_report`
    generateAnalyzerReport: process.env.npm_config_generate_report || false
  }
}
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>

module.exports = {
  NODE_ENV: '"production"',
  ENV_CONFIG: '"prod"',
	BASE_API: '"https://api-prod"'
  BASE_API: '"https://api-prod"',
  DISABLED_FEATURES: '[""]',
  ASSETS_PUBLIC_PATH: '/pleroma/admin/'
}
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT

module.exports = {
  NODE_ENV: '"production"',
  ENV_CONFIG: '"sit"',
+8 −0
Original line number Diff line number Diff line
#!/bin/sh

# SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
# SPDX-License-Identifier: AGPL-3.0-only

set -e
envsubst "$(env | sed -e 's/=.*//' -e 's/^/\$/g')" < "/etc/nginx/nginx.conf.tpl" > "/etc/nginx/nginx.conf"
exec "$@"

docker/nginx.conf.tpl

0 → 100644
+35 −0
Original line number Diff line number Diff line
# SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
# SPDX-License-Identifier: AGPL-3.0-only

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /tmp/nginx.pid;
events {
    worker_connections  1024;
}
http {
    client_body_temp_path /tmp/client_temp;
    proxy_temp_path       /tmp/proxy_temp_path;
    fastcgi_temp_path     /tmp/fastcgi_temp;
    uwsgi_temp_path       /tmp/uwsgi_temp;
    scgi_temp_path        /tmp/scgi_temp;
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    keepalive_timeout  65;
    proxy_cache_path /tmp/pleroma-media-cache levels=1:2 keys_zone=pleroma_media_cache:10m max_size=10g
                     inactive=720m use_temp_path=off;
    server {
        listen 80;
        server_name _;
        root /usr/share/nginx/html;
        location / {
        try_files $uri $uri/ /index.html;
      }
    }
}
+16 −12
Original line number Diff line number Diff line
<!--
SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
SPDX-License-Identifier: MIT
-->

<!DOCTYPE html>
<html>
  <head>
@@ -5,9 +10,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>vue-element-admin</title>
    <title>Admin FE</title>
  </head>
	<script src=<%= htmlWebpackPlugin.options.path %>/tinymce4.7.5/tinymce.min.js></script>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
+114 −77
Original line number Diff line number Diff line
{
  "name": "vue-element-admin",
  "version": "3.6.2",
  "version": "3.10.0",
  "description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features",
  "author": "Pan <panfree23@gmail.com>",
  "license": "MIT",
  "private": true,
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
    "build:sit": "cross-env NODE_ENV=production env_config=sit node build/build.js",
    "dev": "cross-env BABEL_ENV=development NODE_OPTIONS=--openssl-legacy-provider webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "build:prod": "cross-env NODE_OPTIONS=--openssl-legacy-provider NODE_ENV=production env_config=prod node build/build.js",
    "build:sit": "cross-env NODE_OPTIONS=--openssl-legacy-provider NODE_ENV=production env_config=sit node build/build.js",
    "lint": "eslint --ext .js,.vue src",
    "test": "npm run lint"
    "test": "jest",
    "test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand",
    "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.json"
  },
  "keywords": [
    "vue",
    "element-ui",
    "admin",
    "management-system",
    "admin-template"
  ],
  "repository": {
    "type": "git",
    "url": "git+https://git.pleroma.social/pleroma/admin-fe.git"
  },
  "resolutions": {
    "prosemirror-model": "1.18.3"
  },
  "bugs": {
    "url": "https://git.pleroma.social/pleroma/admin-fe/-/issues"
  },
  "dependencies": {
    "axios": "0.17.1",
    "clipboard": "1.7.1",
    "codemirror": "5.32.0",
    "dropzone": "5.2.0",
    "echarts": "3.8.5",
    "element-ui": "2.0.8",
    "file-saver": "1.3.3",
    "font-awesome": "4.7.0",
    "js-cookie": "2.2.0",
    "jsonlint": "1.6.2",
    "jszip": "3.1.5",
    "mockjs": "1.0.1-beta3",
    "@babel/runtime": "7.19.0",
    "axios": "0.27.2",
    "clipboard": "2.0.11",
    "element-ui": "2.15.12",
    "js-cookie": "2.2.1",
    "localforage": "1.10.0",
    "lodash": "4.17.21",
    "lodash.debounce": "4.0.8",
    "marked": "0.8.2",
    "luxon": "3.1.1",
    "normalize.css": "7.0.0",
    "nprogress": "0.2.0",
    "screenfull": "3.3.2",
    "showdown": "1.8.5",
    "simplemde": "1.11.2",
    "sortablejs": "1.7.0",
    "vue": "2.5.10",
    "vue-count-to": "1.0.13",
    "vue-i18n": "7.3.2",
    "vue-multiselect": "2.0.8",
    "vue-router": "3.0.1",
    "vue-splitpane": "1.0.2",
    "vuedraggable": "2.15.0",
    "vuex": "3.0.1",
    "xlsx": "^0.11.16"
    "numeral": "2.0.6",
    "tiptap": "1.32.2",
    "tiptap-extensions": "1.35.2",
    "vue": "2.7.8",
    "vue-i18n": "8.28.2",
    "vue-router": "3.6.5",
    "vuex": "3.0.1"
  },
  "devDependencies": {
    "autoprefixer": "7.2.3",
    "babel-core": "6.26.0",
    "babel-eslint": "8.0.3",
    "@babel/core": "7.19.1",
    "@babel/plugin-syntax-dynamic-import": "7.8.3",
    "@babel/plugin-transform-runtime": "7.19.1",
    "@babel/preset-env": "7.19.1",
    "@vue/babel-helper-vue-jsx-merge-props": "1.4.0",
    "@vue/babel-preset-jsx": "1.4.0",
    "@vue/test-utils": "1.3.3",
    "autoprefixer": "10.4.16",
    "babel-eslint": "8.2.6",
    "babel-helper-vue-jsx-merge-props": "2.0.3",
    "babel-loader": "7.1.2",
    "babel-plugin-syntax-jsx": "6.18.0",
    "babel-plugin-transform-runtime": "6.23.0",
    "babel-plugin-transform-vue-jsx": "3.5.0",
    "babel-preset-env": "1.6.1",
    "babel-preset-stage-2": "6.24.1",
    "chalk": "2.3.0",
    "copy-webpack-plugin": "4.3.0",
    "cross-env": "5.1.1",
    "css-loader": "0.28.7",
    "eslint": "4.13.1",
    "eslint-friendly-formatter": "3.0.0",
    "eslint-loader": "1.9.0",
    "eslint-plugin-html": "4.0.1",
    "extract-text-webpack-plugin": "3.0.2",
    "file-loader": "1.1.5",
    "friendly-errors-webpack-plugin": "1.6.1",
    "html-webpack-plugin": "2.30.1",
    "node-notifier": "5.1.2",
    "node-sass": "^4.7.2",
    "optimize-css-assets-webpack-plugin": "3.2.0",
    "ora": "1.3.0",
    "portfinder": "1.0.13",
    "postcss-import": "11.0.0",
    "postcss-loader": "2.0.9",
    "postcss-url": "7.3.0",
    "pushstate-server": "3.0.1",
    "rimraf": "2.6.2",
    "sass-loader": "6.0.6",
    "babel-jest": "25.5.1",
    "babel-loader": "8.2.5",
    "babel-plugin-dynamic-import-node-babel-7": "2.0.7",
    "babel-plugin-transform-es2015-modules-commonjs": "6.26.2",
    "compression-webpack-plugin": "2.0.0",
    "connect": "3.7.0",
    "cross-env": "7.0.3",
    "css-loader": "1.0.1",
    "eslint": "4.19.1",
    "eslint-friendly-formatter": "4.0.1",
    "eslint-loader": "2.2.1",
    "eslint-plugin-vue": "4.7.1",
    "file-loader": "1.1.11",
    "flush-promises": "1.0.2",
    "hash-sum": "1.0.2",
    "html-webpack-plugin": "3.2.0",
    "jest": "25.5.4",
    "jest-transform-stub": "2.0.0",
    "mini-css-extract-plugin": "0.12.0",
    "sass": "1.57.1",
    "optimize-css-assets-webpack-plugin": "5.0.8",
    "ora": "3.4.0",
    "path-to-regexp": "2.4.0",
    "postcss": "8.4.20",
    "postcss-loader": "4.3.0",
    "postcss-url": "10.1.3",
    "rimraf": "2.7.1",
    "sass-loader": "7.3.1",
    "script-loader": "0.7.2",
    "semver": "5.4.1",
    "shelljs": "0.7.8",
    "svg-sprite-loader": "3.5.2",
    "uglifyjs-webpack-plugin": "1.1.3",
    "url-loader": "0.6.2",
    "vue-loader": "13.5.0",
    "vue-style-loader": "3.0.3",
    "vue-template-compiler": "2.5.10",
    "webpack": "3.10.0",
    "webpack-bundle-analyzer": "2.9.1",
    "webpack-dev-server": "2.9.7",
    "webpack-merge": "4.1.1"
    "semver": "5.7.1",
    "serve-static": "1.15.0",
    "svg-sprite-loader": "3.9.2",
    "svgo": "2.8.0",
    "uglifyjs-webpack-plugin": "1.3.0",
    "vue-jest": "4.0.1",
    "vue-loader": "15.10.1",
    "vue-style-loader": "4.1.3",
    "vue-template-compiler": "2.7.8",
    "webpack": "4.46.0",
    "webpack-cli": "3.3.12",
    "webpack-dev-server": "3.11.3",
    "webpack-merge": "4.2.2"
  },
  "engines": {
    "node": ">= 4.0.0",
    "node": ">= 6.0.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
  ],
  "jest": {
    "coverageReporters": ["cobertura", "text-summary"],
    "moduleFileExtensions": [
      "js",
      "json",
      "vue"
    ],
    "moduleDirectories": [
      "node_modules",
      "src"
    ],
    "transform": {
      "^.+\\.vue$": "vue-jest",
      "^.+\\.js$": "babel-jest",
      ".+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$'": "jest-transform-stub"
    },
    "moduleNameMapper": {
      "^.+.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub",
      "^@/(.*)$": "<rootDir>/src/$1"
    }
  }
}

renovate.json

0 → 100644
+6 −0
Original line number Diff line number Diff line
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:base"
  ]
}
+11 −6
Original line number Diff line number Diff line
<!--
SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
SPDX-License-Identifier: MIT
-->

<template>
  <div id="app">
		<router-view></router-view>
    <router-view/>
  </div>
</template>

+10 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

export async function needReboot(authHost, token) {
  return Promise.resolve({ data: false })
}

export async function restartApp(authHost, token) {
  return Promise.resolve()
}
+620 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

export async function fetchChat(id, authHost, token) {
  return Promise.resolve({ data: userChats[0] })
}

export async function fetchChatMessages(id, max_id, authHost, token) {
  return Promise.resolve({ data: chatMessages })
}

export async function deleteChat(chat_id, message_id, authHost, token) {
  return Promise.resolve({ data: userChats[0] })
}

export const userChats = [
  {
    id: '9y8e7ESoVUiKVMAoCW',
    last_message: {
      account_id: '9xUIiQfGrdPJDZe39s',
      attachment: null,
      card: null,
      chat_id: '9y8e7ESoVUiKVMAoCW',
      content: 'heyy',
      created_at: '2020-09-11T00:07:13.000Z',
      emojis: [],
      id: '9z22Q9MzWiAk7GZnNY',
      unread: false
    },
    receiver: {
      acct: 'test10',
      avatar: 'http://localhost:4000/images/avi.png',
      avatar_static: 'http://localhost:4000/images/avi.png',
      bot: false,
      created_at: '2020-07-27T00:33:02.000Z',
      display_name: 'test10',
      emojis: [],
      fields: [],
      followers_count: 2,
      following_count: 1,
      header: 'http://localhost:4000/images/banner.png',
      header_static: 'http://localhost:4000/images/banner.png',
      id: '9xUj5WTmzSlFPN6OLg',
      locked: false,
      note: '',
      pleroma: {
        accepts_chat_messages: true,
        ap_id: 'http://localhost:4000/users/test10',
        background_image: null,
        is_confirmed: true,
        favicon: null,
        hide_favorites: true,
        hide_followers: false,
        hide_followers_count: false,
        hide_follows: false,
        hide_follows_count: false,
        is_admin: false,
        is_moderator: true,
        relationship: {},
        skip_thread_containment: false,
        tags: [
          'mrf_tag:media-force-nsfw',
          'mrf_tag:media-strip',
          'mrf_tag:force-unlisted'
        ]
      },
      source: {
        fields: [],
        note: '',
        pleroma: {
          actor_type: 'Person',
          discoverable: false
        },
        sensitive: false
      },
      statuses_count: 20,
      url: 'http://localhost:4000/users/test10',
      username: 'test10'
    },
    sender: {
      acct: 'mk',
      avatar: 'http://localhost:4000/media/9051960b674309674f2f1a3a0e05916013260af13f672df32c869cb841958a44.gif',
      avatar_static: 'http://localhost:4000/media/9051960b674309674f2f1a3a0e05916013260af13f672df32c869cb841958a44.gif',
      bot: false,
      created_at: '2020-07-26T19:37:31.000Z',
      display_name: 'mk',
      emojis: [],
      fields: [
        {
          name: 'website',
          value: '<a href="http://marykatefain.com" rel="ugc">marykatefain.com</a>'
        }
      ],
      followers_count: 2,
      following_count: 1,
      header: 'http://localhost:4000/media/139889433c4085dcf219171fdcc48659fa3fb5090a748ca37513fda051226b12.gif',
      header_static: 'http://localhost:4000/media/139889433c4085dcf219171fdcc48659fa3fb5090a748ca37513fda051226b12.gif',
      id: '9xUIiQfGrdPJDZe39s',
      locked: false,
      note: 'a bio about me',
      pleroma: {
        accepts_chat_messages: true,
        ap_id: 'https://localhost/users/mk',
        background_image: null,
        is_confirmed: true,
        favicon: null,
        hide_favorites: true,
        hide_followers: false,
        hide_followers_count: false,
        hide_follows: false,
        hide_follows_count: false,
        is_admin: true,
        is_moderator: false,
        relationship: {},
        skip_thread_containment: false,
        tags: [
          'verified'
        ]
      },
      source: {
        fields: [
          {
            name: 'website',
            value: 'marykatefain.com'
          }
        ],
        note: 'a bio about me',
        pleroma: {
          actor_type: 'Person',
          discoverable: false
        },
        sensitive: false
      },
      statuses_count: 77,
      url: 'https://localhost/users/mk',
      username: 'mk'
    },
    unread: 0,
    updated_at: '2020-09-11T00:07:13.000Z'
  },
  {
    id: '9y8dwDAQzFBZIZJzEG',
    last_message: {
      account_id: '9xUIiQfGrdPJDZe39s',
      attachment: null,
      card: null,
      chat_id: '9y8dwDAQzFBZIZJzEG',
      content: 'hiiiiiiiiiiiiiiiiiii',
      created_at: '2020-08-15T06:45:13.000Z',
      emojis: [],
      id: '9y8e4EZndDmfzA0lGa',
      unread: false
    },
    receiver: {
      acct: 'user2',
      avatar: 'http://localhost:4000/media/5a702176cd5181f81532a42fafa87953db1586ca39a3c83cd3df1bc9b5cb7d07.png',
      avatar_static: 'http://localhost:4000/media/5a702176cd5181f81532a42fafa87953db1586ca39a3c83cd3df1bc9b5cb7d07.png',
      bot: false,
      created_at: '2020-08-01T19:23:57.000Z',
      display_name: 'User2',
      emojis: [],
      fields: [],
      followers_count: 0,
      following_count: 2,
      header: 'http://localhost:4000/media/1b1fc87d56e4f94b0ca8eb23100c92f67371bfa37b2898cd804341ed1a2d5c84.jpg',
      header_static: 'http://localhost:4000/media/1b1fc87d56e4f94b0ca8eb23100c92f67371bfa37b2898cd804341ed1a2d5c84.jpg',
      id: '9xfhRuCIyydruc0Sh6',
      locked: false,
      note: 'Just me!',
      pleroma: {
        accepts_chat_messages: true,
        ap_id: 'http://localhost:4000/users/user2',
        background_image: null,
        is_confirmed: false,
        favicon: null,
        hide_favorites: true,
        hide_followers: false,
        hide_followers_count: false,
        hide_follows: false,
        hide_follows_count: false,
        is_admin: false,
        is_moderator: false,
        relationship: {},
        skip_thread_containment: false,
        tags: [
          'mrf_tag:force-unlisted',
          'mrf_tag:media-strip'
        ]
      },
      source: {
        fields: [],
        note: 'Just me!',
        pleroma: {
          actor_type: 'Person',
          discoverable: false
        },
        sensitive: false
      },
      statuses_count: 69,
      url: 'http://localhost:4000/users/user2',
      username: 'user2'
    },
    sender: {
      acct: 'mk',
      avatar: 'http://localhost:4000/media/9051960b674309674f2f1a3a0e05916013260af13f672df32c869cb841958a44.gif',
      avatar_static: 'http://localhost:4000/media/9051960b674309674f2f1a3a0e05916013260af13f672df32c869cb841958a44.gif',
      bot: false,
      created_at: '2020-07-26T19:37:31.000Z',
      display_name: 'mk',
      emojis: [],
      fields: [
        {
          name: 'website',
          value: '<a href="http://marykatefain.com" rel="ugc">marykatefain.com</a>'
        }
      ],
      followers_count: 2,
      following_count: 1,
      header: 'http://localhost:4000/media/139889433c4085dcf219171fdcc48659fa3fb5090a748ca37513fda051226b12.gif',
      header_static: 'http://localhost:4000/media/139889433c4085dcf219171fdcc48659fa3fb5090a748ca37513fda051226b12.gif',
      id: '9xUIiQfGrdPJDZe39s',
      locked: false,
      note: 'a bio about me',
      pleroma: {
        accepts_chat_messages: true,
        ap_id: 'https://localhost/users/mk',
        background_image: null,
        is_confirmed: true,
        favicon: null,
        hide_favorites: true,
        hide_followers: false,
        hide_followers_count: false,
        hide_follows: false,
        hide_follows_count: false,
        is_admin: true,
        is_moderator: false,
        relationship: {},
        skip_thread_containment: false,
        tags: [
          'verified'
        ]
      },
      source: {
        fields: [
          {
            name: 'website',
            value: 'marykatefain.com'
          }
        ],
        note: 'a bio about me',
        pleroma: {
          actor_type: 'Person',
          discoverable: false
        },
        sensitive: false
      },
      statuses_count: 77,
      url: 'https://localhost/users/mk',
      username: 'mk'
    },
    unread: 0,
    updated_at: '2020-08-15T06:45:13.000Z'
  },
  {
    id: '9y8dubemxq32fkkoeu',
    last_message: null,
    receiver: {
      acct: 'mk',
      avatar: 'http://localhost:4000/media/9051960b674309674f2f1a3a0e05916013260af13f672df32c869cb841958a44.gif',
      avatar_static: 'http://localhost:4000/media/9051960b674309674f2f1a3a0e05916013260af13f672df32c869cb841958a44.gif',
      bot: false,
      created_at: '2020-07-26T19:37:31.000Z',
      display_name: 'mk',
      emojis: [],
      fields: [
        {
          name: 'website',
          value: '<a href="http://marykatefain.com" rel="ugc">marykatefain.com</a>'
        }
      ],
      followers_count: 2,
      following_count: 1,
      header: 'http://localhost:4000/media/139889433c4085dcf219171fdcc48659fa3fb5090a748ca37513fda051226b12.gif',
      header_static: 'http://localhost:4000/media/139889433c4085dcf219171fdcc48659fa3fb5090a748ca37513fda051226b12.gif',
      id: '9xUIiQfGrdPJDZe39s',
      locked: false,
      note: 'a bio about me',
      pleroma: {
        accepts_chat_messages: true,
        ap_id: 'https://localhost/users/mk',
        background_image: null,
        is_confirmed: true,
        favicon: null,
        hide_favorites: true,
        hide_followers: false,
        hide_followers_count: false,
        hide_follows: false,
        hide_follows_count: false,
        is_admin: true,
        is_moderator: false,
        relationship: {},
        skip_thread_containment: false,
        tags: [
          'verified'
        ]
      },
      source: {
        fields: [
          {
            name: 'website',
            value: 'marykatefain.com'
          }
        ],
        note: 'a bio about me',
        pleroma: {
          actor_type: 'Person',
          discoverable: false
        },
        sensitive: false
      },
      statuses_count: 77,
      url: 'https://localhost/users/mk',
      username: 'mk'
    },
    sender: {
      acct: 'mk',
      avatar: 'http://localhost:4000/media/9051960b674309674f2f1a3a0e05916013260af13f672df32c869cb841958a44.gif',
      avatar_static: 'http://localhost:4000/media/9051960b674309674f2f1a3a0e05916013260af13f672df32c869cb841958a44.gif',
      bot: false,
      created_at: '2020-07-26T19:37:31.000Z',
      display_name: 'mk',
      emojis: [],
      fields: [
        {
          name: 'website',
          value: '<a href="http://marykatefain.com" rel="ugc">marykatefain.com</a>'
        }
      ],
      followers_count: 2,
      following_count: 1,
      header: 'http://localhost:4000/media/139889433c4085dcf219171fdcc48659fa3fb5090a748ca37513fda051226b12.gif',
      header_static: 'http://localhost:4000/media/139889433c4085dcf219171fdcc48659fa3fb5090a748ca37513fda051226b12.gif',
      id: '9xUIiQfGrdPJDZe39s',
      locked: false,
      note: 'a bio about me',
      pleroma: {
        accepts_chat_messages: true,
        ap_id: 'https://localhost/users/mk',
        background_image: null,
        is_confirmed: true,
        favicon: null,
        hide_favorites: true,
        hide_followers: false,
        hide_followers_count: false,
        hide_follows: false,
        hide_follows_count: false,
        is_admin: true,
        is_moderator: false,
        relationship: {},
        skip_thread_containment: false,
        tags: [
          'verified'
        ]
      },
      source: {
        fields: [
          {
            name: 'website',
            value: 'marykatefain.com'
          }
        ],
        note: 'a bio about me',
        pleroma: {
          actor_type: 'Person',
          discoverable: false
        },
        sensitive: false
      },
      statuses_count: 77,
      url: 'https://localhost/users/mk',
      username: 'mk'
    },
    unread: 0,
    updated_at: '2020-08-15T06:43:29.000Z'
  }
]

export const chatMessages = [
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'heyy',
    created_at: '2020-09-11T00:07:13.000Z',
    emojis: [],
    id: '9z22Q9MzWiAk7GZnNY',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: {
      description: null,
      id: '-1990764178',
      pleroma: {
        mime_type: 'image/png'
      },
      preview_url: 'http://localhost:4000/media/b087b890b39aa8301f736e8b45c02213183986c8a994c2c99e921ae85afa17e4.png',
      remote_url: 'http://localhost:4000/media/b087b890b39aa8301f736e8b45c02213183986c8a994c2c99e921ae85afa17e4.png',
      text_url: 'http://localhost:4000/media/b087b890b39aa8301f736e8b45c02213183986c8a994c2c99e921ae85afa17e4.png',
      type: 'image',
      url: 'http://localhost:4000/media/b087b890b39aa8301f736e8b45c02213183986c8a994c2c99e921ae85afa17e4.png'
    },
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: null,
    created_at: '2020-09-10T20:35:33.000Z',
    emojis: [],
    id: '9z1jWuQNaq8Ef6fdOS',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'probably',
    created_at: '2020-09-10T16:57:33.000Z',
    emojis: [],
    id: '9z1Q4eXb9kBYA8rNT6',
    unread: false
  },
  {
    account_id: '9xUj5WTmzSlFPN6OLg',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'That has got to be 20 by now',
    created_at: '2020-09-10T16:57:29.000Z',
    emojis: [],
    id: '9z1Q4LQAF9wuraEfk8',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'I miss bars :(',
    created_at: '2020-09-10T16:57:22.000Z',
    emojis: [],
    id: '9z1Q3gmlKEfEpnUdm4',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'Yeah tying to!',
    created_at: '2020-09-10T16:57:15.000Z',
    emojis: [],
    id: '9z1Q307VxCiKVhs6eO',
    unread: false
  },
  {
    account_id: '9xUj5WTmzSlFPN6OLg',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'staying safe with covid and such?',
    created_at: '2020-09-10T16:57:10.000Z',
    emojis: [],
    id: '9z1Q2Z56U3k6ePXIe1',
    unread: false
  },
  {
    account_id: '9xUj5WTmzSlFPN6OLg',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'how have you been?',
    created_at: '2020-09-10T16:57:06.000Z',
    emojis: [],
    id: '9z1Q29XvQHLfSGowxU',
    unread: false
  },
  {
    account_id: '9xUj5WTmzSlFPN6OLg',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'so what are you doing?',
    created_at: '2020-09-10T16:57:02.000Z',
    emojis: [],
    id: '9z1Q1lPb9aQYbUjxeD',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'crazy',
    created_at: '2020-09-10T16:56:55.000Z',
    emojis: [],
    id: '9z1Q19zQHwVMXbD2DA',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'omg yeah same',
    created_at: '2020-09-10T16:56:54.000Z',
    emojis: [],
    id: '9z1Q12zWJBQIpsCVtI',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'hahahaha',
    created_at: '2020-09-10T16:56:51.000Z',
    emojis: [],
    id: '9z1Q0pyKiHkWSQXsjg',
    unread: false
  },
  {
    account_id: '9xUj5WTmzSlFPN6OLg',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'I think this is 13',
    created_at: '2020-09-10T16:56:45.000Z',
    emojis: [],
    id: '9z1Q0Ft6sEBGXnpCb3',
    unread: false
  },
  {
    account_id: '9xUj5WTmzSlFPN6OLg',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'We need to keep typing until we hit 20',
    created_at: '2020-09-10T16:56:42.000Z',
    emojis: [],
    id: '9z1PzywjrTyy08OMOO',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'That&#39;s nice',
    created_at: '2020-09-10T16:56:03.000Z',
    emojis: [],
    id: '9z1PwOkJzs8orKsJDU',
    unread: false
  },
  {
    account_id: '9xUj5WTmzSlFPN6OLg',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'I&#39;ve been good! Keeping busy',
    created_at: '2020-09-10T16:56:00.000Z',
    emojis: [],
    id: '9z1Pw7qmoaDASSljQv',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: '*been',
    created_at: '2020-09-10T16:55:55.000Z',
    emojis: [],
    id: '9z1PvcWVHwZFIa2b0y',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'How have you ben?',
    created_at: '2020-09-10T16:55:52.000Z',
    emojis: [],
    id: '9z1PvK4BuTE03YejNw',
    unread: false
  },
  {
    account_id: '9xUIiQfGrdPJDZe39s',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'Oh it&#39;s okay! No worries!',
    created_at: '2020-09-10T16:55:44.000Z',
    emojis: [],
    id: '9z1Puc4hTDUJcOYW4O',
    unread: false
  },
  {
    account_id: '9xUj5WTmzSlFPN6OLg',
    attachment: null,
    card: null,
    chat_id: '9y8e7ESoVUiKVMAoCW',
    content: 'didn&#39;t mean to ignore you',
    created_at: '2020-09-10T16:55:32.000Z',
    emojis: [],
    id: '9z1PtWGNamQTIvUspk',
    unread: false
  }
]
+54 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

export async function addNewEmojiFile(packName, file, shortcode, filename, host, token) {
  return Promise.resolve()
}

export function addressOfEmojiInPack(host, packName, name) {
  return Promise.resolve()
}

export async function createPack(host, token, packName) {
  return Promise.resolve()
}

export async function deleteEmojiFile(packName, shortcode, host, token) {
  return Promise.resolve()
}

export async function deletePack(host, token, packName) {
  return Promise.resolve()
}

export async function downloadFrom(instanceAddress, packName, as, host, token) {
  return Promise.resolve()
}

export async function fetchPack(packName, page, pageSize, host, token) {
  return Promise.resolve()
}

export async function importFromFS(host, token) {
  return Promise.resolve()
}

export async function listPacks(page, pageSize, host, token) {
  return Promise.resolve()
}

export async function listRemotePacks(instance, page, pageSize, host, token) {
  return Promise.resolve()
}

export async function reloadEmoji(host, token) {
  return Promise.resolve()
}

export async function savePackMetadata(host, token, packName, metadata) {
  return Promise.resolve()
}

export async function updateEmojiFile(packName, shortcode, newShortcode, newFilename, force, host, token) {
  return Promise.resolve()
}
+38 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

let inviteTokens = [
  { expires_at: '01-01-2020', id: 1, invite_type: 'one_time', max_use: 3, token: 'DCN8XyTsVEuz9_KuxPlkbH1RgMsMHepwmZE2gyX07Jw=', used: false, uses: 1 },
  { expires_at: '02-02-2020', id: 2, invite_type: 'one_time', max_use: 1, token: 'KnJTHNedj2Mh14ckx06t-VfOuFL8oNA0nVAK1HLeLf4=', used: true, uses: 1 },
  { expires_at: '03-03-2020', id: 3, invite_type: 'one_time', max_use: 5, token: 'P6F5ayP-rAMbxtmtGJwFJcd7Yk_D2g6UZRfh8EskRUc=', used: false, uses: 0 }
]

export async function generateInviteToken(max_use, expires_at, authHost, token) {
  const newToken = {
    expires_at: '2019-04-10',
    id: 4,
    invite_type: 'one_time',
    max_use: 3,
    token: 'JYl0SjXW8t-t-pLSZBnZLf6PwjCW-qy6Dq70jfUOuqk=',
    used: false,
    uses: 0
  }
  inviteTokens = [...inviteTokens, newToken]
  return Promise.resolve({ data: newToken })
}

export async function inviteViaEmail(email, name, authHost, token) {
  return Promise.resolve()
}

export async function listInviteTokens(authHost, token) {
  return Promise.resolve({ data: {
    invites: inviteTokens
  }})
}

export async function revokeToken(tokenToRevoke, authHost, token) {
  inviteTokens.splice(3, 1, { ...inviteTokens[3], used: true })
  return Promise.resolve()
}
+63 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

const users = [
  { username: 'bob', password: '123456', authHost: 'pleroma' }
]

export async function loginByUsername(username, password, authHost) {
  const user = users.find(user => user.username === username)
  const verifyPassword = user.password === password
  const verifyHost = user.authHost === authHost
  const data = {
    'token_type': 'Bearer',
    'scope': 'read write follow push admin',
    'refresh_token': 'foo123',
    'me': 'bob',
    'expires_in': 600,
    'access_token': 'bar123'
  }

  return verifyPassword && verifyHost
    ? Promise.resolve({ data })
    : Promise.reject({ message: 'Invalid credentials' })
}

export function getUserInfo(token, authHost) {
  const userInfo = {
    'name_html': 'bob',
    'background_image': null,
    'friends_count': 0,
    'description_html': '',
    'followers_count': 0,
    'locked': false,
    'follows_you': true,
    'statusnet_blocking': false,
    'statusnet_profile_url': '',
    'following': true,
    'id': '10',
    'is_local': true,
    'profile_image_url': '',
    'role': 'admin',
    'profile_image_url_profile_size': '',
    'rights': { 'admin': true, 'delete_others_notice': true },
    'token': 'foo123456',
    'no_rich_text': false,
    'statuses_count': 0,
    'cover_photo': '',
    'hide_follows': false,
    'pleroma': { 'is_confirmed': true, 'is_active': true, 'tags': ['force_nsfw'], 'is_admin': true },
    'profile_image_url_original': '',
    'created_at': 'Fri Mar 01 15:15:19 +0000 2019',
    'fields': [],
    'name': 'bob',
    'description': '',
    'favourites_count': 0,
    'default_scope': 'public',
    'profile_image_url_https': '',
    'hide_followers': false,
    'show_role': true,
    'screen_name': 'bob' }

  return Promise.resolve({ data: userInfo })
}
+23 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

const urls = [
  'http://example.com/media/a688346.jpg',
  'http://example.com/media/fb1f4d.jpg'
]

export async function listBannedUrls(page, pageSize, authHost, token) {
  return Promise.resolve({ data: { page_size: 1, count: 2, urls }})
}

export async function purgeUrls(urls, ban, authHost, token) {
  return Promise.resolve()
}

export async function removeBannedUrls(urls, authHost, token) {
  return Promise.resolve()
}

export async function searchBannedUrls(query, page, pageSize, authHost, token) {
  return Promise.resolve()
}
+6 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

export function uploadMedia({ formData, authHost }) {
  return Promise.resolve()
}
+14 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

export async function fetchLog(authHost, token, params, page = 1) {
  return Promise.resolve()
}

export async function fetchAdmins(authHost, token) {
  return Promise.resolve()
}

export async function fetchModerators(authHost, token) {
  return Promise.resolve()
}
+12 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

export async function getNodeInfo(authHost) {
  const data = {
    metadata: {
      mailerEnabled: true
    }
  }

  return Promise.resolve({ data })
}
+7 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

export async function fetchPeers(authHost, token) {
  const data = ['lain.com', 'heaven.com']
  return Promise.resolve({ data })
}
+14 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

export async function fetchRelays(authHost, token) {
  return Promise.resolve()
}

export async function addRelay(relay_url, authHost, token) {
  return Promise.resolve()
}

export async function deleteRelay(relay_url, authHost, token) {
  return Promise.resolve()
}
+42 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

const reports = [
  { created_at: '2019-05-21T21:35:33.000Z', account: { nickname: 'benjamin', tags: [] }, actor: {}, state: 'open', id: '2', content: 'This is a report', statuses: [] },
  { created_at: '2019-05-20T22:45:33.000Z', account: { nickname: 'alice', tags: [] }, actor: {}, state: 'resolved', id: '1', content: 'Please block this user', statuses: [] },
  { created_at: '2019-05-18T13:01:33.000Z', account: { nickname: 'nick_keys', tags: [] }, actor: {}, state: 'closed', id: '3', content: '', statuses: [] },
  { created_at: '2019-05-21T21:35:33.000Z', account: { nickname: 'benjamin', tags: [] }, actor: {}, state: 'open', id: '5', content: 'This is a report', statuses: [] },
  { created_at: '2019-05-20T22:45:33.000Z', account: { nickname: 'alice', tags: [] }, actor: {}, state: 'resolved', id: '7', content: 'Please block this user', statuses: [
    { account: { nickname: 'alice', avatar: '' }, visibility: 'public', sensitive: false, id: '11', content: 'Hey!', url: '', created_at: '2019-05-10T21:35:33.000Z' },
    { account: { nickname: 'alice', avatar: '' }, visibility: 'unlisted', sensitive: true, id: '10', content: 'Bye!', url: '', created_at: '2019-05-10T21:00:33.000Z' }
  ] },
  { created_at: '2019-05-18T13:01:33.000Z', account: { nickname: 'nick_keys', tags: [] }, actor: {}, state: 'closed', id: '6', content: '', statuses: [] },
  { created_at: '2019-05-18T13:01:33.000Z', account: { nickname: 'nick_keys', tags: [] }, actor: {}, state: 'closed', id: '4', content: '', statuses: [] }
]

export async function fetchReports(filter, page, pageSize, authHost, token) {
  return filter.length > 0
    ? Promise.resolve({ data: { reports: reports.filter(report => report.state === filter) }})
    : Promise.resolve({ data: { reports }})
}

export async function changeState(reportsData, authHost, token) {
  return Promise.resolve({ data: '' })
}

export async function createNote(content, reportID, authHost, token) {
  return Promise.resolve()
}

export async function deleteNote(noteID, reportID, authHost, token) {
  return Promise.resolve()
}

// export async function changeStatusScope(id, sensitive, visibility, authHost, token) {
//   const status = reports[4].statuses[0]
//   return Promise.resolve({ data: { ...status, sensitive, visibility }})
// }

// export async function deleteStatus(statusId, authHost, token) {
//   return Promise.resolve()
// }
+62 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

const configsWithTagPolicy = {
  configs: [{
    group: ':pleroma',
    key: ':mrf',
    value: [
      { tuple: [':policies', ['Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy', 'Pleroma.Web.ActivityPub.MRF.TagPolicy']] },
      { tuple: [':transparency', true] },
      { tuple: [':transparency_exclusions', []] }
    ] },
  {
    group: ':pleroma',
    key: ':media_proxy',
    value: [
      { tuple: [':enabled', true] },
      { tuple: [':invalidation', [
        { tuple: [':provider', 'Pleroma.Web.MediaProxy.Invalidation.Script'] },
        { tuple: [':enabled', true] }
      ]] }
    ] }],
  need_reboot: false
}

const configAfterUpdate = {
  configs: [{
    db: [':policies'],
    group: ':pleroma',
    key: ':mrf',
    value: [{ tuple: [':policies', ['Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy', 'Pleroma.Web.ActivityPub.MRF.TagPolicy']] }]
  }],
  need_reboot: false
}

export async function fetchSettings(authHost, token) {
  return Promise.resolve({ data: configsWithTagPolicy })
}

export async function getInstanceDocument(name, authHost, token) {
  return Promise.resolve({ data: '<h1>Instance panel</h1>' })
}

export async function updateSettings(configs, authHost, token) {
  return Promise.resolve({ data: configAfterUpdate })
}

export async function deleteInstanceDocument(name, authHost, token) {
  return Promise.resolve()
}

export async function fetchDescription(authHost, token) {
  return Promise.resolve()
}

export async function updateInstanceDocument(name, formData, authHost, token) {
  return Promise.resolve()
}

export async function removeSettings(configs, authHost, token) {
  return Promise.resolve()
}
+100 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

export async function changeStatusScope(id, sensitive, visibility, authHost, token) {
  return Promise.resolve()
}

export async function deleteStatus(id, authHost, token) {
  return Promise.resolve()
}

export async function fetchStatus(id, authHost, token) {
  const data = {
    account: {
      id: '9n1bySks25olxWrku0',
      avatar: 'http://localhost:4000/images/avi.png',
      nickname: 'dolin',
      tags: ['mrf_tag:media-strip', 'mrf_tag:sandbox', 'mrf_tag:disable-any-subscription', 'mrf_tag:media-force-nsfw'],
      url: 'http://localhost:4000/users/dolin'
    },
    content: 'pizza makes everything better',
    created_at: '2020-05-22T17:34:34.000Z',
    id: '9vJOO3iFPyjNaEhJ5s',
    media_attachments: [],
    poll: null,
    sensitive: false,
    spoiler_text: '',
    visibility: 'public',
    url: 'http://localhost:4000/notice/9vJOO3iFPyjNaEhJ5s'
  }

  return Promise.resolve({ data })
}

export async function fetchStatusesByInstance({ instance, authHost, token, pageSize, page }) {
  let data
  if (pageSize === 1) {
    data = page === 1 || page === 2
      ? [{
        'account': {
          'avatar': 'http://localhost:4000/images/avi.png',
          'nickname': 'sky',
          'url': 'http://localhost:4000/users/sky'
        },
        'content': 'A nice young couple contacted us from Brazil to decorate their newly acquired apartment.',
        'created_at': '2020-01-31T18:20:01.000Z',
        'id': '9rZIr0Jzao5Gjgfmro',
        'sensitive': false,
        'url': 'http://localhost:4000/objects/7af9abbd-fb6c-4318-aeb7-6636c138ac98',
        'visibility': 'unlisted'
      }]
      : []
  } else {
    data = [
      {
        'account': {
          'avatar': 'http://localhost:4000/images/avi.png',
          'nickname': 'sky',
          'url': 'http://localhost:4000/users/sky'
        },
        'content': 'i love parks&rec',
        'created_at': '2020-04-12T18:20:01.000Z',
        'id': 'o5Gjgfmro9rZIr0Jza',
        'sensitive': false,
        'url': 'http://localhost:4000/objects/7af9abbd-aeb7-6636c138ac98-fb6c-4318',
        'visibility': 'unlisted'
      },
      {
        'account': {
          'avatar': 'http://localhost:4000/images/avi.png',
          'nickname': 'sky',
          'url': 'http://localhost:4000/users/sky'
        },
        'content': 'the happiest man ever',
        'created_at': '2019-11-23T12:56:18.000Z',
        'id': '9pFoVfWMU3A96Rzq3k',
        'sensitive': false,
        'url': 'http://localhost:4000/objects/449c90fe-c457-4c64-baf2-fe6d0a59ca25',
        'visibility': 'unlisted'
      }]
  }
  return Promise.resolve({ data })
}

export async function fetchStatusesCount(instance, authHost, token) {
  const data = instance === 'heaven.com'
    ? {
      'status_visibility':
      { 'direct': 1, 'private': 2, 'public': 3, 'unlisted': 0 }
    }
    : {
      'status_visibility':
      { 'direct': 4, 'private': 10, 'public': 4, 'unlisted': 10 }
    }
  return Promise.resolve({ data })
}

export async function fetchStatuses({ godmode, localOnly, authHost, token, pageSize, page }) {
  return Promise.resolve()
}
+134 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import userChats from './chat'

export let users = [
  { is_confirmed: true, is_approved: true, is_active: true, id: '2', nickname: 'allis', local: true, external: false, roles: { admin: true, moderator: false }, tags: [], actor_type: 'Person' },
  { is_confirmed: true, is_approved: true, is_active: true, id: '10', nickname: 'bob', local: true, external: false, roles: { admin: false, moderator: false }, tags: ['mrf_tag:sandbox'], actor_type: 'Person' },
  { is_confirmed: true, is_approved: false, is_active: true, id: '567', nickname: 'ded', local: false, external: true, roles: { admin: false, moderator: false }, tags: [], actor_type: 'Person' },
  { is_confirmed: true, is_approved: true, is_active: false, id: 'abc', nickname: 'john', local: true, external: false, roles: { admin: false, moderator: false }, tags: ['mrf_tag:media-strip'], actor_type: 'Person' },
  { is_confirmed: true, is_approved: false, is_active: true, id: '100', nickname: 'sally', local: true, external: false, roles: { admin: false, moderator: false }, tags: [], actor_type: 'Service' },
  { is_confirmed: true, is_approved: false, is_active: true, id: '123', nickname: 'bot', local: true, external: false, roles: { admin: false, moderator: false }, tags: [], actor_type: 'Application' }
]

const userProfile = { avatar: 'avatar.jpg', nickname: 'allis', id: '2', tags: [], roles: { admin: true, moderator: false }, local: true, external: false }

const userStatuses = [
  { account: { id: '9n1bySks25olxWrku0', nickname: 'dolin' }, content: 'pizza makes everything better', id: '9vJOO3iFPyjNaEhJ5s', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' },
  { account: { id: '9n1bySks25olxWrku0', nickname: 'dolin' }, content: 'pizza time', id: '9vJPD5XKOdzQ0bvGLY', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' },
  { account: { id: '9n1bySks25olxWrku0', nickname: 'dolin' }, content: 'what is yout favorite pizza?', id: '9jop82OBXeFPYulVjM', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' }
]

export async function fetchUser(id, authHost, token) {
  return Promise.resolve({ data: userProfile })
}

export async function fetchUserCredentials(nickname, authHost, token) {
  return Promise.resolve({ data: {}})
}

export async function fetchUsers(filters, actorTypeFilters, authHost, token, page = 1) {
  return Promise.resolve({ data: {
    users,
    count: users.length,
    page_size: 50
  }})
}

export async function fetchUserStatuses(id, authHost, godmode, token) {
  return Promise.resolve({ data: userStatuses })
}

export async function fetchUserChats(id, authHost, godmode, token) {
  return Promise.resolve({ data: userChats })
}

export async function getPasswordResetToken(nickname, authHost, token) {
  return Promise.resolve({ data: { token: 'g05lxnBJQnL', link: 'http://url/api/pleroma/password_reset/g05lxnBJQnL' }})
}

export async function searchUsers(query, filters, actorTypeFilters, authHost, token, page = 1) {
  const response = users.filter(user => user.nickname === query)
  return Promise.resolve({ data: {
    users: response,
    count: response.length,
    page_size: 50
  }})
}

export async function activateUsers(nicknames, authHost, token) {
  const response = nicknames.map(nickname => {
    const currentUser = users.find(user => user.nickname === nickname)
    return { ...currentUser, is_active: true }
  })
  return Promise.resolve({ data: response })
}

export async function addRight(nicknames, right, authHost, token) {
  return Promise.resolve({ data:
    { [`is_${right}`]: true }
  })
}

export async function deactivateUsers(nicknames, authHost, token) {
  const response = nicknames.map(nickname => {
    const currentUser = users.find(user => user.nickname === nickname)
    return { ...currentUser, is_active: false }
  })
  return Promise.resolve({ data: response })
}

export async function approveUserAccount(nicknames, authHost, token) {
  const response = nicknames.map(nickname => {
    const currentUser = users.find(user => user.nickname === nickname)
    return { ...currentUser, is_approved: true }
  })
  return Promise.resolve({ data: response })
}

export async function deleteRight(nickname, right, authHost, token) {
  return Promise.resolve({ data:
    { [`is_${right}`]: false }
  })
}

export async function deleteUsers(nicknames, authHost, token) {
  return Promise.resolve({ data:
    nicknames
  })
}

export async function tagUser(nickname, tag, authHost, token) {
  return Promise.resolve()
}

export async function untagUser(nickname, tag, authHost, token) {
  return Promise.resolve()
}

export async function createNewAccount(nickname, email, password, authHost, token) {
  const newUser = { active: true, is_active: true, id: '15', nickname, local: true, external: false, roles: { admin: false, moderator: false }, tags: [] }
  users = [...users, newUser]
  return Promise.resolve()
}

export async function updateUserCredentials(nickname, credentials, authHost, token) {
  return Promise.resolve()
}

export async function disableMfa(nickname, authHost, token) {
  return Promise.resolve()
}

export async function forcePasswordReset(nicknames, authHost, token) {
  return Promise.resolve()
}

export async function confirmUserEmail(nicknames, authHost, token) {
  return Promise.resolve()
}

export async function resendConfirmationEmail(nicknames, authHost, token) {
  return Promise.resolve()
}

src/api/app.js

0 → 100644
+26 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function needReboot(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/need_reboot`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function restartApp(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/restart`,
    method: 'get',
    headers: authHeaders(token)
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

src/api/article.js

deleted100644 → 0
+0 −40
Original line number Diff line number Diff line
import request from '@/utils/request'

export function fetchList(query) {
  return request({
    url: '/article/list',
    method: 'get',
    params: query
  })
}

export function fetchArticle() {
  return request({
    url: '/article/detail',
    method: 'get'
  })
}

export function fetchPv(pv) {
  return request({
    url: '/article/pv',
    method: 'get',
    params: { pv }
  })
}

export function createArticle(data) {
  return request({
    url: '/article/create',
    method: 'post',
    data
  })
}

export function updateArticle(data) {
  return request({
    url: '/article/update',
    method: 'post',
    data
  })
}

src/api/chat.js

0 → 100644
+38 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function deleteChatMessage(chat_id, message_id, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/chats/${chat_id}/messages/${message_id}`,
    method: 'delete',
    headers: authHeaders(token)
  })
}

export async function fetchChat(id, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/chats/${id}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchChatMessages(id, maxId, authHost, token) {
  const url = maxId
    ? `/api/pleroma/admin/chats/${id}/messages?max_id=${maxId}`
    : `/api/pleroma/admin/chats/${id}/messages`
  return await request({
    baseURL: baseName(authHost),
    url,
    method: 'get',
    headers: authHeaders(token)
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

src/api/emojiPacks.js

0 → 100644
+139 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function addNewEmojiFile(packName, file, shortcode, filename, host, token) {
  const data = new FormData()
  if (filename.trim() !== '') {
    data.set('filename', filename)
  }
  if (shortcode.trim() !== '') {
    data.set('shortcode', shortcode)
  }
  data.set('file', file)

  return await request({
    baseURL: baseName(host),
    url: `/api/pleroma/emoji/packs/files?name=${packName}`,
    method: 'post',
    headers: authHeaders(token),
    data
  })
}

export function addressOfEmojiInPack(host, packName, name) {
  return `${baseName(host)}/emoji/${encodeUri(packName)}/${name}`
}

export async function createPack(host, token, packName) {
  return await request({
    baseURL: baseName(host),
    url: `/api/pleroma/emoji/pack?name=${packName}`,
    method: 'post',
    headers: authHeaders(token)
  })
}

export async function deleteEmojiFile(packName, shortcode, host, token) {
  return await request({
    baseURL: baseName(host),
    url: `/api/pleroma/emoji/packs/files?name=${packName}&shortcode=${shortcode}`,
    method: 'delete',
    headers: authHeaders(token)
  })
}

export async function deletePack(host, token, packName) {
  return await request({
    baseURL: baseName(host),
    url: `/api/pleroma/emoji/pack?name=${packName}`,
    method: 'delete',
    headers: authHeaders(token)
  })
}

export async function downloadFrom(instanceAddress, packName, as, host, token) {
  return await request({
    baseURL: baseName(host),
    url: '/api/pleroma/emoji/packs/download',
    method: 'post',
    headers: authHeaders(token),
    data: as.trim() === ''
      ? { url: baseName(instanceAddress), name: packName }
      : { url: baseName(instanceAddress), name: packName, as },
    timeout: 0
  })
}

export async function fetchPack(packName, page, pageSize, host, token) {
  return await request({
    baseURL: baseName(host),
    url: `/api/pleroma/emoji/pack?name=${packName}&page=${page}&page_size=${pageSize}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function importFromFS(host, token) {
  return await request({
    baseURL: baseName(host),
    url: '/api/pleroma/emoji/packs/import',
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function listPacks(page, pageSize, host, token) {
  return await request({
    baseURL: baseName(host),
    url: `/api/pleroma/emoji/packs?page=${page}&page_size=${pageSize}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function listRemotePacks(instance, page, pageSize, host, token) {
  return await request({
    baseURL: baseName(host),
    url: `/api/pleroma/emoji/packs/remote?url=${baseName(instance)}&page=${page}&page_size=${pageSize}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function reloadEmoji(host, token) {
  return await request({
    baseURL: baseName(host),
    url: '/api/pleroma/admin/reload_emoji',
    method: 'post',
    headers: authHeaders(token)
  })
}

export async function savePackMetadata(host, token, packName, metadata) {
  return await request({
    baseURL: baseName(host),
    url: `/api/pleroma/emoji/pack?name=${packName}`,
    method: 'patch',
    headers: authHeaders(token),
    data: { metadata },
    timeout: 0 // This might take a long time
  })
}

export async function updateEmojiFile(packName, shortcode, newShortcode, newFilename, force, host, token) {
  return await request({
    baseURL: baseName(host),
    url: `/api/pleroma/emoji/packs/files?name=${packName}`,
    method: 'patch',
    headers: authHeaders(token),
    data: { shortcode, new_shortcode: newShortcode, new_filename: newFilename, force }
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

const encodeUri = (name) => encodeURIComponent(name)

src/api/invites.js

0 → 100644
+48 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function generateInviteToken(max_use, expires_at, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/invite_token`,
    method: 'post',
    headers: authHeaders(token),
    data: expires_at && expires_at.length > 0 ? { max_use, expires_at } : { max_use }
  })
}

export async function inviteViaEmail(email, name, authHost, token) {
  const data = name.length > 0 ? { email, name } : { email }
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/users/email_invite',
    method: 'post',
    headers: authHeaders(token),
    data
  })
}

export async function listInviteTokens(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/invites`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function revokeToken(tokenToRevoke, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/revoke_invite`,
    method: 'post',
    headers: authHeaders(token),
    data: { token: tokenToRevoke }
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}
+35 −15
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2017-2019 PanJiaChen <https://github.com/PanJiaChen/vue-element-admin>
// SPDX-License-Identifier: MIT
//
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { baseName } from './utils'

export function loginByUsername(username, password) {
  const data = {
    username,
    password
  }
  return request({
    url: '/login/login',
export async function loginByUsername(username, password, authHost) {
  const appsRequest = await request({
    baseURL: baseName(authHost),
    url: '/api/v1/apps',
    method: 'post',
    data
  })
    data: {
      client_name: `AdminFE_${Math.random()}`,
      redirect_uris: `${window.location.origin}/oauth-callback`,
      scopes: 'read write follow push admin'
    }
  })

  const app = appsRequest.data

export function logout() {
  return request({
    url: '/login/logout',
    method: 'post'
    baseURL: baseName(authHost),
    url: '/oauth/token',
    method: 'post',
    data: {
      client_id: app.client_id,
      client_secret: app.client_secret,
      grant_type: 'password',
      username: username,
      password: password
    }
  })
}

export function getUserInfo(token) {
export function getUserInfo(token, authHost) {
  return request({
    url: '/user/info',
    baseURL: baseName(authHost),
    url: '/api/v1/accounts/verify_credentials',
    method: 'get',
    params: { token }
    headers: token ? { 'Authorization': `Bearer ${token}` } : {}
  })
}

const oauth = { loginByUsername, getUserInfo }

export default oauth
+46 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function listBannedUrls(page, pageSize, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/media_proxy_caches?page=${page}&page_size=${pageSize}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function purgeUrls(urls, ban, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/media_proxy_caches/purge`,
    method: 'post',
    headers: authHeaders(token),
    data: { urls, ban }
  })
}

export async function removeBannedUrls(urls, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/media_proxy_caches/delete`,
    method: 'post',
    headers: authHeaders(token),
    data: { urls }
  })
}

export async function searchBannedUrls(query, page, pageSize, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/media_proxy_caches?query=${query}&page=${page}&page_size=${pageSize}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

src/api/mediaUpload.js

0 → 100644
+22 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import { getToken } from '@/utils/auth'
import { baseName } from './utils'

const UPLOAD_URL = '/api/v1/media'

export function uploadMedia({ formData, authHost }) {
  const url = baseName(authHost) + UPLOAD_URL

  return fetch(url, {
    body: formData,
    method: 'POST',
    headers: authHeaders()
  })
    .then((data) => data.json())
}

const authHeaders = () => {
  return { 'Authorization': `Bearer ${getToken()}` }
}
+41 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import _ from 'lodash'

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function fetchLog(authHost, token, params, page = 1) {
  const normalizedParams = new URLSearchParams(
    _.omitBy({ ...params, page }, _.isUndefined)
  ).toString()

  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/moderation_log?${normalizedParams}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchAdmins(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users?filters=is_admin`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchModerators(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users?filters=is_moderator`,
    method: 'get',
    headers: authHeaders(token)
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

src/api/nodeInfo.js

0 → 100644
+13 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { baseName } from './utils'

export async function getNodeInfo(authHost) {
  return await request({
    baseURL: baseName(authHost),
    url: `/nodeinfo/2.0.json`,
    method: 'get'
  })
}

src/api/peers.js

0 → 100644
+17 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function fetchPeers(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/v1/instance/peers`,
    method: 'get',
    headers: authHeaders(token)
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

src/api/qiniu.js

deleted100644 → 0
+0 −8
Original line number Diff line number Diff line
import request from '@/utils/request'

export function getToken() {
  return request({
    url: '/qiniu/upload/token', // 假地址 自行替换
    method: 'get'
  })
}

src/api/relays.js

0 → 100644
+37 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function fetchRelays(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/relay',
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function addRelay(relay_url, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/relay',
    method: 'post',
    headers: authHeaders(token),
    data: { relay_url }
  })
}

export async function deleteRelay(relay_url, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/relay',
    method: 'delete',
    headers: authHeaders(token),
    data: { relay_url }
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

src/api/remoteSearch.js

deleted100644 → 0
+0 −9
Original line number Diff line number Diff line
import request from '@/utils/request'

export function userSearch(name) {
  return request({
    url: '/search/user',
    method: 'get',
    params: { name }
  })
}

src/api/reports.js

0 → 100644
+58 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function changeState(reports, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/reports`,
    method: 'patch',
    headers: authHeaders(token),
    data: { reports }
  })
}

export async function fetchReports(filter, page, pageSize, authHost, token) {
  const url = filter.length > 0
    ? `/api/pleroma/admin/reports?state=${filter}&page=${page}&page_size=${pageSize}`
    : `/api/pleroma/admin/reports?page=${page}&page_size=${pageSize}`
  return await request({
    baseURL: baseName(authHost),
    url,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchSingleReport(id, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/reports/${id}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function createNote(content, reportID, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/reports/${reportID}/notes`,
    method: `post`,
    headers: authHeaders(token),
    data: { content }
  })
}

export async function deleteNote(noteID, reportID, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/reports/${reportID}/notes/${noteID}`,
    method: `delete`,
    headers: authHeaders(token)
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

src/api/settings.js

0 → 100644
+104 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'
import _ from 'lodash'

export async function deleteInstanceDocument(name, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/instance_document/${name}`,
    method: 'delete',
    headers: authHeaders(token)
  })
}

export async function fetchDescription(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/v1/pleroma/admin/config/descriptions`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchDescription2(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/v2/pleroma/admin/config/descriptions`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchSettings(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/config`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function getInstanceDocument(name, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/instance_document/${name}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function updateInstanceDocument(name, formData, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/instance_document/${name}`,
    method: 'patch',
    data: formData,
    headers: { ...authHeaders(token), 'Content-Type': 'multipart/form-data' }
  })
}

export async function updateSettings(configs, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/config`,
    method: 'post',
    headers: authHeaders(token),
    data: { configs }
  })
}

export async function removeSettings(configs, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/config`,
    method: 'post',
    headers: authHeaders(token),
    data: { configs }
  })
}

export async function fetchFrontends(authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/frontends`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function installFrontend(data, authHost, token) {
  const filteredData = _.pickBy(data)
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/frontends/install`,
    method: 'post',
    headers: authHeaders(token),
    data: filteredData
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

src/api/status.js

0 → 100644
+63 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function changeStatusScope(id, sensitive, visibility, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/statuses/${id}`,
    method: 'put',
    headers: authHeaders(token),
    data: { sensitive, visibility }
  })
}

export async function deleteStatus(id, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/statuses/${id}`,
    method: 'delete',
    headers: authHeaders(token)
  })
}

export async function fetchStatus(id, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/statuses/${id}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchStatuses({ godmode, localOnly, authHost, token, pageSize, page }) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/statuses?godmode=${godmode}&local_only=${localOnly}&page=${page}&page_size=${pageSize}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchStatusesCount(instance, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: instance ? `/api/pleroma/admin/stats?instance=${instance}` : `/api/pleroma/admin/stats`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchStatusesByInstance({ instance, authHost, token, pageSize, page }) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/instances/${instance}/statuses?page=${page}&page_size=${pageSize}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}

src/api/transaction.js

deleted100644 → 0
+0 −9
Original line number Diff line number Diff line
import request from '@/utils/request'

export function fetchList(query) {
  return request({
    url: '/transaction/list',
    method: 'get',
    params: query
  })
}

src/api/users.js

0 → 100644
+225 −0
Original line number Diff line number Diff line
// SPDX-FileCopyrightText: 2019-2022 Pleroma Authors <https://pleroma.social>
// SPDX-License-Identifier: AGPL-3.0-only

import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { baseName } from './utils'

export async function activateUsers(nicknames, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/activate`,
    method: 'patch',
    headers: authHeaders(token),
    data: { nicknames }
  })
}

export async function addRight(nicknames, right, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/permission_group/${right}`,
    method: 'post',
    headers: authHeaders(token),
    data: { nicknames }
  })
}

export async function createNewAccount(nickname, email, password, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/users',
    method: 'post',
    headers: authHeaders(token),
    data: { users: [{ nickname, email, password }] }
  })
}

export async function deactivateUsers(nicknames, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/deactivate`,
    method: 'patch',
    headers: authHeaders(token),
    data: { nicknames }
  })
}

export async function deleteRight(nicknames, right, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/permission_group/${right}`,
    method: 'delete',
    headers: authHeaders(token),
    data: { nicknames }
  })
}

export async function deleteUsers(nicknames, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users`,
    method: 'delete',
    headers: authHeaders(token),
    data: { nicknames }
  })
}

export async function disableMfa(nickname, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/disable_mfa`,
    method: 'put',
    headers: authHeaders(token),
    data: { nickname }
  })
}

export async function fetchUser(id, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/${id}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchUserCredentials(nickname, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/${nickname}/credentials`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function updateUserCredentials(nickname, credentials, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/${nickname}/credentials`,
    method: 'patch',
    headers: authHeaders(token),
    data: credentials
  })
}

export async function fetchUsers(filters, actorTypeFilters, authHost, token, page = 1) {
  const url = actorTypeFilters.length === 0
    ? `/api/pleroma/admin/users?page=${page}&filters=${filters}`
    : actorTypeFilters.reduce((acc, filter) => {
      const newAcc = acc.concat(`&actor_types[]=${filter}`)
      return newAcc
    }, `/api/pleroma/admin/users?page=${page}&filters=${filters}`)

  return await request({
    baseURL: baseName(authHost),
    url,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function getPasswordResetToken(nickname, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/${nickname}/password_reset`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function forcePasswordReset(nicknames, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/force_password_reset`,
    method: 'patch',
    headers: authHeaders(token),
    data: { nicknames }
  })
}

export async function searchUsers(query, filters, actorTypeFilters, authHost, token, page = 1) {
  const url = actorTypeFilters.length === 0
    ? `/api/pleroma/admin/users?query=${query}&page=${page}&filters=${filters}`
    : actorTypeFilters.reduce((acc, filter) => {
      const newAcc = acc.concat(`&actor_types[]=${filter}`)
      return newAcc
    }, `/api/pleroma/admin/users?query=${query}&page=${page}&filters=${filters}`)

  return await request({
    baseURL: baseName(authHost),
    url,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function tagUser(nicknames, tags, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/users/tag',
    method: 'put',
    headers: authHeaders(token),
    data: { nicknames, tags }
  })
}

export async function untagUser(nicknames, tags, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/users/tag',
    method: 'delete',
    headers: authHeaders(token),
    data: { nicknames, tags }
  })
}

export async function fetchUserStatuses(id, authHost, godmode, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/${id}/statuses?godmode=${godmode}`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function fetchUserChats(id, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: `/api/pleroma/admin/users/${id}/chats`,
    method: 'get',
    headers: authHeaders(token)
  })
}

export async function approveUserAccount(nicknames, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/users/approve',
    method: 'patch',
    headers: authHeaders(token),
    data: { nicknames }
  })
}

export async function confirmUserEmail(nicknames, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/users/confirm_email',
    method: 'patch',
    headers: authHeaders(token),
    data: { nicknames }
  })
}

export async function resendConfirmationEmail(nicknames, authHost, token) {
  return await request({
    baseURL: baseName(authHost),
    url: '/api/pleroma/admin/users/resend_confirmation_email',
    method: 'patch',
    headers: authHeaders(token),
    data: { nicknames }
  })
}

const authHeaders = (token) => token ? { 'Authorization': `Bearer ${getToken()}` } : {}