Compare commits
1 Commits
chapril
...
honeypot-r
Author | SHA1 | Date | |
---|---|---|---|
2568db9bed |
@ -1,66 +0,0 @@
|
||||
# Update the VARIANT arg in docker-compose.yml to pick an Elixir version: 1.9, 1.10, 1.10.4
|
||||
ARG VARIANT="1.12.3"
|
||||
FROM elixir:${VARIANT}
|
||||
|
||||
# This Dockerfile adds a non-root user with sudo access. Update the “remoteUser” property in
|
||||
# devcontainer.json to use it. More info: https://aka.ms/vscode-remote/containers/non-root-user.
|
||||
ARG USERNAME=vscode
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=$USER_UID
|
||||
|
||||
# Options for common package install script
|
||||
ARG INSTALL_ZSH="true"
|
||||
ARG UPGRADE_PACKAGES="true"
|
||||
ARG COMMON_SCRIPT_SOURCE="https://raw.githubusercontent.com/microsoft/vscode-dev-containers/v0.209.6/script-library/common-debian.sh"
|
||||
ARG COMMON_SCRIPT_SHA="d35dd1711454156c9a59cc41ebe04fbff681ca0bd304f10fd5b13285d0de13b2"
|
||||
|
||||
# Optional Settings for Phoenix
|
||||
ARG PHOENIX_VERSION="1.6.2"
|
||||
|
||||
# [Optional] Setup nodejs
|
||||
ARG NODE_SCRIPT_SOURCE="https://raw.githubusercontent.com/microsoft/vscode-dev-containers/main/script-library/node-debian.sh"
|
||||
ARG NODE_SCRIPT_SHA="dev-mode"
|
||||
ARG NODE_VERSION="none"
|
||||
ENV NVM_DIR=/usr/local/share/nvm
|
||||
ENV NVM_SYMLINK_CURRENT=true
|
||||
ENV PATH=${NVM_DIR}/current/bin:${PATH}
|
||||
|
||||
# [Optional, Choice] Node.js version: none, lts/*, 16, 14, 12, 10
|
||||
ARG NODE_VERSION="none"
|
||||
|
||||
# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies.
|
||||
RUN apt-get update \
|
||||
&& export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install --no-install-recommends curl ca-certificates 2>&1 \
|
||||
&& curl -sSL ${COMMON_SCRIPT_SOURCE} -o /tmp/common-setup.sh \
|
||||
&& ([ "${COMMON_SCRIPT_SHA}" = "dev-mode" ] || (echo "${COMMON_SCRIPT_SHA} */tmp/common-setup.sh" | sha256sum -c -)) \
|
||||
&& /bin/bash /tmp/common-setup.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" \
|
||||
#
|
||||
# [Optional] Install Node.js for use with web applications
|
||||
&& if [ "$NODE_VERSION" != "none" ]; then \
|
||||
curl -sSL ${NODE_SCRIPT_SOURCE} -o /tmp/node-setup.sh \
|
||||
&& ([ "${NODE_SCRIPT_SHA}" = "dev-mode" ] || (echo "${NODE_SCRIPT_SHA} */tmp/node-setup.sh" | sha256sum -c -)) \
|
||||
&& /bin/bash /tmp/node-setup.sh "${NVM_DIR}" "${NODE_VERSION}" "${USERNAME}"; \
|
||||
fi \
|
||||
#
|
||||
# Install dependencies
|
||||
&& apt-get install -y build-essential \
|
||||
#
|
||||
# Clean up
|
||||
&& apt-get autoremove -y \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/common-setup.sh /tmp/node-setup.sh
|
||||
|
||||
RUN su ${USERNAME} -c "mix local.hex --force \
|
||||
&& mix local.rebar --force \
|
||||
&& mix archive.install --force hex phx_new ${PHOENIX_VERSION}"
|
||||
|
||||
RUN apt-get update \
|
||||
&& export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install --no-install-recommends cmake webp bash libncurses6 git python3 inotify-tools \
|
||||
&& apt-get autoremove -y \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# [Optional] Uncomment this line to install additional package.
|
||||
# RUN mix ...
|
@ -1,44 +0,0 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/elixir-phoenix-postgres
|
||||
{
|
||||
"name": "Elixir, Phoenix, Node.js & PostgresSQL (Community)",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"service": "elixir",
|
||||
"workspaceFolder": "/workspace",
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"sqltools.connections": [{
|
||||
"name": "Container database",
|
||||
"driver": "PostgreSQL",
|
||||
"previewLimit": 50,
|
||||
"server": "localhost",
|
||||
"port": 5432,
|
||||
"database": "postgres",
|
||||
"username": "postgres",
|
||||
"password": "postgres"
|
||||
}]
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"jakebecker.elixir-ls",
|
||||
"mtxr.sqltools",
|
||||
"mtxr.sqltools-driver-pg"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
"forwardPorts": [4000, 4001, 5432],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "mix deps.get",
|
||||
// "runArgs": ["--userns=keep-id", "--privileged"],
|
||||
// "containerUser": "vscode",
|
||||
// "containerEnv": {
|
||||
// "HOME": "/home/vscode",
|
||||
// },
|
||||
// "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,Z",
|
||||
|
||||
// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "vscode"
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
elixir:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
# Elixir Version: 1.9, 1.10, 1.10.4, ...
|
||||
VARIANT: "1.13.1"
|
||||
# Phoenix Version: 1.4.17, 1.5.4, ...
|
||||
PHOENIX_VERSION: "1.6.6"
|
||||
# Node Version: 10, 11, ...
|
||||
NODE_VERSION: "16"
|
||||
|
||||
volumes:
|
||||
- ..:/workspace:z
|
||||
# Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
|
||||
network_mode: service:db
|
||||
|
||||
# Overrides default command so things don't shut down after the process ends.
|
||||
command: sleep infinity
|
||||
environment:
|
||||
MOBILIZON_INSTANCE_NAME: My Mobilizon Instance
|
||||
MOBILIZON_INSTANCE_HOST: localhost
|
||||
MOBILIZON_INSTANCE_HOST_PORT: 4000
|
||||
MOBILIZON_INSTANCE_PORT: 4000
|
||||
MOBILIZON_INSTANCE_EMAIL: noreply@mobilizon.me
|
||||
MOBILIZON_INSTANCE_REGISTRATIONS_OPEN: "true"
|
||||
MOBILIZON_DATABASE_PASSWORD: postgres
|
||||
MOBILIZON_DATABASE_USERNAME: postgres
|
||||
MOBILIZON_DATABASE_DBNAME: mobilizon
|
||||
MOBILIZON_DATABASE_HOST: db
|
||||
|
||||
db:
|
||||
image: postgis/postgis:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: app
|
||||
|
||||
volumes:
|
||||
postgres-data: null
|
@ -15,5 +15,5 @@ Makefile
|
||||
README.md
|
||||
SECURITY.md
|
||||
ssh_match_hostname
|
||||
support
|
||||
.js/package-lock.json
|
||||
js/node_modules
|
15
.doctor.exs
@ -1,15 +0,0 @@
|
||||
%Doctor.Config{
|
||||
exception_moduledoc_required: true,
|
||||
failed: false,
|
||||
ignore_modules: [Mobilizon.Web, Mobilizon.GraphQL.Schema, Mobilizon.Service.Activity.Renderer, Mobilizon.Service.Workers.Helper],
|
||||
ignore_paths: [],
|
||||
min_module_doc_coverage: 100,
|
||||
min_module_spec_coverage: 50,
|
||||
min_overall_doc_coverage: 100,
|
||||
min_overall_spec_coverage: 90,
|
||||
moduledoc_required: true,
|
||||
raise: false,
|
||||
reporter: Doctor.Reporters.Full,
|
||||
struct_type_spec_required: true,
|
||||
umbrella: false
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
# Database settings
|
||||
POSTGRES_USER=mobilizon
|
||||
POSTGRES_PASSWORD=changethis
|
||||
POSTGRES_DB=mobilizon
|
||||
POSTGRES_PORT=5432
|
||||
|
||||
# Instance configuration
|
||||
MOBILIZON_INSTANCE_REGISTRATIONS_OPEN=false
|
||||
MOBILIZON_INSTANCE_NAME=My Mobilizon Instance
|
||||
MOBILIZON_INSTANCE_HOST=mobilizon.lan
|
||||
MOBILIZON_INSTANCE_PORT=4000
|
||||
|
||||
MOBILIZON_INSTANCE_SECRET_KEY_BASE=changethis
|
||||
MOBILIZON_INSTANCE_SECRET_KEY=changethis
|
||||
|
||||
MOBILIZON_INSTANCE_EMAIL=noreply@mobilizon.lan
|
||||
MOBILIZON_REPLY_EMAIL=contact@mobilizon.lan
|
||||
|
||||
# Email settings
|
||||
MOBILIZON_SMTP_SERVER=localhost
|
||||
MOBILIZON_SMTP_PORT=25
|
||||
MOBILIZON_SMTP_USERNAME=noreply@mobilizon.lan
|
||||
MOBILIZON_SMTP_PASSWORD=password
|
||||
MOBILIZON_SMTP_SSL=false
|
@ -1,4 +1,3 @@
|
||||
[
|
||||
plugins: [Phoenix.LiveView.HTMLFormatter],
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test,priv}/**/*.{ex,exs,heex}"]
|
||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test,priv}/**/*.{ex,exs}"]
|
||||
]
|
||||
|
10
.gitignore
vendored
@ -14,7 +14,6 @@ erl_crash.dump
|
||||
# secrets files as long as you replace their contents by environment
|
||||
# variables.
|
||||
/config/*.secret.exs
|
||||
/config/runtime.exs
|
||||
|
||||
/setup_db.psql
|
||||
|
||||
@ -26,26 +25,17 @@ priv/data/*
|
||||
!priv/data/.gitkeep
|
||||
priv/errors/*
|
||||
!priv/errors/.gitkeep
|
||||
priv/cert/
|
||||
priv/python/__pycache__/
|
||||
.vscode/
|
||||
cover/
|
||||
site/
|
||||
test/fixtures/image_tmp.jpg
|
||||
test/fixtures/picture_tmp.png
|
||||
test/fixtures/DSCN0010_tmp.jpg
|
||||
test/uploads/
|
||||
uploads/*
|
||||
release/
|
||||
!uploads/.gitkeep
|
||||
!uploads/exports/.gitkeep
|
||||
!uploads/exports/**/.gitkeep
|
||||
.idea
|
||||
*.mo
|
||||
*.po~
|
||||
.weblate
|
||||
docker/production/.env
|
||||
test-junit-report.xml
|
||||
js/junit.xml
|
||||
.env
|
||||
demo/
|
||||
|
358
.gitlab-ci.yml
@ -1,22 +1,17 @@
|
||||
image: tcitworld/mobilizon-ci
|
||||
|
||||
stages:
|
||||
- install
|
||||
- check
|
||||
- build-js
|
||||
- test
|
||||
- docker
|
||||
- package
|
||||
- upload
|
||||
- deploy
|
||||
- docker
|
||||
|
||||
variables:
|
||||
MIX_ENV: "test"
|
||||
YARN_CACHE_FOLDER: "js/.yarn"
|
||||
# DB Variables for Postgres / Postgis
|
||||
POSTGRES_DB: mobilizon_test
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_PASSWORD: ""
|
||||
POSTGRES_HOST: postgres
|
||||
# DB Variables for Mobilizon
|
||||
MOBILIZON_DATABASE_USERNAME: $POSTGRES_USER
|
||||
@ -25,137 +20,95 @@ variables:
|
||||
MOBILIZON_DATABASE_HOST: $POSTGRES_HOST
|
||||
GEOLITE_CITIES_PATH: "/usr/share/GeoIP/GeoLite2-City.mmdb"
|
||||
MOBILIZON_INSTANCE_REGISTRATIONS_OPEN: "true"
|
||||
# Release elements
|
||||
PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${CI_PROJECT_NAME}"
|
||||
ARCH: "amd64"
|
||||
EXPORT_FORMATS: "csv,ods,pdf"
|
||||
APP_VERSION: "${CI_COMMIT_REF_NAME}"
|
||||
APP_ASSET: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${ARCH}.tar.gz"
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
|
||||
cache:
|
||||
key: "${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}"
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- ~/.cache/Cypress
|
||||
- cache/Cypress
|
||||
- deps/
|
||||
- _build/
|
||||
- deps/
|
||||
- js/node_modules
|
||||
- js/.yarn
|
||||
- cache/Cypress
|
||||
|
||||
# Installed dependencies are cached across the pipeline
|
||||
# So there is no need to reinstall them all the time
|
||||
# It saves minutes during a pipeline build time
|
||||
install:
|
||||
stage: install
|
||||
script:
|
||||
- yarn --cwd "js" install --frozen-lockfile
|
||||
- mix deps.get
|
||||
- mix compile
|
||||
|
||||
lint-elixir:
|
||||
lint:
|
||||
stage: check
|
||||
before_script:
|
||||
- mix deps.get
|
||||
script:
|
||||
- export EXITVALUE=0
|
||||
- git fetch origin ${CI_DEFAULT_BRANCH}
|
||||
- TARGET_SHA1=$(git show-ref -s ${CI_DEFAULT_BRANCH})
|
||||
- echo "$TARGET_SHA1"
|
||||
- mix deps.get
|
||||
- mix credo --strict -a || export EXITVALUE=1
|
||||
- mix format --check-formatted --dry-run || export EXITVALUE=1
|
||||
- mix credo diff --from-git-merge-base $TARGET_SHA1 --strict -a || export EXITVALUE=1
|
||||
- mix sobelow --config || export EXITVALUE=1
|
||||
- cd js
|
||||
- yarn install
|
||||
- yarn run lint || export EXITVALUE=1
|
||||
- yarn run prettier -c . || export EXITVALUE=1
|
||||
- yarn run build:assets
|
||||
- cd ../
|
||||
- exit $EXITVALUE
|
||||
|
||||
lint-front:
|
||||
image: node:16
|
||||
stage: check
|
||||
before_script:
|
||||
- export EXITVALUE=0
|
||||
- yarn --cwd "js" install --frozen-lockfile
|
||||
script:
|
||||
- yarn --cwd "js" run lint || export EXITVALUE=1
|
||||
- yarn --cwd "js" run prettier -c . || export EXITVALUE=1
|
||||
- exit $EXITVALUE
|
||||
|
||||
build-frontend:
|
||||
stage: build-js
|
||||
image: node:16
|
||||
before_script:
|
||||
- apt update
|
||||
- apt install -y --no-install-recommends python build-essential webp imagemagick gifsicle jpegoptim optipng pngquant
|
||||
script:
|
||||
- yarn --cwd "js" install --frozen-lockfile
|
||||
- yarn --cwd "js" run build
|
||||
artifacts:
|
||||
expire_in: 5 days
|
||||
expire_in: 1 day
|
||||
when: on_success
|
||||
paths:
|
||||
- priv/static
|
||||
needs:
|
||||
- lint-front
|
||||
|
||||
deps:
|
||||
stage: check
|
||||
before_script:
|
||||
- mix deps.get
|
||||
script:
|
||||
- export EXITVALUE=0
|
||||
- mix deps.get
|
||||
- mix hex.outdated || export EXITVALUE=1
|
||||
- yarn --cwd "js" outdated || export EXITVALUE=1
|
||||
- cd js
|
||||
- yarn outdated || export EXITVALUE=1
|
||||
- exit $EXITVALUE
|
||||
allow_failure: true
|
||||
needs:
|
||||
- install
|
||||
|
||||
exunit:
|
||||
stage: test
|
||||
services:
|
||||
- name: postgis/postgis:14-3.2
|
||||
- name: mdillon/postgis:11
|
||||
alias: postgres
|
||||
variables:
|
||||
MIX_ENV: test
|
||||
before_script:
|
||||
- mix deps.get && mix tz_world.update
|
||||
- mix ecto.create
|
||||
- mix ecto.migrate
|
||||
- cd js
|
||||
- yarn install
|
||||
- yarn run build:assets
|
||||
- cd ../
|
||||
- mix deps.get
|
||||
- MIX_ENV=test mix ecto.create
|
||||
- MIX_ENV=test mix ecto.migrate
|
||||
dependencies:
|
||||
- lint
|
||||
script:
|
||||
- mix coveralls
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
junit:
|
||||
- test-junit-report.xml
|
||||
expire_in: 30 days
|
||||
|
||||
jest:
|
||||
stage: test
|
||||
needs:
|
||||
- lint-front
|
||||
before_script:
|
||||
- yarn --cwd "js" install --frozen-lockfile
|
||||
- cd js
|
||||
- yarn install
|
||||
dependencies:
|
||||
- lint
|
||||
script:
|
||||
- yarn --cwd "js" run test:unit --no-color --ci --reporters=default --reporters=jest-junit
|
||||
- yarn run test:unit --no-color
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- js/coverage
|
||||
reports:
|
||||
junit:
|
||||
- js/junit.xml
|
||||
expire_in: 30 days
|
||||
|
||||
# cypress:
|
||||
# stage: test
|
||||
# services:
|
||||
# - name: postgis/postgis:13.3
|
||||
# - name: mdillon/postgis:11
|
||||
# alias: postgres
|
||||
# variables:
|
||||
# MIX_ENV=e2e
|
||||
# script:
|
||||
# - mix ecto.create
|
||||
# - mix ecto.migrate
|
||||
# - mix run priv/repo/e2e.seed.exs
|
||||
# - mix phx.server &
|
||||
# - mix deps.get
|
||||
# - cd js
|
||||
# - yarn install
|
||||
# - npx cypress install # just to be sure
|
||||
# - yarn run build
|
||||
# - cd ../
|
||||
# - MIX_ENV=e2e mix ecto.create
|
||||
# - MIX_ENV=e2e mix ecto.migrate
|
||||
# - MIX_ENV=e2e mix run priv/repo/e2e.seed.exs
|
||||
# - MIX_ENV=e2e mix phx.server &
|
||||
# - cd js
|
||||
# - npx wait-on http://localhost:4000
|
||||
# - if [ -z "$CYPRESS_KEY" ]; then npx cypress run; else npx cypress run --record --parallel --key $CYPRESS_KEY; fi
|
||||
@ -165,201 +118,48 @@ jest:
|
||||
# - js/tests/e2e/screenshots/**/*.png
|
||||
# - js/tests/e2e/videos/**/*.mp4
|
||||
|
||||
pages:
|
||||
stage: deploy
|
||||
script:
|
||||
- mkdir public
|
||||
- mix deps.get
|
||||
- mix docs
|
||||
- mv doc public/backend
|
||||
# #- yarn run --cwd "js" styleguide:build
|
||||
# #- mv js/styleguide public/frontend
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == "main"'
|
||||
artifacts:
|
||||
expire_in: 1 hour
|
||||
paths:
|
||||
- public
|
||||
# pages:
|
||||
# stage: deploy
|
||||
# script:
|
||||
# # - mkdir public
|
||||
# # Mobilizon documentation is now on https://framagit.org/framasoft/joinmobilizon/documentation
|
||||
# # Mix docs disabled because of https://github.com/elixir-lang/ex_doc/issues/1172
|
||||
# # - mix deps.get
|
||||
# # - mix docs
|
||||
# # - mv doc public/backend
|
||||
# #- cd js
|
||||
# #- yarn install
|
||||
# #- yarn run styleguide:build
|
||||
# #- mv styleguide ../public/frontend
|
||||
# only:
|
||||
# - master
|
||||
# artifacts:
|
||||
# expire_in: 1 hour
|
||||
# paths:
|
||||
# - public
|
||||
|
||||
.docker: &docker
|
||||
stage: docker
|
||||
image: docker:20.10.12
|
||||
variables:
|
||||
DOCKER_TLS_CERTDIR: "/certs"
|
||||
DOCKER_HOST: tcp://docker:2376
|
||||
DOCKER_TLS_VERIFY: 1
|
||||
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
|
||||
DOCKER_DRIVER: overlay2
|
||||
services:
|
||||
- docker:20.10.12-dind
|
||||
cache: {}
|
||||
image:
|
||||
name: gcr.io/kaniko-project/executor:debug
|
||||
entrypoint: [""]
|
||||
before_script:
|
||||
# Install buildx
|
||||
- wget https://github.com/docker/buildx/releases/download/v0.8.1/buildx-v0.8.1.linux-amd64
|
||||
- mkdir -p ~/.docker/cli-plugins/
|
||||
- mv buildx-v0.8.1.linux-amd64 ~/.docker/cli-plugins/docker-buildx
|
||||
- chmod a+x ~/.docker/cli-plugins/docker-buildx
|
||||
# Create env
|
||||
- docker context create tls-environment
|
||||
- docker buildx create --use tls-environment
|
||||
# Install qemu/binfmt
|
||||
- docker pull tonistiigi/binfmt:latest
|
||||
- docker run --rm --privileged tonistiigi/binfmt:latest --install all
|
||||
# Login to DockerHub
|
||||
- mkdir -p ~/.docker
|
||||
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$CI_REGISTRY_AUTH\",\"email\":\"$CI_REGISTRY_EMAIL\"}}}" > ~/.docker/config.json
|
||||
tags:
|
||||
- "privileged"
|
||||
|
||||
build-docker-main:
|
||||
<<: *docker
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE != "framasoft"'
|
||||
when: never
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
- mkdir -p /kaniko/.docker
|
||||
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$CI_REGISTRY_AUTH\",\"email\":\"$CI_REGISTRY_EMAIL\"}}}" > /kaniko/.docker/config.json
|
||||
script:
|
||||
- docker buildx build --push --platform linux/amd64 -t framasoft/mobilizon:main -f docker/production/Dockerfile .
|
||||
- /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/docker/production/Dockerfile --destination $DOCKER_IMAGE_NAME
|
||||
|
||||
build-docker-master:
|
||||
<<: *docker
|
||||
only:
|
||||
- schedules
|
||||
variables:
|
||||
DOCKER_IMAGE_NAME: framasoft/mobilizon:master
|
||||
|
||||
build-docker-tag:
|
||||
<<: *docker
|
||||
rules: &tag-rules
|
||||
- if: '$CI_PROJECT_NAMESPACE != "framasoft"'
|
||||
when: never
|
||||
- if: $CI_COMMIT_TAG
|
||||
timeout: 3 hours
|
||||
script:
|
||||
- >
|
||||
docker buildx build
|
||||
--push
|
||||
--platform linux/amd64,linux/arm64,linux/arm
|
||||
-t framasoft/mobilizon:$CI_COMMIT_TAG
|
||||
-t framasoft/mobilizon:latest
|
||||
-f docker/production/Dockerfile .
|
||||
|
||||
# Packaging app for amd64
|
||||
package-app:
|
||||
image: mobilizon/buildpack:1.13.4-erlang-24.3.3-debian-buster
|
||||
stage: package
|
||||
variables: &release-variables
|
||||
MIX_ENV: "prod"
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
TZ: Etc/UTC
|
||||
APP_ASSET: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${ARCH}.tar.gz"
|
||||
script: &release-script
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix deps.get --only-prod
|
||||
- mix compile
|
||||
- mix phx.digest.clean --all && \
|
||||
- mix release --path release/mobilizon
|
||||
- cd release/mobilizon && ln -s lib/mobilizon-*/priv priv && cd ../../
|
||||
- du -sh release/
|
||||
- 'echo "Artifact: ${APP_ASSET}"'
|
||||
- tar czf ${APP_ASSET} -C release mobilizon
|
||||
- du -sh ${APP_ASSET}
|
||||
only:
|
||||
- tags@framasoft/mobilizon
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- ${APP_ASSET}
|
||||
|
||||
package-app-dev:
|
||||
stage: package
|
||||
variables: *release-variables
|
||||
script: *release-script
|
||||
except:
|
||||
- tags@framasoft/mobilizon
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- ${APP_ASSET}
|
||||
|
||||
# Packaging app for multi-arch
|
||||
multi-arch-release:
|
||||
stage: package
|
||||
image: docker:20.10.12
|
||||
- tags
|
||||
variables:
|
||||
DOCKER_TLS_CERTDIR: "/certs"
|
||||
DOCKER_HOST: tcp://docker:2376
|
||||
DOCKER_TLS_VERIFY: 1
|
||||
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
|
||||
DOCKER_DRIVER: overlay2
|
||||
APP_ASSET: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${ARCH}.tar.gz"
|
||||
OS: debian-buster
|
||||
services:
|
||||
- docker:20.10.12-dind
|
||||
cache: {}
|
||||
before_script:
|
||||
# Install buildx
|
||||
- wget https://github.com/docker/buildx/releases/download/v0.8.1/buildx-v0.8.1.linux-amd64
|
||||
- mkdir -p ~/.docker/cli-plugins/
|
||||
- mv buildx-v0.8.1.linux-amd64 ~/.docker/cli-plugins/docker-buildx
|
||||
- chmod a+x ~/.docker/cli-plugins/docker-buildx
|
||||
# Create env
|
||||
- docker context create tls-environment
|
||||
- docker buildx create --use tls-environment
|
||||
# Install qemu/binfmt
|
||||
- docker pull tonistiigi/binfmt:latest
|
||||
- docker run --rm --privileged tonistiigi/binfmt:latest --install all
|
||||
script:
|
||||
- docker buildx build --platform linux/${ARCH} --output type=local,dest=releases --build-arg APP_ASSET=${APP_ASSET} -f docker/multiarch/Dockerfile .
|
||||
- ls -alh releases/mobilizon/
|
||||
- du -sh releases/mobilizon/${APP_ASSET}
|
||||
- mv releases/mobilizon/${APP_ASSET} .
|
||||
tags:
|
||||
- "privileged"
|
||||
artifacts:
|
||||
expire_in: 2 days
|
||||
paths:
|
||||
- ${APP_ASSET}
|
||||
parallel:
|
||||
matrix:
|
||||
- ARCH: ["arm", "arm64"]
|
||||
rules:
|
||||
- if: '$CI_PROJECT_NAMESPACE != "framasoft"'
|
||||
when: never
|
||||
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
||||
- if: $CI_COMMIT_TAG
|
||||
timeout: 3h
|
||||
|
||||
# Release
|
||||
release-upload:
|
||||
stage: upload
|
||||
image: framasoft/upload-packages:latest
|
||||
variables:
|
||||
APP_ASSET: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_${ARCH}.tar.gz"
|
||||
rules: *tag-rules
|
||||
script:
|
||||
- eval `ssh-agent -s`
|
||||
- ssh-add <(echo "${DEPLOYEMENT_KEY}" | base64 --decode -i)
|
||||
- echo "put -r ${APP_ASSET}" | sftp -o "VerifyHostKeyDNS yes" ${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:public/
|
||||
artifacts:
|
||||
expire_in: 1 day
|
||||
when: on_success
|
||||
paths:
|
||||
- mobilizon_*.tar.gz
|
||||
parallel:
|
||||
matrix:
|
||||
- ARCH: ["amd64", "arm", "arm64"]
|
||||
|
||||
release-create:
|
||||
stage: deploy
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
rules: *tag-rules
|
||||
variables:
|
||||
APP_ASSET_AMD64: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_amd64.tar.gz"
|
||||
APP_ASSET_ARM: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_arm.tar.gz"
|
||||
APP_ASSET_ARM64: "${CI_PROJECT_NAME}_${CI_COMMIT_REF_NAME}_arm64.tar.gz"
|
||||
before_script:
|
||||
- apk --no-cache add gawk sed grep
|
||||
script: |
|
||||
CHANGELOG=$(awk -v version="$APP_VERSION" '/^## / { printit = $2 == version }; printit' CHANGELOG.md | grep -v "## $APP_VERSION" | sed '1{/^$/d}')
|
||||
ENDPOINT="https://packages.joinmobilizon.org"
|
||||
|
||||
release-cli create --name "$CI_COMMIT_TAG" \
|
||||
--description "$CHANGELOG" \
|
||||
--tag-name "$CI_COMMIT_TAG" \
|
||||
--assets-link "{\"name\":\"${APP_ASSET_AMD64}\",\"url\":\"${ENDPOINT}/${APP_ASSET_AMD64}\"}" \
|
||||
--assets-link "{\"name\":\"${APP_ASSET_ARM}\",\"url\":\"${ENDPOINT}/${APP_ASSET_ARM}\"}" \
|
||||
--assets-link "{\"name\":\"${APP_ASSET_ARM64}\",\"url\":\"${ENDPOINT}/${APP_ASSET_ARM64}\"}"
|
||||
DOCKER_IMAGE_NAME: framasoft/mobilizon:$CI_COMMIT_TAG
|
||||
|
@ -1,12 +0,0 @@
|
||||
[
|
||||
verbose: true,
|
||||
private: false,
|
||||
skip: true,
|
||||
router: "lib/web/router.ex",
|
||||
exit: "low",
|
||||
format: "txt",
|
||||
out: "",
|
||||
threshold: "medium",
|
||||
ignore: ["Config.HTTPS", "Config.CSP"],
|
||||
ignore_files: ["config/runtime.exs"]
|
||||
]
|
@ -1,16 +0,0 @@
|
||||
|
||||
02CE4963DFD1B0D6D5C567357CAFFE97
|
||||
155A1FB53DE39EC8EFCFD7FB94EA823D
|
||||
2262742E5C8944D5BF6698EC61F5DE50
|
||||
25BEE162A99754480967216281E9EF33
|
||||
2A6F71CD6F1246F0B152C2376E2E398A
|
||||
30552A09D485A6AA73401C1D54F63C21
|
||||
52900CE4EE3598F6F178A651FB256770
|
||||
6151F44368FC19F2394274F513C29151
|
||||
765526195D4C6D770EAF4DC944A8CBF4
|
||||
B2FF1A12F13B873507C85091688C1D6D
|
||||
B9AF8A342CD7FF39E10CC10A408C28E1
|
||||
C042E87389F7BDCFF4E076E95731AE69
|
||||
C42BFAEF7100F57BED75998B217C857A
|
||||
D11958E86F1B6D37EF656B63405CA8A4
|
||||
F16F054F2628609A726B9FF2F089D484
|
@ -1,2 +0,0 @@
|
||||
elixir 1.13.4-otp-24
|
||||
erlang 24.3.3
|
1436
CHANGELOG.md
@ -1,6 +1,6 @@
|
||||
FROM elixir:alpine
|
||||
FROM bitwalker/alpine-elixir:latest
|
||||
|
||||
RUN apk add --no-cache inotify-tools postgresql-client yarn file make gcc libc-dev argon2 imagemagick cmake build-base libwebp-tools bash ncurses git python3
|
||||
RUN apk add --no-cache inotify-tools postgresql-client yarn file make gcc libc-dev argon2 imagemagick cmake build-base libwebp-tools bash ncurses
|
||||
|
||||
RUN mix local.hex --force && mix local.rebar --force
|
||||
|
||||
|
25
Makefile
@ -1,27 +1,18 @@
|
||||
init:
|
||||
@bash docker/message.sh "Start"
|
||||
@bash docker/message.sh "start"
|
||||
make start
|
||||
|
||||
setup: stop
|
||||
@bash docker/message.sh "Compiling everything"
|
||||
docker-compose run --rm api bash -c 'mix deps.get; yarn --cwd "js"; yarn --cwd "js" build:pictures; mix ecto.create; mix ecto.migrate'
|
||||
migrate:
|
||||
docker-compose run --rm api mix ecto.migrate
|
||||
logs:
|
||||
docker-compose logs -f
|
||||
start: stop
|
||||
@bash docker/message.sh "Starting Mobilizon with Docker"
|
||||
@bash docker/message.sh "starting Mobilizon with docker"
|
||||
docker-compose up -d api
|
||||
@bash docker/message.sh "Docker server started"
|
||||
@bash docker/message.sh "Docker server started."
|
||||
stop:
|
||||
@bash docker/message.sh "Stopping Mobilizon"
|
||||
@bash docker/message.sh "stopping Mobilizon"
|
||||
docker-compose down
|
||||
@bash docker/message.sh "Mobilizon is stopped"
|
||||
@bash docker/message.sh "stopped"
|
||||
test: stop
|
||||
@bash docker/message.sh "Running tests"
|
||||
docker-compose -f docker-compose.yml -f docker-compose.test.yml run api mix test $(only)
|
||||
@bash docker/message.sh "Done running tests"
|
||||
format:
|
||||
docker-compose run --rm api bash -c "mix format && mix credo --strict"
|
||||
@bash docker/message.sh "Code is now ready to commit :)"
|
||||
docker-compose -f docker-compose.yml -f docker-compose.test.yml run api mix test
|
||||
@bash docker/message.sh "Tests runned"
|
||||
|
||||
target: init
|
||||
|
23
README.md
@ -20,7 +20,7 @@ Mobilizon is your federated organization and mobilization platform. Gather peopl
|
||||
|
||||
Mobilizon is a tool designed to create platforms for managing communities and events. Its purpose is to help as many people as possible to free themselves from Facebook groups and events, from Meetup, etc.
|
||||
|
||||
The Mobilizon software is under a Free licence, so anyone can host a Mobilizon server, called an instance. These instances may federate with each other, so any person with an account on _ExampleMeet_ will be able to register to an event created on _SpecimenEvent_.
|
||||
The Mobilizon software is under a Free licence, so anyone can host a Mobilizon server, called an instance. These instances may federate with each other, so any person with an account on *ExampleMeet* will be able to register to an event created on *SpecimenEvent*.
|
||||
|
||||
## ✨ Features
|
||||
|
||||
@ -46,26 +46,23 @@ We appreciate any contribution to Mobilizon. Check our [CONTRIBUTING](CONTRIBUTI
|
||||
## Links
|
||||
|
||||
### Learn more
|
||||
|
||||
- 🌐 Official website: [https://joinmobilizon.org](https://joinmobilizon.org)
|
||||
- 🔢 Pick an instance [https://mobilizon.org](https://mobilizon.org)
|
||||
- 💻 Source: [https://framagit.org/framasoft/mobilizon](https://framagit.org/framasoft/mobilizon)
|
||||
- 📜 Documentation [https://docs.joinmobilizon.org](https://docs.joinmobilizon.org)
|
||||
* 🌐 Official website: [https://joinmobilizon.org](https://joinmobilizon.org)
|
||||
* 🔢 Pick an instance [https://mobilizon.org](https://mobilizon.org)
|
||||
* 💻 Source: [https://framagit.org/framasoft/mobilizon](https://framagit.org/framasoft/mobilizon)
|
||||
* 📜 Documentation [https://docs.joinmobilizon.org](https://docs.joinmobilizon.org)
|
||||
|
||||
### Discuss
|
||||
|
||||
- 💬 Element/Matrix: [https://matrix.to/#/#Mobilizon:matrix.org](https://matrix.to/#/#Mobilizon:matrix.org)
|
||||
- 🗣️ Forum: [https://framacolibri.org/c/mobilizon](https://framacolibri.org/c/mobilizon)
|
||||
* 💬 Element/Matrix: [https://matrix.to/#/#Mobilizon:matrix.org](https://matrix.to/#/#Mobilizon:matrix.org)
|
||||
* 🗣️ Forum: [https://framacolibri.org/c/mobilizon](https://framacolibri.org/c/mobilizon)
|
||||
|
||||
### Follow
|
||||
|
||||
- 🐘 Mastodon: [https://framapiaf.org/@mobilizon](https://framapiaf.org/@mobilizon)
|
||||
- 🐦 Twitter [https://twitter.com/@joinmobilizon](https://twitter.com/@joinmobilizon)
|
||||
* 🐘 Mastodon: [https://framapiaf.org/@mobilizon](https://framapiaf.org/@mobilizon)
|
||||
* 🐦 Twitter [https://twitter.com/@joinmobilizon](https://twitter.com/@joinmobilizon)
|
||||
|
||||
Note: Most federation code comes from [Pleroma](https://pleroma.social), which is `Copyright © 2017-2018 Pleroma Authors - AGPL-3.0`.
|
||||
|
||||
## ❤️ Supports of our crowdfunding
|
||||
|
||||
## ❤️ Supports of our crowdfunding
|
||||
---
|
||||
|
||||
We have run [a crowdfunding campaign](https://framablog.org/2019/05/14/mobilizon-lets-finance-a-software-to-free-our-events-from-facebook/) to pave the road to the version 1.0.0 of Mobilizon. Thanks to everyone who pitched in and shared the news around! The list of [everyone who donated is available here](https://joinmobilizon.org/hall-of-fame).
|
||||
|
32
SECURITY.md
@ -5,15 +5,15 @@ Framasoft, the Mobilizon maintainer team and community take all security bugs in
|
||||
|
||||
### Goals
|
||||
|
||||
- Mobilizon users can understand the distinctions between public data and private data/metadata on Mobilizon.
|
||||
* Mobilizon users can understand the distinctions between public data and private data/metadata on Mobilizon.
|
||||
|
||||
- Users always know where their private data/metadata resides, who has access to it, and are able to access, export, and delete it.
|
||||
* Users always know where their private data/metadata resides, who has access to it, and are able to access, export, and delete it.
|
||||
|
||||
- Protect private user data/metadata, not just from hackers but also (as much as is possible) from other users, instance admins, community moderators, and external applications.
|
||||
* Protect private user data/metadata, not just from hackers but also (as much as is possible) from other users, instance admins, community moderators, and external applications.
|
||||
|
||||
- Secure from malicious creation, alteration or deletion of public data.
|
||||
* Secure from malicious creation, alteration or deletion of public data.
|
||||
|
||||
- GDPR compliance.
|
||||
* GDPR compliance.
|
||||
|
||||
Framasoft is both a developer of open-source/free/libre self-hosted software, and a service provider with users in the European Union. As a result, we are putting user privacy, data sovereignty, and GDPR compliance into our security plans, including asking both the Framasoft community and outside hackers to review our approaches and implementations.
|
||||
|
||||
@ -21,11 +21,11 @@ Framasoft is both a developer of open-source/free/libre self-hosted software, an
|
||||
|
||||
[Mobilizon](https://joinmobilizon.org) will be challenging to keep secure, as it is:
|
||||
|
||||
- open source, both back-end and front-end
|
||||
* open source, both back-end and front-end
|
||||
|
||||
- self-hosted by diverse organisations and individuals
|
||||
* self-hosted by diverse organisations and individuals
|
||||
|
||||
- federated (data is transmitted between different hosted instances)
|
||||
* federated (data is transmitted between different hosted instances)
|
||||
|
||||
This means there are more attack surfaces compared to typical proprietary, centralised platforms, but also means that hackers and even users can review every part of Mobilizon and make sure that it works as expected. This should result in more secure software, and higher trust in the application and its ecosystem.
|
||||
|
||||
@ -33,14 +33,14 @@ This means there are more attack surfaces compared to typical proprietary, centr
|
||||
|
||||
We are committed to working with security researchers to verify, reproduce, and respond to legitimate reported vulnerabilities. You can help us by following these simple guidelines:
|
||||
|
||||
- Alert us about the vulnerability as soon as you become aware of it by emailing the lead maintainer at tcit+mobilizon@framasoft.org.
|
||||
- Provide details needed to reproduce and validate the vulnerability and a Proof of Concept (PoC) as soon as possible
|
||||
- Act in good faith to avoid privacy violations, destruction of data, and interruption or degradation of services
|
||||
- Do not access or modify users’ private data, without explicit permission of the owner. Only interact with your own accounts or test accounts for security research purposes;
|
||||
- Contact Framasoft or a maintainer of the Mobilizon project (or the instance admin) immediately if you do inadvertently encounter user data. Do not view, alter, save, store, transfer, or otherwise access the data, and immediately purge any local information upon reporting the vulnerability;
|
||||
- The lead maintainer will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating the next steps in handling your report. After the initial reply to your report, the security team will endeavor to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||
- Give us time to confirm, determine the affected versions and prepare fixes to correct the issue before disclosing it to other parties (if after waiting a reasonable amount of time, we are clearly unable or unwilling to do anything about it, please do hold us accountable!)
|
||||
- Please test against a local instance of the software, and refrain from running any Denial of Service or automated testing tools against Framasoft's (and our partners') infrastructure
|
||||
* Alert us about the vulnerability as soon as you become aware of it by emailing the lead maintainer at tcit+mobilizon@framasoft.org.
|
||||
* Provide details needed to reproduce and validate the vulnerability and a Proof of Concept (PoC) as soon as possible
|
||||
* Act in good faith to avoid privacy violations, destruction of data, and interruption or degradation of services
|
||||
* Do not access or modify users’ private data, without explicit permission of the owner. Only interact with your own accounts or test accounts for security research purposes;
|
||||
* Contact Framasoft or a maintainer of the Mobilizon project (or the instance admin) immediately if you do inadvertently encounter user data. Do not view, alter, save, store, transfer, or otherwise access the data, and immediately purge any local information upon reporting the vulnerability;
|
||||
* The lead maintainer will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating the next steps in handling your report. After the initial reply to your report, the security team will endeavor to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||
* Give us time to confirm, determine the affected versions and prepare fixes to correct the issue before disclosing it to other parties (if after waiting a reasonable amount of time, we are clearly unable or unwilling to do anything about it, please do hold us accountable!)
|
||||
* Please test against a local instance of the software, and refrain from running any Denial of Service or automated testing tools against Framasoft's (and our partners') infrastructure
|
||||
|
||||
Note : Please report security bugs in third-party modules to the person or team maintaining the module.
|
||||
|
||||
|
189
UPGRADE.md
@ -1,189 +0,0 @@
|
||||
# Upgrading from 2.0 to 2.1
|
||||
|
||||
## Mailer library change
|
||||
|
||||
### Docker
|
||||
|
||||
The change is already applied. You may remove the `MOBILIZON_SMTP_HOSTNAME` environment key which is not used anymore.
|
||||
|
||||
### Release and source mode
|
||||
|
||||
In your configuration file under `config :mobilizon, Mobilizon.Web.Email.Mailer`,
|
||||
|
||||
- Change `Bamboo.SMTPAdapter` to `Swoosh.Adapters.SMTP`,
|
||||
- rename the `server` key to `relay`
|
||||
- remove the `hostname` key,
|
||||
- the default value of the username and password fields is an empty string and no longer `nil`.
|
||||
|
||||
```diff
|
||||
config :mobilizon, Mobilizon.Web.Email.Mailer,
|
||||
- adapter: Bamboo.SMTPAdapter,
|
||||
+ adapter: Swoosh.Adapters.SMTP,
|
||||
- server: "localhost",
|
||||
+ relay: "localhost",
|
||||
- hostname: "localhost",
|
||||
# usually 25, 465 or 587
|
||||
port: 25,
|
||||
- username: nil,
|
||||
+ username: "",
|
||||
- password: nil,
|
||||
+ password: "",
|
||||
# can be `:always` or `:never`
|
||||
tls: :if_available,
|
||||
allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
|
||||
retries: 1,
|
||||
# can be `true`
|
||||
no_mx_lookups: false,
|
||||
# can be `:always`. If your smtp relay requires authentication set it to `:always`.
|
||||
auth: :if_available
|
||||
```
|
||||
|
||||
# Upgrading from 1.3 to 2.0
|
||||
|
||||
Requirements dependencies depend on the way Mobilizon is installed.
|
||||
|
||||
## New Elixir version requirement
|
||||
|
||||
### Docker and Release install
|
||||
|
||||
You are already using latest Elixir version in the release tarball and Docker images.
|
||||
|
||||
### Source install
|
||||
|
||||
**Elixir 1.12 and Erlang OTP 22 are now required**. If your distribution or the repositories from Erlang Solutions don't provide these versions, you need to uninstall the current versions and install [Elixir](https://github.com/asdf-vm/asdf-elixir) through the [ASDF tool](https://asdf-vm.com/).
|
||||
|
||||
## Geographic timezone data
|
||||
|
||||
Mobilizon 2.0 uses data based on [timezone-boundary-builder](https://github.com/evansiroky/timezone-boundary-builder) (which is based itself on OpenStreetMap data) to determine the timezone of an event automatically, based on it's geocoordinates. However, this needs ~700Mio of disk, so we don't redistribute data directly, depending on the case. It's possible to skip this part, but users will need to manually pick the timezone for every event they created when it has a different timezone from their own.
|
||||
|
||||
### Docker install
|
||||
|
||||
The geographic timezone data is already bundled into the image, you have nothing to do.
|
||||
|
||||
### Release install
|
||||
|
||||
In order to keep the release tarballs light, the geographic timezone data is not bundled directly. You need to download the data :
|
||||
|
||||
- either raw from Github, but **requires an extra ~1Gio of memory** to process the data
|
||||
|
||||
```sh
|
||||
sudo -u mobilizon mkdir /var/lib/mobilizon/timezones
|
||||
sudo -u mobilizon ./bin/mobilizon_ctl tz_world.update
|
||||
```
|
||||
|
||||
- either already processed from our own distribution server
|
||||
|
||||
```sh
|
||||
sudo -u mobilizon mkdir /var/lib/mobilizon/timezones
|
||||
sudo -u mobilizon curl -L 'https://packages.joinmobilizon.org/tz_world/timezones-geodata.dets' -o /var/lib/mobilizon/timezones/timezones-geodata.dets
|
||||
```
|
||||
|
||||
In both cases, ~700Mio of disk will be used. You may use the following configuration to specify where the data is expected if you decide to change it from the default location (`/var/lib/mobilizon/timezones`) :
|
||||
|
||||
```elixir
|
||||
config :tz_world, data_dir: "/some/place"
|
||||
```
|
||||
|
||||
### Source install
|
||||
|
||||
You need to download the data :
|
||||
|
||||
- either raw from Github, but **requires an extra ~1Gio of memory** to process the data
|
||||
|
||||
```sh
|
||||
sudo -u mobilizon mkdir /var/lib/mobilizon/timezones
|
||||
sudo -u mobilizon mix mobilizon.tz_world.update
|
||||
```
|
||||
|
||||
- either already processed from our own distribution server
|
||||
|
||||
```sh
|
||||
sudo -u mobilizon mkdir /var/lib/mobilizon/timezones
|
||||
sudo -u mobilizon curl -L 'https://packages.joinmobilizon.org/tz_world/timezones-geodata.dets' -o /var/lib/mobilizon/timezones/timezones-geodata.dets
|
||||
```
|
||||
|
||||
In both cases, ~700Mio of disk will be used. You may use the following configuration to specify where the data is expected:
|
||||
|
||||
```elixir
|
||||
config :tz_world, data_dir: "/some/place"
|
||||
```
|
||||
|
||||
## Exports folder
|
||||
|
||||
Create the folder for default CSV export:
|
||||
|
||||
```sh
|
||||
sudo -u mobilizon mkdir -p /var/lib/mobilizon/uploads/exports/csv
|
||||
```
|
||||
|
||||
This path can be configured, see [the dedicated docs page about this](https://docs.joinmobilizon.org/administration/configure/exports/).
|
||||
Files in this folder are temporary and are cleaned once an hour.
|
||||
|
||||
## New optional dependencies
|
||||
|
||||
These are optional, installing them will allow Mobilizon to export to PDF and ODS as well. Mobilizon 2.0 allows to export the participant list, but more is planned.
|
||||
|
||||
### Docker
|
||||
|
||||
Everything is included in our Docker image.
|
||||
|
||||
### Release and source install
|
||||
|
||||
New optional Python dependencies:
|
||||
|
||||
- `Python` >= 3.6
|
||||
- `weasyprint` for PDF export (with [a few extra dependencies](https://doc.courtbouillon.org/weasyprint/stable/first_steps.html))
|
||||
- `pyexcel-ods3` for ODS export (no extra dependencies)
|
||||
|
||||
Both can be installed through pip. You need to enable and configure exports for PDF and ODS in the configuration afterwards. Read [the dedicated docs page about this](https://docs.joinmobilizon.org/administration/configure/exports/).
|
||||
|
||||
# Upgrading from 1.0 to 1.1
|
||||
|
||||
The 1.1 version of Mobilizon brings Elixir releases support. An Elixir release is a self-contained directory that contains all of Mobilizon's code (front-end and backend), it's dependencies, as well as the Erlang Virtual Machine and runtime (only the parts you need). As long as the release has been assembled on the same OS and architecture, it can be deploy and run straight away. [Read more about releases](https://elixir-lang.org/getting-started/mix-otp/config-and-releases.html#releases).
|
||||
|
||||
## Comparison
|
||||
|
||||
Migrating to releases means:
|
||||
|
||||
- You only get a precompiled binary, so you avoid compilation times when updating
|
||||
- No need to have Elixir/NodeJS installed on the system
|
||||
- Code/data/config location is more common (/opt, /var/lib, /etc)
|
||||
- More efficient, as only what you need from the Elixir/Erlang standard libraries is included and all of the code is directly preloaded
|
||||
- You can't hardcode modifications in Mobilizon's code
|
||||
|
||||
Staying on source releases means:
|
||||
|
||||
- You need to recompile everything with each update
|
||||
- Compiling frontend and backend has higher system requirements than just running Mobilizon
|
||||
- You can change things in Mobilizon's code and recompile right away to test changes
|
||||
|
||||
## Releases
|
||||
|
||||
If you want to migrate to releases, [we provide a full guide](https://docs.joinmobilizon.org/administration/upgrading/source_to_release/). You may do this at any time.
|
||||
|
||||
## Source install
|
||||
|
||||
To stay on a source release, you just need to check the following things:
|
||||
|
||||
- Rename your configuration file `config/prod.secret.exs` to `config/runtime.exs`.
|
||||
- If your config file includes `server: true` under `Mobilizon.Web.Endpoint`, remove it.
|
||||
```diff
|
||||
config :mobilizon, Mobilizon.Web.Endpoint,
|
||||
- server: true,
|
||||
```
|
||||
- The uploads default directory is now `/var/lib/mobilizon/uploads`. To keep it in the previous `uploads/` directory, just add the following line to `config/runtime.exs`:
|
||||
```elixir
|
||||
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "uploads"
|
||||
```
|
||||
Or you may use any other directory where the `mobilizon` user has write permissions.
|
||||
- The GeoIP database default directory is now `/var/lib/mobilizon/geo/GeoLite2-City.mmdb`. To keep it in the previous `priv/data/GeoLite2-City.mmdb` directory, just add the following line to `config/runtime.exs`:
|
||||
```elixir
|
||||
config :geolix, databases: [
|
||||
%{
|
||||
id: :city,
|
||||
adapter: Geolix.Adapter.MMDB2,
|
||||
source: "priv/data/GeoLite2-City.mmdb"
|
||||
}
|
||||
]
|
||||
```
|
||||
Or you may use any other directory where the `mobilizon` user has read permissions.
|
@ -8,45 +8,42 @@ import Config
|
||||
# General application configuration
|
||||
config :mobilizon,
|
||||
ecto_repos: [Mobilizon.Storage.Repo],
|
||||
env: config_env()
|
||||
env: Mix.env()
|
||||
|
||||
config :mobilizon, Mobilizon.Storage.Repo, types: Mobilizon.Storage.PostgresTypes
|
||||
|
||||
config :mobilizon, :instance,
|
||||
name: "Mobilizon du Chapril",
|
||||
description: "Instance du Chapril",
|
||||
name: "My Mobilizon Instance",
|
||||
description: "Change this to a proper description of your instance",
|
||||
hostname: "localhost",
|
||||
registrations_open: true,
|
||||
registrations_open: false,
|
||||
registration_email_allowlist: [],
|
||||
registration_email_denylist: [],
|
||||
languages: [],
|
||||
default_language: "fr",
|
||||
default_language: "en",
|
||||
demo: false,
|
||||
repository: Mix.Project.config()[:source_url],
|
||||
allow_relay: true,
|
||||
federating: true,
|
||||
remote_limit: 100_000,
|
||||
upload_limit: 10_485_760,
|
||||
avatar_upload_limit: 2_097_152,
|
||||
banner_upload_limit: 4_194_304,
|
||||
upload_limit: 10_000_000,
|
||||
avatar_upload_limit: 2_000_000,
|
||||
banner_upload_limit: 4_000_000,
|
||||
remove_orphan_uploads: true,
|
||||
orphan_upload_grace_period_hours: 48,
|
||||
remove_unconfirmed_users: true,
|
||||
unconfirmed_user_grace_period_hours: 48,
|
||||
activity_expire_days: 365,
|
||||
activity_keep_number: 100,
|
||||
enable_instance_feeds: true,
|
||||
email_from: "noreply@mobilizon.chapril.org",
|
||||
email_reply_to: "noreply@mobilizon.chapril.org"
|
||||
email_from: "noreply@localhost",
|
||||
email_reply_to: "noreply@localhost"
|
||||
|
||||
config :mobilizon, :groups, enabled: true
|
||||
config :mobilizon, :events, creation: true
|
||||
|
||||
config :mobilizon, :restrictions, only_admin_can_create_groups: false
|
||||
config :mobilizon, :restrictions, only_groups_can_create_events: false
|
||||
config :mobilizon, :events, creation: true
|
||||
|
||||
# Configures the endpoint
|
||||
config :mobilizon, Mobilizon.Web.Endpoint,
|
||||
http: [
|
||||
transport_options: [socket_opts: [:inet6]]
|
||||
],
|
||||
url: [
|
||||
host: "mobilizon.local",
|
||||
scheme: "https"
|
||||
@ -60,19 +57,15 @@ config :mobilizon, Mobilizon.Web.Endpoint,
|
||||
config :mime, :types, %{
|
||||
"application/activity+json" => ["activity-json"],
|
||||
"application/ld+json" => ["activity-json"],
|
||||
"application/jrd+json" => ["jrd-json"],
|
||||
"application/xrd+xml" => ["xrd-xml"]
|
||||
"application/jrd+json" => ["jrd-json"]
|
||||
}
|
||||
|
||||
# Upload configuration
|
||||
config :mobilizon, Mobilizon.Web.Upload,
|
||||
uploader: Mobilizon.Web.Upload.Uploader.Local,
|
||||
filters: [
|
||||
Mobilizon.Web.Upload.Filter.AnalyzeMetadata,
|
||||
Mobilizon.Web.Upload.Filter.Resize,
|
||||
Mobilizon.Web.Upload.Filter.Optimize,
|
||||
Mobilizon.Web.Upload.Filter.BlurHash,
|
||||
Mobilizon.Web.Upload.Filter.Dedupe
|
||||
Mobilizon.Web.Upload.Filter.Dedupe,
|
||||
Mobilizon.Web.Upload.Filter.Optimize
|
||||
],
|
||||
allow_list_mime_types: ["image/gif", "image/jpeg", "image/png", "image/webp"],
|
||||
link_name: true,
|
||||
@ -86,36 +79,16 @@ config :mobilizon, Mobilizon.Web.Upload,
|
||||
]
|
||||
]
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "/var/lib/mobilizon/uploads"
|
||||
|
||||
config :tz_world, data_dir: "/var/lib/mobilizon/timezones"
|
||||
|
||||
config :mobilizon, Timex.Gettext, default_locale: "fr"
|
||||
|
||||
config :mobilizon, :media_proxy,
|
||||
enabled: true,
|
||||
proxy_opts: [
|
||||
redirect_on_failure: false,
|
||||
max_body_length: 25 * 1_048_576,
|
||||
# Note: max_read_duration defaults to Mobilizon.Web.ReverseProxy.max_read_duration_default/1
|
||||
max_read_duration: 30_000,
|
||||
http: [
|
||||
follow_redirect: true,
|
||||
pool: :media
|
||||
]
|
||||
]
|
||||
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "uploads"
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Email.Mailer,
|
||||
adapter: Swoosh.Adapters.SMTP,
|
||||
relay: "localhost",
|
||||
adapter: Bamboo.SMTPAdapter,
|
||||
server: "localhost",
|
||||
hostname: "localhost",
|
||||
# usually 25, 465 or 587
|
||||
port: 25,
|
||||
username: "",
|
||||
password: "",
|
||||
# can be `:always` or `:never`
|
||||
auth: :if_available,
|
||||
# can be `true`
|
||||
ssl: false,
|
||||
username: nil,
|
||||
password: nil,
|
||||
# can be `:always` or `:never`
|
||||
tls: :if_available,
|
||||
allowed_tls_versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
|
||||
@ -125,27 +98,17 @@ config :mobilizon, Mobilizon.Web.Email.Mailer,
|
||||
|
||||
# Configures Elixir's Logger
|
||||
config :logger, :console,
|
||||
backends: [:console],
|
||||
format: "$time $metadata[$level] $message\n",
|
||||
metadata: [:request_id]
|
||||
|
||||
config :logger, Sentry.LoggerBackend,
|
||||
level: :warn,
|
||||
capture_log_messages: true
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Auth.Guardian,
|
||||
issuer: "mobilizon",
|
||||
token_ttl: %{
|
||||
"access" => {15, :minutes},
|
||||
"refresh" => {60, :days}
|
||||
}
|
||||
config :mobilizon, Mobilizon.Web.Auth.Guardian, issuer: "mobilizon"
|
||||
|
||||
config :guardian, Guardian.DB,
|
||||
repo: Mobilizon.Storage.Repo,
|
||||
# default
|
||||
schema_name: "guardian_tokens",
|
||||
# store all token types if not set
|
||||
token_types: ["refresh"],
|
||||
# token_types: ["refresh_token"],
|
||||
# default: 60 minutes
|
||||
sweep_interval: 60
|
||||
|
||||
@ -161,12 +124,30 @@ config :ueberauth,
|
||||
|
||||
config :mobilizon, :auth, oauth_consumer_strategies: []
|
||||
|
||||
config :mobilizon, :ldap,
|
||||
enabled: System.get_env("LDAP_ENABLED") == "true",
|
||||
host: System.get_env("LDAP_HOST") || "localhost",
|
||||
port: String.to_integer(System.get_env("LDAP_PORT") || "389"),
|
||||
ssl: System.get_env("LDAP_SSL") == "true",
|
||||
sslopts: [],
|
||||
tls: System.get_env("LDAP_TLS") == "true",
|
||||
tlsopts: [],
|
||||
base: System.get_env("LDAP_BASE") || "dc=example,dc=com",
|
||||
uid: System.get_env("LDAP_UID") || "cn",
|
||||
require_bind_for_search: !(System.get_env("LDAP_REQUIRE_BIND_FOR_SEARCH") == "false"),
|
||||
# The full CN to filter by `memberOf`, or `false` if disabled
|
||||
group: false,
|
||||
# Either the admin UID matching the field in `uid`,
|
||||
# Either a tuple with the fully qualified DN: {:full, uid=admin,dc=example.com,dc=local}
|
||||
bind_uid: System.get_env("LDAP_BIND_UID"),
|
||||
bind_password: System.get_env("LDAP_BIND_PASSWORD")
|
||||
|
||||
config :geolix,
|
||||
databases: [
|
||||
%{
|
||||
id: :city,
|
||||
adapter: Geolix.Adapter.MMDB2,
|
||||
source: "/var/lib/mobilizon/geo/GeoLite2-City.mmdb"
|
||||
source: "priv/data/GeoLite2-City.mmdb"
|
||||
}
|
||||
]
|
||||
|
||||
@ -185,17 +166,6 @@ config :phoenix, :format_encoders, json: Jason, "activity-json": Jason
|
||||
config :phoenix, :json_library, Jason
|
||||
config :phoenix, :filter_parameters, ["password", "token"]
|
||||
|
||||
config :absinthe, schema: Mobilizon.GraphQL.Schema
|
||||
config :absinthe, Absinthe.Logger, filter_variables: ["token", "password", "secret"]
|
||||
|
||||
config :codepagex, :encodings, [
|
||||
:ascii,
|
||||
~r[iso8859]i,
|
||||
:"VENDORS/MICSFT/WINDOWS/CP1252"
|
||||
]
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Gettext, split_module_by: [:locale, :domain]
|
||||
|
||||
config :ex_cldr,
|
||||
default_locale: "en",
|
||||
default_backend: Mobilizon.Cldr
|
||||
@ -206,17 +176,14 @@ config :http_signatures,
|
||||
config :mobilizon, :cldr,
|
||||
locales: [
|
||||
"fr",
|
||||
"en",
|
||||
"ru",
|
||||
"ar"
|
||||
"en"
|
||||
]
|
||||
|
||||
config :mobilizon, :activitypub,
|
||||
# One day
|
||||
actor_stale_period: 3_600 * 48,
|
||||
actor_key_rotation_delay: 3_600 * 48,
|
||||
sign_object_fetches: true,
|
||||
stale_actor_search_exclusion_after: 3_600 * 24 * 7
|
||||
sign_object_fetches: true
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Nominatim
|
||||
|
||||
@ -248,24 +215,6 @@ config :mobilizon, :maps,
|
||||
type: :openstreetmap
|
||||
]
|
||||
|
||||
config :mobilizon, :http_security,
|
||||
enabled: true,
|
||||
sts: false,
|
||||
sts_max_age: 31_536_000,
|
||||
csp_policy: [
|
||||
script_src: [],
|
||||
style_src: [],
|
||||
connect_src: [],
|
||||
font_src: [],
|
||||
img_src: ["*.tile.openstreetmap.org"],
|
||||
manifest_src: [],
|
||||
media_src: [],
|
||||
object_src: [],
|
||||
frame_src: [],
|
||||
frame_ancestors: []
|
||||
],
|
||||
referrer_policy: "same-origin"
|
||||
|
||||
config :mobilizon, :anonymous,
|
||||
participation: [
|
||||
allowed: true,
|
||||
@ -294,20 +243,13 @@ config :mobilizon, :anonymous,
|
||||
config :mobilizon, Oban,
|
||||
repo: Mobilizon.Storage.Repo,
|
||||
log: false,
|
||||
queues: [default: 10, search: 5, mailers: 10, background: 5, activity: 5, notifications: 5],
|
||||
plugins: [
|
||||
{Oban.Plugins.Cron,
|
||||
crontab: [
|
||||
{"@hourly", Mobilizon.Service.Workers.BuildSiteMap, queue: :background},
|
||||
{"17 4 * * *", Mobilizon.Service.Workers.RefreshGroups, queue: :background},
|
||||
{"36 * * * *", Mobilizon.Service.Workers.RefreshInstances, queue: :background},
|
||||
{"@hourly", Mobilizon.Service.Workers.CleanOrphanMediaWorker, queue: :background},
|
||||
{"@hourly", Mobilizon.Service.Workers.CleanUnconfirmedUsersWorker, queue: :background},
|
||||
{"@hourly", Mobilizon.Service.Workers.ExportCleanerWorker, queue: :background},
|
||||
{"@hourly", Mobilizon.Service.Workers.SendActivityRecapWorker, queue: :notifications},
|
||||
{"@daily", Mobilizon.Service.Workers.CleanOldActivityWorker, queue: :background}
|
||||
]},
|
||||
{Oban.Plugins.Pruner, max_age: 300}
|
||||
queues: [default: 10, search: 5, mailers: 10, background: 5],
|
||||
crontab: [
|
||||
{"@hourly", Mobilizon.Service.Workers.BuildSiteMap, queue: :background},
|
||||
{"17 * * * *", Mobilizon.Service.Workers.RefreshGroups, queue: :background},
|
||||
# To be activated in Mobilizon 1.2
|
||||
# {"@hourly", Mobilizon.Service.Workers.CleanOrphanMediaWorker, queue: :background},
|
||||
{"@hourly", Mobilizon.Service.Workers.CleanUnconfirmedUsersWorker, queue: :background}
|
||||
]
|
||||
|
||||
config :mobilizon, :rich_media,
|
||||
@ -329,26 +271,6 @@ config :mobilizon, :external_resource_providers, %{
|
||||
"https://docs.google.com/spreadsheets/" => :google_spreadsheets
|
||||
}
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Notifier,
|
||||
notifiers: [
|
||||
Mobilizon.Service.Notifier.Email,
|
||||
Mobilizon.Service.Notifier.Push
|
||||
]
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Notifier.Email, enabled: true
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Notifier.Push, enabled: true
|
||||
|
||||
config :mobilizon, :exports,
|
||||
path: "/var/lib/mobilizon/uploads/exports",
|
||||
formats: [
|
||||
Mobilizon.Service.Export.Participants.CSV,
|
||||
Mobilizon.Service.Export.Participants.PDF,
|
||||
Mobilizon.Service.Export.Participants.ODS
|
||||
]
|
||||
|
||||
config :mobilizon, :analytics, providers: []
|
||||
|
||||
# Import environment specific config. This must remain at the bottom
|
||||
# of this file so it overrides the configuration defined above.
|
||||
import_config "#{config_env()}.exs"
|
||||
import_config "#{Mix.env()}.exs"
|
||||
|
@ -1,15 +1,20 @@
|
||||
import Config
|
||||
|
||||
# For development, we disable any cache and enable
|
||||
# debugging and code reloading.
|
||||
#
|
||||
# The watchers configuration can be used to run external
|
||||
# watchers to your application. For example, we use it
|
||||
# with brunch.io to recompile .js and .css sources.
|
||||
config :mobilizon, Mobilizon.Web.Endpoint,
|
||||
http: [
|
||||
port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_HOST_PORT", "4000"))
|
||||
port: 4000
|
||||
],
|
||||
url: [
|
||||
host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.local"),
|
||||
port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_HOST_PORT", "80")),
|
||||
port: 80,
|
||||
scheme: "http"
|
||||
],
|
||||
secret_key_base: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY_BASE", "changethis"),
|
||||
debug_errors: true,
|
||||
code_reloader: true,
|
||||
check_origin: false,
|
||||
@ -18,8 +23,7 @@ config :mobilizon, Mobilizon.Web.Endpoint,
|
||||
"node_modules/webpack/bin/webpack.js",
|
||||
"--mode",
|
||||
"development",
|
||||
"--watch",
|
||||
"--watch-options-stdin",
|
||||
"--watch-stdin",
|
||||
"--config",
|
||||
"node_modules/@vue/cli-service/webpack.config.js",
|
||||
cd: Path.expand("../js", __DIR__)
|
||||
@ -58,8 +62,6 @@ config :logger, :console, format: "[$level] $message\n", level: :debug
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Nominatim
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Gettext, allowed_locales: ["fr", "en", "ru", "ar"]
|
||||
|
||||
# Set a higher stacktrace during development. Avoid configuring such
|
||||
# in production as building large stacktraces may be expensive.
|
||||
config :phoenix, :stacktrace_depth, 20
|
||||
@ -67,7 +69,7 @@ config :phoenix, :stacktrace_depth, 20
|
||||
# Initialize plugs at runtime for faster development compilation
|
||||
config :phoenix, :plug_init_mode, :runtime
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Email.Mailer, adapter: Swoosh.Adapters.Local
|
||||
config :mobilizon, Mobilizon.Web.Email.Mailer, adapter: Bamboo.LocalAdapter
|
||||
|
||||
# Configure your database
|
||||
config :mobilizon, Mobilizon.Storage.Repo,
|
||||
@ -87,18 +89,26 @@ config :mobilizon, :instance,
|
||||
registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN") == "true",
|
||||
groups: true
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Auth.Guardian,
|
||||
secret_key: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY", "changethis")
|
||||
|
||||
# config :mobilizon, :activitypub, sign_object_fetches: false
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "uploads"
|
||||
|
||||
config :mobilizon, :exports, path: "uploads/exports"
|
||||
|
||||
config :tz_world, data_dir: "_build/dev/lib/tz_world/priv"
|
||||
|
||||
config :mobilizon, :anonymous,
|
||||
reports: [
|
||||
allowed: true
|
||||
]
|
||||
|
||||
require Logger
|
||||
|
||||
cond do
|
||||
System.get_env("INSTANCE_CONFIG") &&
|
||||
File.exists?("./config/#{System.get_env("INSTANCE_CONFIG")}") ->
|
||||
import_config System.get_env("INSTANCE_CONFIG")
|
||||
|
||||
System.get_env("DOCKER", "false") == "false" && File.exists?("./config/dev.secret.exs") ->
|
||||
import_config "dev.secret.exs"
|
||||
|
||||
System.get_env("DOCKER", "false") == "true" ->
|
||||
Logger.info("Using environment configuration for Docker")
|
||||
|
||||
true ->
|
||||
Logger.error("No configuration file found")
|
||||
end
|
||||
|
@ -16,29 +16,37 @@ config :logger, level: :info
|
||||
# Load all locales in production
|
||||
config :mobilizon, :cldr,
|
||||
locales: [
|
||||
# "ar",
|
||||
# "be",
|
||||
# "bn",
|
||||
# "ca",
|
||||
# "cs",
|
||||
# "cy",
|
||||
# "de",
|
||||
"ar",
|
||||
"be",
|
||||
"ca",
|
||||
"cs",
|
||||
"de",
|
||||
"en",
|
||||
# "es",
|
||||
# "fa",
|
||||
# "fi",
|
||||
"es",
|
||||
"fi",
|
||||
"fr",
|
||||
# "gd",
|
||||
# "gl",
|
||||
# "hu",
|
||||
# "id",
|
||||
# "it",
|
||||
# "ja",
|
||||
# "nl",
|
||||
# "nn",
|
||||
# "pl",
|
||||
# "pt",
|
||||
# "ru",
|
||||
# "sv",
|
||||
# "zh_Hant"
|
||||
"gl",
|
||||
"hu",
|
||||
"it",
|
||||
"ja",
|
||||
"nl",
|
||||
"nn",
|
||||
"oc",
|
||||
"pl",
|
||||
"pt",
|
||||
"ru",
|
||||
"sv"
|
||||
]
|
||||
|
||||
cond do
|
||||
System.get_env("INSTANCE_CONFIG") &&
|
||||
File.exists?("./config/#{System.get_env("INSTANCE_CONFIG")}") ->
|
||||
import_config System.get_env("INSTANCE_CONFIG")
|
||||
|
||||
File.exists?("./config/prod.secret.exs") ->
|
||||
import_config "prod.secret.exs"
|
||||
|
||||
true ->
|
||||
require Logger
|
||||
Logger.error("No configuration file found")
|
||||
end
|
||||
|
@ -36,58 +36,29 @@ config :mobilizon, Mobilizon.Storage.Repo,
|
||||
port: System.get_env("MOBILIZON_DATABASE_PORT") || "5432",
|
||||
pool: Ecto.Adapters.SQL.Sandbox
|
||||
|
||||
config :mobilizon, :ldap,
|
||||
enabled: System.get_env("LDAP_ENABLED") == "true",
|
||||
host: System.get_env("LDAP_HOST") || "localhost",
|
||||
port: String.to_integer(System.get_env("LDAP_PORT") || "389"),
|
||||
ssl: System.get_env("LDAP_SSL") == "true",
|
||||
sslopts: [],
|
||||
tls: System.get_env("LDAP_TLS") == "true",
|
||||
tlsopts: [],
|
||||
base: System.get_env("LDAP_BASE") || "dc=example,dc=com",
|
||||
uid: System.get_env("LDAP_UID") || "cn",
|
||||
require_bind_for_search: !(System.get_env("LDAP_REQUIRE_BIND_FOR_SEARCH") == "false"),
|
||||
# The full CN to filter by `memberOf`, or `false` if disabled
|
||||
group: false,
|
||||
# Either the admin UID matching the field in `uid`,
|
||||
# Either a tuple with the fully qualified DN: {:full, uid=admin,dc=example.com,dc=local}
|
||||
bind_uid: System.get_env("LDAP_BIND_UID"),
|
||||
bind_password: System.get_env("LDAP_BIND_PASSWORD")
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Email.Mailer, adapter: Swoosh.Adapters.Test
|
||||
config :mobilizon, Mobilizon.Web.Email.Mailer, adapter: Bamboo.TestAdapter
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Upload, filters: [], link_name: false
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "test/uploads"
|
||||
|
||||
config :mobilizon, :exports, path: "test/uploads/exports"
|
||||
|
||||
config :tz_world, data_dir: "_build/test/lib/tz_world/priv"
|
||||
config :exvcr,
|
||||
vcr_cassette_library_dir: "test/fixtures/vcr_cassettes"
|
||||
|
||||
config :tesla, Mobilizon.Service.HTTP.ActivityPub,
|
||||
adapter: Mobilizon.Service.HTTP.ActivityPub.Mock
|
||||
|
||||
config :tesla, Mobilizon.Service.HTTP.WebfingerClient,
|
||||
adapter: Mobilizon.Service.HTTP.WebfingerClient.Mock
|
||||
|
||||
config :tesla, Mobilizon.Service.HTTP.GeospatialClient,
|
||||
adapter: Mobilizon.Service.HTTP.GeospatialClient.Mock
|
||||
|
||||
config :tesla, Mobilizon.Service.HTTP.HostMetaClient,
|
||||
adapter: Mobilizon.Service.HTTP.HostMetaClient.Mock
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Mock
|
||||
|
||||
config :mobilizon, Oban, queues: false, plugins: false
|
||||
config :mobilizon, Oban, queues: false, crontab: false, plugins: false
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Auth.Guardian, secret_key: "some secret"
|
||||
|
||||
config :mobilizon, :activitypub, sign_object_fetches: false
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Gettext, allowed_locales: ["fr", "en", "es", "ru"]
|
||||
|
||||
config :junit_formatter, report_dir: "."
|
||||
|
||||
if System.get_env("DOCKER", "false") == "false" && File.exists?("./config/test.secret.exs") do
|
||||
import_config "test.secret.exs"
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: "3.2"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
|
@ -1,14 +1,13 @@
|
||||
version: "3.2"
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
postgres:
|
||||
container_name: mobilizon_db
|
||||
restart: unless-stopped
|
||||
image: postgis/postgis
|
||||
image: postgis/postgis:13-3.0
|
||||
environment:
|
||||
- POSTGRES_USER
|
||||
- POSTGRES_PASSWORD
|
||||
- POSTGRES_DB
|
||||
- POSTGRES_PORT
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: mobilizon_dev
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
api:
|
||||
@ -18,24 +17,29 @@ services:
|
||||
volumes:
|
||||
- ".:/app"
|
||||
ports:
|
||||
- 4000:4000
|
||||
- "4000:4000"
|
||||
depends_on:
|
||||
- postgres
|
||||
environment:
|
||||
MIX_ENV: "dev"
|
||||
DOCKER: "true"
|
||||
MOBILIZON_INSTANCE_NAME: My Mobilizon Instance
|
||||
MOBILIZON_INSTANCE_HOST: localhost
|
||||
MOBILIZON_INSTANCE_HOST_PORT: 4000
|
||||
MOBILIZON_INSTANCE_PORT: 4000
|
||||
MOBILIZON_INSTANCE_HOST: mobilizon.me
|
||||
MOBILIZON_INSTANCE_EMAIL: noreply@mobilizon.me
|
||||
MOBILIZON_INSTANCE_REGISTRATIONS_OPEN: "true"
|
||||
MOBILIZON_DATABASE_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
MOBILIZON_DATABASE_USERNAME: ${POSTGRES_USER}
|
||||
MOBILIZON_DATABASE_DBNAME: ${POSTGRES_DB}
|
||||
MOBILIZON_DATABASE_PASSWORD: postgres
|
||||
MOBILIZON_DATABASE_USERNAME: postgres
|
||||
MOBILIZON_DATABASE_DBNAME: mobilizon_dev
|
||||
MOBILIZON_DATABASE_HOST: postgres
|
||||
MOBILIZON_DATABASE_PORT: ${POSTGRES_PORT}
|
||||
command: sh -c "mix phx.server"
|
||||
command: >
|
||||
sh -c "cd js &&
|
||||
yarn install &&
|
||||
cd ../ &&
|
||||
mix deps.get &&
|
||||
mix compile &&
|
||||
mix ecto.create &&
|
||||
mix ecto.migrate &&
|
||||
mix phx.server"
|
||||
volumes:
|
||||
pgdata:
|
||||
.:
|
||||
|
@ -1,44 +0,0 @@
|
||||
FROM elixir as build
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
ENV MIX_ENV prod
|
||||
# ENV LANG en_US.UTF-8
|
||||
ARG APP_ASSET
|
||||
|
||||
# Set the right versions
|
||||
ENV ELIXIR_VERSION latest
|
||||
ENV ERLANG_VERSION latest
|
||||
ENV NODE_VERSION 16
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update -yq && apt-get install -yq build-essential cmake postgresql-client git curl gnupg unzip exiftool webp imagemagick gifsicle
|
||||
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# # Install Node & yarn
|
||||
# RUN curl -sL https://deb.nodesource.com/setup_16.x | bash && apt-get install nodejs -yq
|
||||
# RUN npm install -g yarn
|
||||
|
||||
# Install build tools
|
||||
RUN source /root/.bashrc && \
|
||||
mix local.rebar --force && \
|
||||
mix local.hex -if-missing --force
|
||||
|
||||
RUN mkdir /mobilizon
|
||||
COPY ./ /mobilizon
|
||||
WORKDIR /mobilizon
|
||||
|
||||
# # Build front-end
|
||||
# RUN yarn --cwd "js" install --frozen-lockfile
|
||||
# RUN yarn --cwd "js" run build
|
||||
|
||||
# Elixir release
|
||||
RUN source /root/.bashrc && \
|
||||
mix deps.get --only prod && \
|
||||
mix compile && \
|
||||
mix phx.digest.clean --all && \
|
||||
mix release --path release/mobilizon && \
|
||||
cd release/mobilizon && \
|
||||
ln -s lib/mobilizon-*/priv priv && \
|
||||
cd ../../
|
||||
|
||||
# Make a release archive
|
||||
RUN tar -zcf /mobilizon/${APP_ASSET} -C release mobilizon
|
@ -1 +0,0 @@
|
||||
Contains the Dockerfile used to generate multi-arch Elixir releases
|
@ -1,18 +1,14 @@
|
||||
# First build the application assets
|
||||
FROM node:16-alpine as assets
|
||||
FROM node:alpine as assets
|
||||
|
||||
RUN apk add --no-cache python build-base libwebp-tools bash imagemagick ncurses
|
||||
|
||||
RUN apk add --no-cache python3 build-base libwebp-tools bash imagemagick ncurses
|
||||
WORKDIR /build
|
||||
COPY js .
|
||||
|
||||
ENV CYPRESS_INSTALL_BINARY 0
|
||||
|
||||
# Network timeout because it's slow when cross-compiling
|
||||
RUN yarn install --network-timeout 100000 \
|
||||
RUN yarn install \
|
||||
&& yarn run build
|
||||
|
||||
# Then, build the application binary
|
||||
FROM elixir:1.13-alpine AS builder
|
||||
FROM elixir:alpine AS builder
|
||||
|
||||
RUN apk add --no-cache build-base git cmake
|
||||
|
||||
@ -24,48 +20,25 @@ RUN mix local.hex --force \
|
||||
|
||||
COPY lib ./lib
|
||||
COPY priv ./priv
|
||||
COPY config/config.exs config/prod.exs ./config/
|
||||
COPY config/docker.exs ./config/runtime.exs
|
||||
COPY config ./config
|
||||
COPY rel ./rel
|
||||
COPY support ./support
|
||||
COPY docker/production/releases.exs ./config/
|
||||
COPY --from=assets ./priv/static ./priv/static
|
||||
|
||||
RUN mix phx.digest.clean --all \
|
||||
RUN mix phx.digest \
|
||||
&& mix release
|
||||
|
||||
# Finally setup the app
|
||||
FROM alpine
|
||||
|
||||
ARG BUILD_DATE
|
||||
ARG VCS_REF
|
||||
RUN apk add --no-cache openssl ncurses-libs file postgresql-client
|
||||
|
||||
LABEL org.opencontainers.image.title="mobilizon" \
|
||||
org.opencontainers.image.description="Mobilizon for Docker" \
|
||||
org.opencontainers.image.vendor="joinmobilizon.org" \
|
||||
org.opencontainers.image.documentation="https://docs.joinmobilizon.org" \
|
||||
org.opencontainers.image.licenses="AGPL-3.0" \
|
||||
org.opencontainers.image.source="https://framagit.org/framasoft/mobilizon" \
|
||||
org.opencontainers.image.url="https://joinmobilizon.org" \
|
||||
org.opencontainers.image.revision=$VCS_REF \
|
||||
org.opencontainers.image.created=$BUILD_DATE
|
||||
|
||||
RUN apk add --no-cache curl openssl ca-certificates ncurses-libs file postgresql-client libgcc libstdc++ imagemagick python3 py3-pip py3-pillow py3-cffi py3-brotli gcc g++ musl-dev python3-dev pango libxslt-dev ttf-cantarell
|
||||
RUN pip install weasyprint pyexcel-ods3
|
||||
|
||||
RUN mkdir -p /var/lib/mobilizon/uploads && chown nobody:nobody /var/lib/mobilizon/uploads
|
||||
RUN mkdir -p /var/lib/mobilizon/uploads/exports/{csv,pdf,ods} && chown -R nobody:nobody /var/lib/mobilizon/uploads/exports
|
||||
RUN mkdir -p /var/lib/mobilizon/timezones
|
||||
RUN curl -L 'https://packages.joinmobilizon.org/tz_world/timezones-geodata.dets' -o /var/lib/mobilizon/timezones/timezones-geodata.dets
|
||||
RUN chown nobody:nobody /var/lib/mobilizon/timezones
|
||||
RUN mkdir -p /etc/mobilizon && chown nobody:nobody /etc/mobilizon
|
||||
RUN mkdir -p /app/uploads && chown nobody:nobody /app/uploads
|
||||
|
||||
USER nobody
|
||||
EXPOSE 4000
|
||||
|
||||
ENV MOBILIZON_DOCKER=true
|
||||
|
||||
COPY --from=builder --chown=nobody:nobody _build/prod/rel/mobilizon ./
|
||||
RUN cp /releases/*/runtime.exs /etc/mobilizon/config.exs
|
||||
COPY docker/production/docker-entrypoint.sh ./
|
||||
|
||||
ENTRYPOINT ["./docker-entrypoint.sh"]
|
||||
|
@ -2,22 +2,11 @@
|
||||
|
||||
import Config
|
||||
|
||||
listen_ip = System.get_env("MOBILIZON_INSTANCE_LISTEN_IP", "0.0.0.0")
|
||||
|
||||
listen_ip =
|
||||
case listen_ip |> to_charlist() |> :inet.parse_address() do
|
||||
{:ok, listen_ip} -> listen_ip
|
||||
_ -> raise "MOBILIZON_INSTANCE_LISTEN_IP does not match the expected IP format."
|
||||
end
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Endpoint,
|
||||
server: true,
|
||||
url: [host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.lan")],
|
||||
http: [
|
||||
port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_PORT", "4000")),
|
||||
ip: listen_ip
|
||||
],
|
||||
secret_key_base: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY_BASE", "changethis")
|
||||
server: true,
|
||||
url: [host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.lan")],
|
||||
http: [port: 4000],
|
||||
secret_key_base: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY_BASE", "changethis")
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Auth.Guardian,
|
||||
secret_key: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY", "changethis")
|
||||
@ -33,6 +22,11 @@ config :mobilizon, :instance,
|
||||
email_from: System.get_env("MOBILIZON_INSTANCE_EMAIL", "noreply@mobilizon.lan"),
|
||||
email_reply_to: System.get_env("MOBILIZON_REPLY_EMAIL", "noreply@mobilizon.lan")
|
||||
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local,
|
||||
uploads: System.get_env("MOBILIZON_UPLOADS", "/app/uploads")
|
||||
|
||||
|
||||
config :mobilizon, Mobilizon.Storage.Repo,
|
||||
adapter: Ecto.Adapters.Postgres,
|
||||
username: System.get_env("MOBILIZON_DATABASE_USERNAME", "username"),
|
||||
@ -43,8 +37,9 @@ config :mobilizon, Mobilizon.Storage.Repo,
|
||||
pool_size: 10
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Email.Mailer,
|
||||
adapter: Swoosh.Adapters.SMTP,
|
||||
relay: System.get_env("MOBILIZON_SMTP_SERVER", "localhost"),
|
||||
adapter: Bamboo.SMTPAdapter,
|
||||
server: System.get_env("MOBILIZON_SMTP_SERVER", "localhost"),
|
||||
hostname: System.get_env("MOBILIZON_SMTP_HOSTNAME", "localhost"),
|
||||
port: System.get_env("MOBILIZON_SMTP_PORT", "25"),
|
||||
username: System.get_env("MOBILIZON_SMTP_USERNAME", nil),
|
||||
password: System.get_env("MOBILIZON_SMTP_PASSWORD", nil),
|
||||
@ -54,26 +49,3 @@ config :mobilizon, Mobilizon.Web.Email.Mailer,
|
||||
retries: 1,
|
||||
no_mx_lookups: false,
|
||||
auth: :if_available
|
||||
|
||||
config :geolix,
|
||||
databases: [
|
||||
%{
|
||||
id: :city,
|
||||
adapter: Geolix.Adapter.MMDB2,
|
||||
source: "/var/lib/mobilizon/geo_db/GeoLite2-City.mmdb"
|
||||
}
|
||||
]
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local,
|
||||
uploads: System.get_env("MOBILIZON_UPLOADS", "/var/lib/mobilizon/uploads")
|
||||
|
||||
config :mobilizon, :exports,
|
||||
path: System.get_env("MOBILIZON_UPLOADS_EXPORTS", "/var/lib/mobilizon/uploads/exports"),
|
||||
formats: [
|
||||
Mobilizon.Service.Export.Participants.CSV,
|
||||
Mobilizon.Service.Export.Participants.PDF,
|
||||
Mobilizon.Service.Export.Participants.ODS
|
||||
]
|
||||
|
||||
config :tz_world,
|
||||
data_dir: System.get_env("MOBILIZON_TIMEZONES_DIR", "/var/lib/mobilizon/timezones")
|
@ -1,11 +1,10 @@
|
||||
FROM elixir:latest
|
||||
LABEL maintainer="Thomas Citharel <tcit@tcit.fr>"
|
||||
|
||||
ENV REFRESHED_AT=2022-04-06
|
||||
RUN apt-get update -yq && apt-get install -yq build-essential inotify-tools postgresql-client git curl gnupg xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 cmake exiftool python3-pip python3-setuptools
|
||||
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash && apt-get install nodejs -yq
|
||||
ENV REFRESHED_AT=2020-10-22
|
||||
RUN apt-get update -yq && apt-get install -yq build-essential inotify-tools postgresql-client git curl gnupg xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 cmake exiftool
|
||||
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash && apt-get install nodejs -yq
|
||||
RUN npm install -g yarn wait-on
|
||||
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
RUN mix local.hex --force && mix local.rebar --force
|
||||
RUN pip3 install -Iv weasyprint pyexcel_ods3
|
||||
RUN curl https://dbip.mirror.framasoft.org/files/dbip-city-lite-latest.mmdb --output GeoLite2-City.mmdb -s && mkdir -p /usr/share/GeoIP && mv GeoLite2-City.mmdb /usr/share/GeoIP/
|
||||
|
@ -1 +0,0 @@
|
||||
Contains the Dockerfile for the image used to run the tests
|
@ -1 +1,3 @@
|
||||
> 0.25% and last 2 versions, not dead, not ie 11, not op_mini all, Firefox ESR
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
|
@ -8,8 +8,9 @@ module.exports = {
|
||||
extends: [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended",
|
||||
"@vue/prettier",
|
||||
"@vue/typescript/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"@vue/prettier/@typescript-eslint",
|
||||
],
|
||||
|
||||
plugins: ["prettier"],
|
||||
@ -29,6 +30,7 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"cypress/no-unnecessary-waiting": "off",
|
||||
"vue/max-len": [
|
||||
"off",
|
||||
{
|
||||
|
1
js/.gitignore
vendored
@ -23,4 +23,3 @@ yarn-error.log*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
.yarn
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"trailingComma": "es5",
|
||||
"semi": true,
|
||||
"singleQuote": false,
|
||||
"bracketSpacing": true
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
nodeLinker: node-modules
|
||||
|
||||
#yarnPath: .yarn/releases/yarn-3.1.1.cjs
|
@ -4,9 +4,9 @@ module.exports = {
|
||||
service: {
|
||||
name: "Mobilizon",
|
||||
// URL to the GraphQL API
|
||||
localSchemaFile: "./schema.graphql",
|
||||
url: "http://localhost:4000/api",
|
||||
},
|
||||
// Files processed by the extension
|
||||
includes: ["js/src/**/*.vue", "js/src/**/*.js"],
|
||||
includes: ["src/**/*.vue", "src/**/*.js"],
|
||||
},
|
||||
};
|
@ -5,41 +5,34 @@
|
||||
"kind": "INTERFACE",
|
||||
"name": "ActionLogObject",
|
||||
"possibleTypes": [
|
||||
{ "name": "Comment" },
|
||||
{ "name": "Event" },
|
||||
{ "name": "Group" },
|
||||
{ "name": "Person" },
|
||||
{ "name": "Report" },
|
||||
{ "name": "ReportNote" },
|
||||
{ "name": "User" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "INTERFACE",
|
||||
"name": "ActivityObject",
|
||||
"possibleTypes": [
|
||||
{ "name": "Comment" },
|
||||
{ "name": "Discussion" },
|
||||
{ "name": "Event" },
|
||||
{ "name": "Group" },
|
||||
{ "name": "Member" },
|
||||
{ "name": "Post" },
|
||||
{ "name": "Resource" }
|
||||
{
|
||||
"name": "Event"
|
||||
},
|
||||
{
|
||||
"name": "Comment"
|
||||
},
|
||||
{
|
||||
"name": "Report"
|
||||
},
|
||||
{
|
||||
"name": "ReportNote"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "INTERFACE",
|
||||
"name": "Actor",
|
||||
"possibleTypes": [
|
||||
{ "name": "Application" },
|
||||
{ "name": "Group" },
|
||||
{ "name": "Person" }
|
||||
{
|
||||
"name": "Person"
|
||||
},
|
||||
{
|
||||
"name": "Group"
|
||||
},
|
||||
{
|
||||
"name": "Application"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "INTERFACE",
|
||||
"name": "Interactable",
|
||||
"possibleTypes": [{ "name": "Event" }, { "name": "Group" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ module.exports = {
|
||||
"!get_union_json.ts",
|
||||
],
|
||||
coverageReporters: ["html", "text", "text-summary"],
|
||||
reporters: ["default", "jest-junit"],
|
||||
// The following should fix the issue with svgs and ?inline loader (see Logo.vue), but doesn't work
|
||||
//
|
||||
// transform: {
|
||||
|
142
js/package.json
@ -1,130 +1,100 @@
|
||||
{
|
||||
"name": "mobilizon",
|
||||
"version": "2.1.0",
|
||||
"version": "1.0.3",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build:assets": "vue-cli-service build --modern",
|
||||
"build:pictures": "bash ./scripts/build/pictures.sh",
|
||||
"build": "yarn run build:assets && yarn run build:pictures",
|
||||
"test:unit": "LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=UTC vue-cli-service test:unit",
|
||||
"test:unit": "LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 vue-cli-service test:unit",
|
||||
"test:e2e": "vue-cli-service test:e2e",
|
||||
"lint": "vue-cli-service lint",
|
||||
"build:assets": "vue-cli-service build --report",
|
||||
"build:pictures": "bash ./scripts/build/pictures.sh"
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@absinthe/socket": "^0.2.1",
|
||||
"@absinthe/socket-apollo-link": "^0.2.1",
|
||||
"@apollo/client": "^3.3.16",
|
||||
"@mdi/font": "^6.1.95",
|
||||
"@sentry/tracing": "^6.16.1",
|
||||
"@sentry/vue": "^6.16.1",
|
||||
"@tailwindcss/line-clamp": "^0.4.0",
|
||||
"@tiptap/core": "^2.0.0-beta.41",
|
||||
"@tiptap/extension-blockquote": "^2.0.0-beta.25",
|
||||
"@tiptap/extension-bold": "^2.0.0-beta.24",
|
||||
"@tiptap/extension-bubble-menu": "^2.0.0-beta.9",
|
||||
"@tiptap/extension-bullet-list": "^2.0.0-beta.23",
|
||||
"@tiptap/extension-document": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-dropcursor": "^2.0.0-beta.25",
|
||||
"@tiptap/extension-gapcursor": "^2.0.0-beta.33",
|
||||
"@tiptap/extension-heading": "^2.0.0-beta.23",
|
||||
"@tiptap/extension-history": "^2.0.0-beta.21",
|
||||
"@tiptap/extension-image": "^2.0.0-beta.6",
|
||||
"@tiptap/extension-italic": "^2.0.0-beta.24",
|
||||
"@tiptap/extension-link": "^2.0.0-beta.8",
|
||||
"@tiptap/extension-list-item": "^2.0.0-beta.19",
|
||||
"@tiptap/extension-mention": "^2.0.0-beta.42",
|
||||
"@tiptap/extension-ordered-list": "^2.0.0-beta.24",
|
||||
"@tiptap/extension-paragraph": "^2.0.0-beta.22",
|
||||
"@tiptap/extension-strike": "^2.0.0-beta.26",
|
||||
"@tiptap/extension-text": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-underline": "^2.0.0-beta.7",
|
||||
"@tiptap/vue-2": "^2.0.0-beta.21",
|
||||
"@vue-a11y/announcer": "^2.1.0",
|
||||
"@vue-a11y/skip-to": "^2.1.2",
|
||||
"@vue/apollo-option": "4.0.0-alpha.11",
|
||||
"@mdi/font": "^5.0.45",
|
||||
"apollo-absinthe-upload-link": "^1.5.0",
|
||||
"autoprefixer": "^10",
|
||||
"blurhash": "^1.1.3",
|
||||
"apollo-cache": "^1.3.5",
|
||||
"apollo-cache-inmemory": "^1.6.6",
|
||||
"apollo-client": "^2.6.10",
|
||||
"apollo-link": "^1.2.14",
|
||||
"apollo-link-error": "^1.1.13",
|
||||
"apollo-link-http": "^1.5.17",
|
||||
"apollo-link-ws": "^1.0.19",
|
||||
"apollo-utilities": "^1.3.2",
|
||||
"buefy": "^0.9.0",
|
||||
"bulma-divider": "^0.2.0",
|
||||
"core-js": "^3.6.4",
|
||||
"date-fns": "^2.16.0",
|
||||
"date-fns-tz": "^1.1.6",
|
||||
"graphql": "^16.0.0",
|
||||
"eslint-plugin-cypress": "^2.10.3",
|
||||
"graphql": "^15.0.0",
|
||||
"graphql-tag": "^2.10.3",
|
||||
"intersection-observer": "^0.12.0",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"leaflet": "^1.4.0",
|
||||
"leaflet.locatecontrol": "^0.76.0",
|
||||
"leaflet.locatecontrol": "^0.72.0",
|
||||
"lodash": "^4.17.11",
|
||||
"ngeohash": "^0.6.3",
|
||||
"p-debounce": "^4.0.0",
|
||||
"phoenix": "^1.6",
|
||||
"postcss": "^8",
|
||||
"register-service-worker": "^1.7.2",
|
||||
"sanitize-html": "^2.5.3",
|
||||
"tailwindcss": "^3",
|
||||
"phoenix": "^1.4.11",
|
||||
"register-service-worker": "^1.7.1",
|
||||
"tippy.js": "^6.2.3",
|
||||
"tiptap": "^1.26.0",
|
||||
"tiptap-extensions": "^1.29.1",
|
||||
"unfetch": "^4.2.0",
|
||||
"v-tooltip": "^2.1.3",
|
||||
"v-tooltip": "2.0.2",
|
||||
"vue": "^2.6.11",
|
||||
"vue-apollo": "^3.0.3",
|
||||
"vue-class-component": "^7.2.3",
|
||||
"vue-i18n": "^8.14.0",
|
||||
"vue-matomo": "^4.1.0",
|
||||
"vue-meta": "^2.3.1",
|
||||
"vue-plausible": "^1.3.1",
|
||||
"vue-property-decorator": "^9.0.0",
|
||||
"vue-router": "^3.1.6",
|
||||
"vue-scrollto": "^2.17.1",
|
||||
"vue2-leaflet": "^2.0.3",
|
||||
"vuedraggable": "^2.24.3"
|
||||
"vuedraggable": "2.23.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rushstack/eslint-patch": "^1.1.0",
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/jest": "^26.0.18",
|
||||
"@types/leaflet": "^1.5.2",
|
||||
"@types/leaflet.locatecontrol": "^0.74",
|
||||
"@types/leaflet.locatecontrol": "^0.60.7",
|
||||
"@types/lodash": "^4.14.141",
|
||||
"@types/ngeohash": "^0.6.2",
|
||||
"@types/phoenix": "^1.5.2",
|
||||
"@types/prosemirror-inputrules": "^1.0.2",
|
||||
"@types/prosemirror-model": "^1.7.2",
|
||||
"@types/prosemirror-state": "^1.2.4",
|
||||
"@types/prosemirror-view": "^1.11.4",
|
||||
"@types/sanitize-html": "^2.5.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.3.0",
|
||||
"@typescript-eslint/parser": "^5.3.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.4",
|
||||
"@vue/cli-plugin-eslint": "~5.0.4",
|
||||
"@vue/cli-plugin-pwa": "~5.0.4",
|
||||
"@vue/cli-plugin-router": "~5.0.4",
|
||||
"@vue/cli-plugin-typescript": "~5.0.4",
|
||||
"@vue/cli-plugin-unit-jest": "~5.0.4",
|
||||
"@vue/cli-service": "~5.0.4",
|
||||
"@vue/eslint-config-typescript": "^10.0.0",
|
||||
"@types/vuedraggable": "^2.23.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.0.1",
|
||||
"@typescript-eslint/parser": "^4.0.1",
|
||||
"@vue/cli-plugin-babel": "~4.5.9",
|
||||
"@vue/cli-plugin-e2e-cypress": "~4.5.9",
|
||||
"@vue/cli-plugin-eslint": "~4.5.9",
|
||||
"@vue/cli-plugin-pwa": "~4.5.9",
|
||||
"@vue/cli-plugin-router": "~4.5.9",
|
||||
"@vue/cli-plugin-typescript": "~4.5.9",
|
||||
"@vue/cli-plugin-unit-jest": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.9",
|
||||
"@vue/eslint-config-prettier": "^6.0.0",
|
||||
"@vue/eslint-config-typescript": "^7.0.0",
|
||||
"@vue/test-utils": "^1.1.0",
|
||||
"@vue/vue2-jest": "^27.0.0-alpha.3",
|
||||
"@vue/vue3-jest": "^27.0.0-alpha.1",
|
||||
"eslint": "^8.2.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"flush-promises": "^1.0.2",
|
||||
"jest": "^27.1.0",
|
||||
"jest-junit": "^13.0.0",
|
||||
"mock-apollo-client": "^1.1.0",
|
||||
"prettier": "^2.2.1",
|
||||
"prettier-eslint": "^14.0.0",
|
||||
"sass": "^1.34.1",
|
||||
"sass-loader": "^12.0.0",
|
||||
"ts-jest": "27",
|
||||
"typescript": "~4.5.5",
|
||||
"vue-cli-plugin-tailwind": "~3.0.0",
|
||||
"vue-i18n-extract": "^2.0.4",
|
||||
"eslint": "^7.7.0",
|
||||
"eslint-config-prettier": "^7.0.0",
|
||||
"eslint-plugin-prettier": "^3.1.3",
|
||||
"eslint-plugin-vue": "^7.0.0",
|
||||
"mock-apollo-client": "^0.4",
|
||||
"prettier": "2.2.1",
|
||||
"prettier-eslint": "^12.0.0",
|
||||
"sass": "^1.29.0",
|
||||
"sass-loader": "^10.0.1",
|
||||
"typescript": "~4.1.2",
|
||||
"vue-cli-plugin-svg": "~0.1.3",
|
||||
"vue-i18n-extract": "^1.0.2",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"webpack-cli": "^4.7.0"
|
||||
"webpack-cli": "^3.3"
|
||||
},
|
||||
"packageManager": "yarn@3.1.1"
|
||||
"resolutions": {
|
||||
"prosemirror-model": "1.9.1",
|
||||
"prosemirror-state": "1.3.3"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 4.2 KiB |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="742.753" height="742.753" viewBox="0 0 557.065 557.065"><path style="stroke:none;fill-rule:nonzero;fill:#636363;fill-opacity:1" d="M135.848 206.352c-4.887 9.359-12.715 17.152-22.098 21.996L235.066 350.14l29.25-14.825zm160.023 160.64-29.25 14.824 61.473 61.711c4.886-9.359 12.719-17.156 22.105-21.996zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#878787;fill-opacity:1" d="m436.234 254.543-68.68 34.809 5.063 32.39 77.711-39.383c-7.39-7.543-12.387-17.398-14.094-27.816zM327.68 309.559l-162.39 82.3c7.39 7.54 12.386 17.395 14.093 27.817l153.363-77.727zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#636363;fill-opacity:1" d="m275.457 106.828-78.36 152.977 23.133 23.226 82.97-161.969c-10.41-1.761-20.243-6.804-27.743-14.234zm-98.742 192.766-39.692 77.488c10.41 1.758 20.239 6.805 27.743 14.23l35.086-68.496zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#5c5c5c;fill-opacity:1" d="M113.074 228.688a51.922 51.922 0 0 1-25.808 5.398 52.012 52.012 0 0 1-4.989-.524l23.176 148.247a51.976 51.976 0 0 1 25.813-5.395c1.668.094 3.332.266 4.984.52zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#575757;fill-opacity:1" d="M179.508 420.41c.527 3.438.71 6.93.539 10.406a51.888 51.888 0 0 1-5.45 20.387l148.22 23.781a51.814 51.814 0 0 1-.54-10.406 51.852 51.852 0 0 1 5.45-20.383zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#878787;fill-opacity:1" d="m450.852 282.898-68.414 133.563c10.41 1.762 20.242 6.805 27.742 14.238l68.414-133.562c-10.41-1.762-20.242-6.805-27.742-14.239zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#ccc;fill-opacity:1" d="M357.543 93.996c-4.887 9.363-12.719 17.156-22.106 22l105.95 106.36c4.886-9.36 12.718-17.157 22.101-22zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#8f8f8f;fill-opacity:1" d="m260.84 78.473-133.93 67.875c7.39 7.539 12.383 17.394 14.094 27.812l133.93-67.875c-7.391-7.539-12.387-17.394-14.094-27.812zm74.355 37.648a52.01 52.01 0 0 1-26.238 5.61 51.5 51.5 0 0 1-4.52-.473l11.864 75.969 32.37 5.191zm-12 125.27 28.051 179.613a51.909 51.909 0 0 1 25.434-5.211c1.812.105 3.617.3 5.406.594l-26.52-169.805zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#ababab;fill-opacity:1" d="M141.098 174.73a51.84 51.84 0 0 1 .57 10.575 51.878 51.878 0 0 1-5.371 20.234l76.027 12.211 14.942-29.18zm130.304 20.926-14.945 29.184 179.633 28.85a51.828 51.828 0 0 1-.52-10.289 51.863 51.863 0 0 1 5.512-20.492zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#c2c2c2;fill-opacity:.995968" d="M358.672 72.691c-1.414 25.907-23.555 45.762-49.461 44.348-25.902-1.41-45.758-23.55-44.348-49.457 1.414-25.902 23.555-45.758 49.461-44.348 25.903 1.414 45.758 23.555 44.348 49.457zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#b3b3b3;fill-opacity:.995968" d="M534.066 248.766c-1.41 25.906-23.554 45.761-49.457 44.347-25.906-1.41-45.761-23.55-44.347-49.457 1.41-25.902 23.55-45.758 49.457-44.347 25.902 1.41 45.758 23.554 44.347 49.457zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#7d7d7d;fill-opacity:.995968" d="M420.773 469.941c-1.414 25.903-23.554 45.758-49.457 44.348-25.906-1.41-45.761-23.555-44.351-49.457 1.414-25.902 23.555-45.758 49.46-44.348 25.903 1.41 45.759 23.555 44.348 49.457zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#4a4a4a;fill-opacity:.995968" d="M175.355 430.563c-1.41 25.902-23.55 45.757-49.457 44.347-25.902-1.414-45.757-23.555-44.347-49.457 1.414-25.906 23.554-45.762 49.457-44.351 25.906 1.414 45.762 23.554 44.347 49.46zm0 0"/><path style="stroke:none;fill-rule:nonzero;fill:#4d4d4d;fill-opacity:.995968" d="M136.977 185.047c-1.41 25.902-23.555 45.758-49.457 44.348-25.907-1.41-45.758-23.555-44.348-49.458 1.41-25.902 23.555-45.757 49.457-44.347 25.902 1.41 45.758 23.555 44.348 49.457zm0 0"/></svg>
|
Before Width: | Height: | Size: 3.7 KiB |
BIN
js/public/img/icons/android-chrome-192x192 (copie).png
Normal file
After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 791 B After Width: | Height: | Size: 507 B |
Before Width: | Height: | Size: 1015 B After Width: | Height: | Size: 668 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"><path style="opacity:1;fill:#fea72b;fill-opacity:1;stroke:none;stroke-opacity:1" d="M-5.801-6.164h72.69v72.871h-72.69z"/><g data-name="Calque 2"><g data-name="header"><path d="M26.58 27.06q0 8-4.26 12.3a12.21 12.21 0 0 1-9 3.42 12.21 12.21 0 0 1-9-3.42Q0 35.1 0 27.06q0-8.04 4.26-12.3a12.21 12.21 0 0 1 9-3.42 12.21 12.21 0 0 1 9 3.42q4.32 4.24 4.32 12.3zM13.29 17q-5.67 0-5.67 10.06t5.67 10.08q5.71 0 5.71-10.08T13.29 17z" style="fill:#3a384c;fill-opacity:1" transform="translate(14.627 5.256) scale(1.15671)"/><path d="M9 6.78a7.37 7.37 0 0 1-.6-3 7.37 7.37 0 0 1 .6-3A8.09 8.09 0 0 1 12.83 0a7.05 7.05 0 0 1 3.69.84 7.37 7.37 0 0 1 .6 3 7.37 7.37 0 0 1-.6 3 7.46 7.46 0 0 1-3.87.84A6.49 6.49 0 0 1 9 6.78z" style="fill:#fff" transform="translate(14.627 5.256) scale(1.15671)"/></g></g></svg>
|
Before Width: | Height: | Size: 857 B |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 668 B After Width: | Height: | Size: 668 B |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 6.2 KiB |
BIN
js/public/img/icons/icon-384x384.png
Normal file
After Width: | Height: | Size: 668 B |
Before Width: | Height: | Size: 1.8 KiB |
BIN
js/public/img/icons/icon-512x512.png
Normal file
After Width: | Height: | Size: 668 B |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 668 B |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 668 B |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 507 B |
@ -1 +1,149 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60"><path style="opacity:1;fill:#fea72b;fill-opacity:1;stroke:none;stroke-opacity:1" d="M-5.801-6.164h72.69v72.871h-72.69z"/><g data-name="Calque 2"><g data-name="header"><path d="M26.58 27.06q0 8-4.26 12.3a12.21 12.21 0 0 1-9 3.42 12.21 12.21 0 0 1-9-3.42Q0 35.1 0 27.06q0-8.04 4.26-12.3a12.21 12.21 0 0 1 9-3.42 12.21 12.21 0 0 1 9 3.42q4.32 4.24 4.32 12.3zM13.29 17q-5.67 0-5.67 10.06t5.67 10.08q5.71 0 5.71-10.08T13.29 17z" style="fill:#3a384c;fill-opacity:1" transform="translate(14.627 5.256) scale(1.15671)"/><path d="M9 6.78a7.37 7.37 0 0 1-.6-3 7.37 7.37 0 0 1 .6-3A8.09 8.09 0 0 1 12.83 0a7.05 7.05 0 0 1 3.69.84 7.37 7.37 0 0 1 .6 3 7.37 7.37 0 0 1-.6 3 7.46 7.46 0 0 1-3.87.84A6.49 6.49 0 0 1 9 6.78z" style="fill:#fff" transform="translate(14.627 5.256) scale(1.15671)"/></g></g></svg>
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="16.000000pt" height="16.000000pt" viewBox="0 0 16.000000 16.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,16.000000) scale(0.000320,-0.000320)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M18 46618 c45 -75 122 -207 122 -211 0 -2 25 -45 55 -95 30 -50 55
|
||||
-96 55 -102 0 -5 5 -10 10 -10 6 0 10 -4 10 -9 0 -5 73 -135 161 -288 89 -153
|
||||
173 -298 187 -323 14 -25 32 -57 41 -72 88 -149 187 -324 189 -335 2 -7 8 -13
|
||||
13 -13 5 0 9 -4 9 -10 0 -5 46 -89 103 -187 175 -302 490 -846 507 -876 8 -16
|
||||
20 -36 25 -45 28 -46 290 -498 339 -585 13 -23 74 -129 136 -236 61 -107 123
|
||||
-215 137 -240 14 -25 29 -50 33 -56 5 -5 23 -37 40 -70 18 -33 38 -67 44 -75
|
||||
11 -16 21 -33 63 -109 14 -25 29 -50 33 -56 4 -5 21 -35 38 -65 55 -100 261
|
||||
-455 269 -465 4 -5 14 -21 20 -35 15 -29 41 -75 103 -180 24 -41 52 -88 60
|
||||
-105 9 -16 57 -100 107 -185 112 -193 362 -626 380 -660 8 -14 23 -38 33 -55
|
||||
11 -16 23 -37 27 -45 4 -8 26 -46 48 -85 23 -38 53 -90 67 -115 46 -81 64
|
||||
-113 178 -310 62 -107 121 -210 132 -227 37 -67 56 -99 85 -148 16 -27 32 -57
|
||||
36 -65 4 -8 15 -27 25 -42 9 -15 53 -89 96 -165 44 -76 177 -307 296 -513 120
|
||||
-206 268 -463 330 -570 131 -227 117 -203 200 -348 36 -62 73 -125 82 -140 10
|
||||
-15 21 -34 25 -42 4 -8 20 -37 36 -65 17 -27 38 -65 48 -82 49 -85 64 -111 87
|
||||
-153 13 -25 28 -49 32 -55 4 -5 78 -134 165 -285 87 -151 166 -288 176 -305
|
||||
10 -16 26 -43 35 -59 9 -17 125 -217 257 -445 132 -229 253 -441 270 -471 17
|
||||
-30 45 -79 64 -108 18 -29 33 -54 33 -57 0 -2 20 -37 44 -77 24 -40 123 -212
|
||||
221 -383 97 -170 190 -330 205 -355 16 -25 39 -65 53 -90 13 -25 81 -144 152
|
||||
-265 70 -121 137 -238 150 -260 12 -22 37 -65 55 -95 18 -30 43 -73 55 -95 12
|
||||
-22 48 -85 80 -140 77 -132 163 -280 190 -330 13 -22 71 -123 130 -225 59
|
||||
-102 116 -199 126 -217 10 -17 29 -50 43 -72 15 -22 26 -43 26 -45 0 -2 27
|
||||
-50 60 -106 33 -56 60 -103 60 -105 0 -2 55 -98 90 -155 8 -14 182 -316 239
|
||||
-414 13 -22 45 -79 72 -124 27 -46 49 -86 49 -89 0 -2 14 -24 30 -48 16 -24
|
||||
30 -46 30 -49 0 -5 74 -135 100 -176 5 -8 24 -42 43 -75 50 -88 58 -101 262
|
||||
-455 104 -179 199 -345 213 -370 14 -25 28 -49 32 -55 4 -5 17 -26 28 -45 10
|
||||
-19 62 -109 114 -200 114 -197 133 -230 170 -295 16 -27 33 -57 38 -65 17 -28
|
||||
96 -165 103 -180 4 -8 16 -28 26 -45 10 -16 77 -131 148 -255 72 -124 181
|
||||
-313 243 -420 62 -107 121 -209 131 -227 35 -62 323 -560 392 -678 38 -66 83
|
||||
-145 100 -175 16 -30 33 -59 37 -65 4 -5 17 -27 29 -47 34 -61 56 -100 90
|
||||
-156 17 -29 31 -55 31 -57 0 -2 17 -32 39 -67 21 -35 134 -229 251 -433 117
|
||||
-203 235 -407 261 -451 27 -45 49 -85 49 -88 0 -4 8 -19 19 -34 15 -21 200
|
||||
-341 309 -533 10 -19 33 -58 51 -87 17 -29 31 -54 31 -56 0 -2 25 -44 55 -94
|
||||
30 -50 55 -95 55 -98 0 -4 6 -15 14 -23 7 -9 27 -41 43 -71 17 -30 170 -297
|
||||
342 -594 171 -296 311 -542 311 -547 0 -5 5 -9 10 -9 6 0 10 -4 10 -10 0 -5
|
||||
22 -47 49 -92 27 -46 58 -99 68 -118 24 -43 81 -140 93 -160 5 -8 66 -114 135
|
||||
-235 69 -121 130 -227 135 -235 12 -21 259 -447 283 -490 10 -19 28 -47 38
|
||||
-62 11 -14 19 -29 19 -32 0 -3 37 -69 83 -148 99 -170 305 -526 337 -583 13
|
||||
-22 31 -53 41 -70 11 -16 22 -37 26 -45 7 -14 82 -146 103 -180 14 -24 181
|
||||
-311 205 -355 13 -22 46 -80 75 -130 29 -49 64 -110 78 -135 14 -25 51 -88 82
|
||||
-140 31 -52 59 -102 63 -110 4 -8 18 -33 31 -55 205 -353 284 -489 309 -535
|
||||
17 -30 45 -78 62 -106 18 -28 36 -60 39 -72 4 -12 12 -22 17 -22 5 0 9 -4 9
|
||||
-10 0 -5 109 -197 241 -427 133 -230 250 -431 259 -448 51 -90 222 -385 280
|
||||
-485 37 -63 78 -135 92 -160 14 -25 67 -117 118 -205 51 -88 101 -175 111
|
||||
-193 34 -58 55 -95 149 -257 51 -88 101 -173 110 -190 9 -16 76 -131 147 -255
|
||||
72 -124 140 -241 151 -260 61 -108 281 -489 355 -615 38 -66 77 -133 87 -150
|
||||
35 -63 91 -161 100 -175 14 -23 99 -169 128 -220 54 -97 135 -235 142 -245 4
|
||||
-5 20 -32 35 -60 26 -48 238 -416 276 -480 10 -16 26 -46 37 -65 30 -53 382
|
||||
-661 403 -695 10 -16 22 -37 26 -45 4 -8 26 -48 50 -88 24 -41 43 -75 43 -77
|
||||
0 -2 22 -40 50 -85 27 -45 50 -84 50 -86 0 -3 38 -69 83 -147 84 -142 302
|
||||
-520 340 -587 10 -19 34 -60 52 -90 18 -30 44 -75 57 -100 14 -25 45 -79 70
|
||||
-120 25 -41 56 -96 70 -121 14 -25 77 -133 138 -240 62 -107 122 -210 132
|
||||
-229 25 -43 310 -535 337 -581 11 -19 26 -45 34 -59 17 -32 238 -414 266 -460
|
||||
11 -19 24 -41 28 -49 3 -7 75 -133 160 -278 84 -146 153 -269 153 -274 0 -5 5
|
||||
-9 10 -9 6 0 10 -4 10 -10 0 -5 82 -150 181 -322 182 -314 201 -346 240 -415
|
||||
12 -21 80 -139 152 -263 71 -124 141 -245 155 -270 14 -25 28 -49 32 -55 6 -8
|
||||
145 -248 220 -380 37 -66 209 -362 229 -395 11 -19 24 -42 28 -49 4 -8 67
|
||||
-118 140 -243 73 -125 133 -230 133 -233 0 -2 15 -28 33 -57 19 -29 47 -78 64
|
||||
-108 17 -30 53 -93 79 -139 53 -90 82 -141 157 -272 82 -142 115 -199 381
|
||||
-659 142 -245 268 -463 281 -485 12 -22 71 -125 132 -230 60 -104 172 -298
|
||||
248 -430 76 -132 146 -253 156 -270 11 -16 22 -36 26 -44 3 -8 30 -54 60 -103
|
||||
29 -49 53 -91 53 -93 0 -3 18 -34 40 -70 22 -36 40 -67 40 -69 0 -2 37 -66 81
|
||||
-142 45 -77 98 -168 119 -204 20 -36 47 -81 58 -100 12 -19 27 -47 33 -62 6
|
||||
-16 15 -28 20 -28 5 0 9 -4 9 -9 0 -6 63 -118 140 -251 77 -133 140 -243 140
|
||||
-245 0 -2 18 -33 41 -70 22 -37 49 -83 60 -101 10 -19 29 -51 40 -71 25 -45
|
||||
109 -189 126 -218 7 -11 17 -29 22 -40 6 -11 22 -38 35 -60 14 -22 37 -62 52
|
||||
-90 14 -27 35 -62 45 -77 11 -14 19 -29 19 -32 0 -3 18 -35 40 -71 22 -36 40
|
||||
-67 40 -69 0 -2 19 -35 42 -72 23 -38 55 -94 72 -124 26 -47 139 -244 171
|
||||
-298 6 -9 21 -36 34 -60 28 -48 37 -51 51 -19 6 12 19 36 29 52 10 17 27 46
|
||||
38 65 11 19 104 181 208 360 103 179 199 345 213 370 14 25 42 74 64 109 21
|
||||
34 38 65 38 67 0 2 18 33 40 69 22 36 40 67 40 69 0 3 177 310 199 346 16 26
|
||||
136 234 140 244 2 5 25 44 52 88 27 44 49 81 49 84 0 2 18 34 40 70 22 36 40
|
||||
67 40 69 0 2 20 36 43 77 35 58 169 289 297 513 9 17 50 86 90 155 40 69 86
|
||||
150 103 180 16 30 35 62 41 70 6 8 16 24 22 35 35 64 72 129 167 293 59 100
|
||||
116 199 127 220 11 20 30 53 41 72 43 72 1070 1850 1121 1940 14 25 65 113
|
||||
113 195 48 83 96 166 107 185 10 19 28 50 38 68 11 18 73 124 137 235 64 111
|
||||
175 303 246 427 71 124 173 299 225 390 52 91 116 202 143 248 27 45 49 85 49
|
||||
89 0 4 6 14 14 22 7 9 28 43 46 76 26 47 251 436 378 655 11 19 29 51 40 70
|
||||
11 19 101 176 201 348 99 172 181 317 181 323 0 5 5 9 10 9 6 0 10 5 10 11 0
|
||||
6 8 23 18 37 11 15 32 52 49 82 16 30 130 228 253 440 122 212 234 405 248
|
||||
430 13 25 39 70 57 100 39 65 69 117 130 225 25 44 50 87 55 95 12 19 78 134
|
||||
220 380 61 107 129 224 150 260 161 277 222 382 246 425 15 28 47 83 71 123
|
||||
24 41 43 78 43 83 0 5 4 9 8 9 4 0 13 12 19 28 7 15 23 45 36 67 66 110 277
|
||||
478 277 483 0 3 6 13 14 21 7 9 27 41 43 71 17 30 45 80 63 110 34 57 375 649
|
||||
394 685 6 11 16 27 22 35 6 8 26 42 44 75 18 33 41 74 51 90 10 17 24 41 32
|
||||
55 54 97 72 128 88 152 11 14 19 28 19 30 0 3 79 141 175 308 96 167 175 305
|
||||
175 308 0 3 6 13 14 21 7 9 26 39 41 66 33 60 276 483 338 587 24 40 46 80 50
|
||||
88 4 8 13 24 20 35 14 23 95 163 125 215 11 19 52 91 92 160 40 69 80 139 90
|
||||
155 9 17 103 179 207 360 105 182 200 346 211 365 103 181 463 802 489 845 7
|
||||
11 15 27 19 35 4 8 29 51 55 95 64 110 828 1433 848 1470 9 17 24 41 33 55 9
|
||||
14 29 48 45 77 15 28 52 93 82 145 30 51 62 107 71 123 17 30 231 398 400 690
|
||||
51 88 103 179 115 202 12 23 26 48 32 55 6 7 24 38 40 68 17 30 61 107 98 170
|
||||
37 63 84 144 103 180 19 36 41 72 48 81 8 8 14 18 14 21 0 4 27 51 59 106 32
|
||||
55 72 124 89 154 16 29 71 125 122 213 51 88 104 180 118 205 13 25 28 50 32
|
||||
55 4 6 17 26 28 45 11 19 45 80 77 135 31 55 66 116 77 135 11 19 88 152 171
|
||||
295 401 694 620 1072 650 1125 11 19 87 152 170 295 83 143 158 273 166 288 9
|
||||
16 21 36 26 45 6 9 31 52 55 96 25 43 54 94 66 115 11 20 95 164 186 321 91
|
||||
157 173 299 182 315 9 17 26 46 37 65 12 19 66 114 121 210 56 96 108 186 117
|
||||
200 8 14 24 40 34 59 24 45 383 664 412 713 5 9 17 29 26 45 15 28 120 210
|
||||
241 419 36 61 68 117 72 125 4 8 12 23 19 34 35 57 245 420 262 453 11 20 35
|
||||
61 53 90 17 29 32 54 32 56 0 3 28 51 62 108 33 57 70 119 80 138 10 19 23 42
|
||||
28 50 5 8 32 53 59 100 27 47 149 258 271 470 122 212 234 405 248 430 30 53
|
||||
62 108 80 135 6 11 15 27 19 35 4 8 85 150 181 315 96 165 187 323 202 350 31
|
||||
56 116 202 130 225 5 8 25 42 43 75 19 33 92 159 162 280 149 257 157 271 202
|
||||
350 19 33 38 67 43 75 9 14 228 392 275 475 12 22 55 96 95 165 40 69 80 139
|
||||
90 155 24 42 202 350 221 383 9 15 27 47 41 72 14 25 75 131 136 236 61 106
|
||||
121 210 134 232 99 172 271 470 279 482 5 8 23 40 40 70 18 30 81 141 142 245
|
||||
60 105 121 210 135 235 14 25 71 124 127 220 56 96 143 247 194 335 51 88 96
|
||||
167 102 175 14 24 180 311 204 355 23 43 340 590 356 615 5 8 50 87 101 175
|
||||
171 301 517 898 582 1008 25 43 46 81 46 83 0 2 12 23 27 47 14 23 40 67 56
|
||||
97 16 30 35 62 42 70 7 8 15 22 18 30 4 8 20 38 37 65 16 28 33 57 37 65 6 12
|
||||
111 196 143 250 5 8 55 95 112 193 57 98 113 195 126 215 12 20 27 46 32 57 6
|
||||
11 14 27 20 35 5 8 76 130 156 270 80 140 165 287 187 325 23 39 52 90 66 115
|
||||
13 25 30 52 37 61 8 8 14 18 14 21 0 4 41 77 92 165 50 87 175 302 276 478
|
||||
101 176 208 360 236 408 28 49 67 117 86 152 19 35 41 70 48 77 6 6 12 15 12
|
||||
19 0 7 124 224 167 291 12 21 23 40 23 42 0 2 21 40 46 83 26 43 55 92 64 109
|
||||
54 95 327 568 354 614 19 30 45 75 59 100 71 128 82 145 89 148 4 2 8 8 8 13
|
||||
0 5 42 82 94 172 311 538 496 858 518 897 14 25 40 70 58 100 18 30 42 71 53
|
||||
90 10 19 79 139 152 265 73 127 142 246 153 265 10 19 43 76 72 125 29 50 63
|
||||
108 75 130 65 116 80 140 87 143 4 2 8 8 8 12 0 8 114 212 140 250 6 8 14 24
|
||||
20 35 5 11 54 97 108 190 l100 170 -9611 3 c-5286 1 -9614 -1 -9618 -5 -5 -6
|
||||
-419 -719 -619 -1068 -89 -155 -267 -463 -323 -560 -38 -66 -81 -140 -95 -165
|
||||
-31 -56 -263 -457 -526 -910 -110 -190 -224 -388 -254 -440 -29 -52 -61 -109
|
||||
-71 -125 -23 -39 -243 -420 -268 -465 -11 -19 -204 -352 -428 -740 -224 -388
|
||||
-477 -826 -563 -975 -85 -148 -185 -322 -222 -385 -37 -63 -120 -207 -185
|
||||
-320 -65 -113 -177 -306 -248 -430 -72 -124 -172 -297 -222 -385 -51 -88 -142
|
||||
-245 -202 -350 -131 -226 -247 -427 -408 -705 -65 -113 -249 -432 -410 -710
|
||||
-160 -278 -388 -673 -506 -877 -118 -205 -216 -373 -219 -373 -3 0 -52 82
|
||||
-109 183 -58 100 -144 250 -192 332 -95 164 -402 696 -647 1120 -85 149 -228
|
||||
396 -317 550 -212 365 -982 1700 -1008 1745 -10 19 -43 76 -72 125 -29 50 -64
|
||||
110 -77 135 -14 25 -63 110 -110 190 -47 80 -96 165 -110 190 -14 25 -99 171
|
||||
-188 325 -89 154 -174 300 -188 325 -13 25 -64 113 -112 195 -48 83 -140 242
|
||||
-205 355 -65 113 -183 317 -263 454 -79 137 -152 264 -163 282 -50 89 -335
|
||||
583 -354 614 -12 19 -34 58 -50 85 -15 28 -129 226 -253 440 -124 215 -235
|
||||
408 -247 430 -12 22 -69 121 -127 220 -58 99 -226 389 -373 645 -148 256 -324
|
||||
561 -392 678 -67 117 -134 232 -147 255 -13 23 -33 59 -46 80 l-22 37 -9615 0
|
||||
-9615 0 20 -32z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 857 B After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 6.3 KiB |
BIN
js/public/img/mobilizon_default_card.png
Executable file → Normal file
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 8.8 KiB |
BIN
js/public/img/mobilizon_logo.png
Executable file → Normal file
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 5.5 KiB |
@ -1,11 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 248.16 46.78">
|
||||
<title>Mobilizon Logo</title>
|
||||
<g data-name="header">
|
||||
<path d="M0 45.82l3.18-40.8a29.88 29.88 0 015.07-.36 27.74 27.74 0 014.95.36l4.86 17.16a92.19 92.19 0 012.34 10.08h.36a92.19 92.19 0 012.34-10.08L28 5.02a29.23 29.23 0 015-.36 29.23 29.23 0 015 .36l3.18 40.8a13.61 13.61 0 01-3.63.42 23.41 23.41 0 01-3.63-.24l-1.2-19.92q-.36-5.52-.48-12.84h-.44l-7.32 26.51a25.62 25.62 0 01-4 .3 23.36 23.36 0 01-3.84-.3L9.36 13.24H9q-.3 8.94-.48 12.84L7.26 46a22.47 22.47 0 01-3.6.24A13.75 13.75 0 010 45.82zM74 31.06q0 8-4.26 12.3a12.21 12.21 0 01-9 3.42 12.21 12.21 0 01-9-3.42q-4.26-4.26-4.26-12.3t4.24-12.31a12.21 12.21 0 019-3.42 12.21 12.21 0 019 3.42Q74 23.02 74 31.06zM60.75 20.98q-5.67 0-5.67 10.08t5.67 10.08q5.67 0 5.67-10.08t-5.67-10.08zM103.2 19.75q2.7 4.11 2.7 11.28T102 42.31a13.18 13.18 0 01-10 4.11 31.41 31.41 0 01-11.34-2V2.2l.4-.45h2.76A4 4 0 0187 2.83a5.38 5.38 0 01.93 3.57v11.94a12.08 12.08 0 017.56-2.7 8.71 8.71 0 017.71 4.11zm-9.72 2a7.28 7.28 0 00-5.58 2.82v16a15 15 0 004.08.54 5.25 5.25 0 004.68-2.67q1.68-2.67 1.68-7.59 0-9.03-4.86-9.1zM121 22v23.94a20.85 20.85 0 01-3.66.3 23 23 0 01-3.78-.3V24.75q0-3.24-2.7-3.24h-.72a9.32 9.32 0 01-.3-2.58 10.7 10.7 0 01.3-2.7 39.63 39.63 0 014.38-.24h1a5.19 5.19 0 014 1.62A6.27 6.27 0 01121 22z" />
|
||||
<path d="M119.82.84a7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.93 7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.93z" fill="#fff" />
|
||||
<path d="M139.08 40.42h2a10.23 10.23 0 01.6 3.18 9.24 9.24 0 01-.18 2.1 38.47 38.47 0 01-5.64.54q-6.48 0-6.48-7v-37l.36-.42h2.88a3.94 3.94 0 013.12 1.05 5.52 5.52 0 01.9 3.57v31.31q-.02 2.67 2.44 2.67zM155.94 22v23.94a20.85 20.85 0 01-3.66.3 23 23 0 01-3.78-.3V24.75q0-3.24-2.7-3.24h-.72a9.32 9.32 0 01-.3-2.58 10.7 10.7 0 01.3-2.7 39.63 39.63 0 014.38-.24h1a5.19 5.19 0 014.05 1.62 6.27 6.27 0 011.43 4.39z" />
|
||||
<path d="M154.8 2.84a7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.93 7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.93z" fill="#fff" />
|
||||
<path d="M163.08 39.22l8.76-11.82q1.32-1.8 4.8-5.7l-.18-.3a63.09 63.09 0 01-7.74.42H163a9.79 9.79 0 01-.24-2.34 15.8 15.8 0 01.42-3.3h20.4a16.31 16.31 0 011 4.26 4.1 4.1 0 01-.78 2.34L175 34.66a64.65 64.65 0 01-4.56 5.7l.18.24q3.12-.3 5.22-.3h2.58a15.35 15.35 0 006.12-.9 9.4 9.4 0 01.72 3.12q0 3.42-4.32 3.42h-18a14.27 14.27 0 01-.9-3.93 5.08 5.08 0 011.04-2.79zM215.88 31.06q0 8-4.26 12.3a13.63 13.63 0 01-18.06 0q-4.26-4.26-4.26-12.3t4.26-12.31a13.63 13.63 0 0118.06 0q4.26 4.27 4.26 12.31zm-13.29-10.08q-5.67 0-5.67 10.08t5.67 10.08q5.67 0 5.67-10.08t-5.67-10.08zM247 25.84v13.32a11 11 0 001.2 5.64 7 7 0 01-4.41 1.56q-2.43 0-3.33-1.14a5.69 5.69 0 01-.9-3.54V27.4a7.74 7.74 0 00-.72-3.87 2.78 2.78 0 00-2.58-1.17 8.62 8.62 0 00-6.3 3v20.58a20.85 20.85 0 01-3.66.3 23 23 0 01-3.78-.3v-29.7l.42-.36h2.76q3.42 0 4.08 3.6 4.38-3.84 8.73-3.84t6.42 2.82a12.17 12.17 0 012.07 7.38z" />
|
||||
<path d="M57.26 10.75a7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.84 7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.84zM198.26 10.75a7.37 7.37 0 01-.6-3 7.37 7.37 0 01.6-3 8.09 8.09 0 013.87-.84 7.05 7.05 0 013.69.84 7.37 7.37 0 01.6 3 7.37 7.37 0 01-.6 3 7.46 7.46 0 01-3.87.84 6.49 6.49 0 01-3.69-.84z" fill="#fff" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 5.5 KiB |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="2799 -911 16 22"><g data-name="Artboard – 1"><g data-name="Symbol 3 – 1"><g data-name="Group 44"><path d="M2799-911v11l8-5" data-name="Path 4"/><path d="M2799-900v11l8-6" data-name="Path 5"/><path d="M2807-905v10l8-5" data-name="Path 6"/><path fill="transparent" d="M2807-895v-10l-8 5z" data-name="Path 7"/></g></g></g></svg>
|
Before Width: | Height: | Size: 378 B |
Before Width: | Height: | Size: 174 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 193 KiB |
Before Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 14 KiB |
@ -1 +0,0 @@
|
||||
<svg height="100px" width="100px" fill="#000000" version="1.0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 84.922" enable-background="new 0 0 100 84.922" xml:space="preserve"><path d="M50.29,42.212"/><path d="M50.29,42.212"/><path d="M50.29,42.212"/><path d="M95.223,22.145c-5.377,3.135-8.271,4.414-13.844,4.125c-2.098-0.024-3.207-0.917-5.281-0.724 c-1.93,0.072-2.918,0.796-4.849,1.447c-2.966,0.917-4.583,1.737-7.694,2.702c-1.977,0.555-3.23,0.579-5.281,1.278 c-1.76,0.748-0.916,0.145-2.146,1.567c-1.592,1.761-1.206,3.136-2.701,6.15c-1.856,3.956-1.641,4.486-0.579,4.969 c-0.699,2.025-0.867,3.377-0.699,5.571c0.192,1.664-0.506,2.821,1.278,4.147c2.437,1.81,7.55,6.054,8.853,6.125 c1.953-0.071,7.646,0.146,10.539-1.855c0.652-0.41,0.845-0.82,0.289,0.725c-0.119,0.192-7.211,5.715-7.982,5.69 c-5.463,0.176-6.511,0.431-6.611,0.556c-0.628-0.243-4.812-5.237-7.377-3.402c-0.99,0.604-1.448,1.183-1.835,2.269 c0.338,0.699,1.931,1.81,3.4,2.726c2.123,1.352,2.315,2.772,4.438,3.281c2.58,0.577,5.33,0.191,6.969,0.408 c0.629,0.169,6.32-1.495,9.865-3.4c3.28-1.688-4.51,3.256-6.416,5.692c-5.74,1.81-4.123,1.882-6.85,2.437 c-2.532,0.578-2.412,0.434-4.148,0.988c-1.785,0.434-3.256,2.87-1.566,4.147c1.013,0.845,4.173-0.337,7.283-0.435 c1.375-0.022,6.994-2.604,8.272-3.279c3.185-1.713,5.522-4.076,7.404-5.428c2.604-1.807-2.942,4.994-5.282,7.84 c-0.675,0.918-0.988,1.109-1.832,2.291c-1.398,1.811,0.385,4.56,1.277,4.125c1.037-0.385,1.713-2.459,2.846-3.135 c0.58-0.314,2.123-2.582,3.57-4.125c1.061-1.205,1.833-1.736,2.846-2.99c1.713-2.123,2.074-3.738,3.57-6.006 c0.916-1.183,1.566-1.543,2.41-2.99c4.463-8.441,3.16-12.229,7.43-18.258c1.303-1.785,2.773-2.22,4.848-3.281 C101.566,30.031,95.175,22.169,95.223,22.145z M74.529,44.528c-1.014,3.545-0.916,3.955-2.846,5.281 c-2.34,1.785-2.461,0.434-7.838,3.425c0,0-2.22-2.315-5.717-3.425c0.023,0.049-0.941-4.486-2.846-6.006 c4.533-3.449,4.412-6.366,5.137-6.27c1.616,0.145,4.198,0.965,8.973-0.844C72.143,41.923,75.471,41.657,74.529,44.528z"/><path d="M47.3,18.863c-2.122-1.423-2.339-2.846-4.438-3.304c-2.58-0.627-5.354-0.241-6.971-0.555 c-0.627-0.072-6.318,1.592-9.84,3.425c-3.328,1.761,4.486-3.184,6.416-5.716c5.716-1.712,4.076-1.785,6.85-2.412 c2.508-0.506,2.387-0.362,4.124-0.868c1.761-0.482,3.256-2.895,1.567-4.269c-1.037-0.772-4.172,0.41-7.26,0.434 C36.35,5.696,30.729,8.277,29.451,9c-3.184,1.664-5.523,4.028-7.404,5.282c-2.629,1.906,2.942-4.872,5.282-7.694 c0.675-0.965,0.989-1.158,1.856-2.291c1.352-1.857-0.41-4.607-1.277-4.269c-1.062,0.482-1.736,2.556-3.016,3.28 c-0.458,0.266-2.002,2.533-3.424,4.125c-1.062,1.158-1.834,1.688-2.847,3.015c-1.736,2.05-2.074,3.666-3.569,5.837 c-0.916,1.302-1.592,1.64-2.412,3.135C8.179,27.813,9.457,31.6,5.212,37.533c-1.302,1.905-2.773,2.315-4.848,3.425 c-1.93,14.037,4.438,21.876,4.413,21.828c5.379-3.062,8.249-4.342,13.845-4.147c2.099,0.12,3.208,1.012,5.282,0.866 c1.93-0.119,2.918-0.844,4.848-1.422c2.967-0.988,4.582-1.81,7.549-2.727c2.123-0.604,3.377-0.627,5.428-1.422 c1.76-0.652,0.916-0.049,2.146-1.424c1.567-1.809,1.205-3.184,2.557-6.127c2.002-4.027,1.784-4.558,0.723-4.992 c0.676-2.074,0.869-3.4,0.699-5.571c-0.217-1.688,0.507-2.87-1.277-4.125c-2.437-1.881-7.55-6.126-8.828-6.15 c-1.978,0.024-7.67-0.193-10.564,1.712c-0.65,0.506-0.844,0.917-0.289-0.555c0.121-0.266,7.212-5.789,7.983-5.861 c5.059-0.108,6.332-0.315,6.573-0.429c0.5,0.013,4.804,5.243,7.417,3.42c0.965-0.651,1.447-1.23,1.857-2.267 C50.364,20.817,48.772,19.708,47.3,18.863z M28.318,35.121c2.315-1.712,2.459-0.362,7.838-3.28c0-0.073,2.219,2.243,5.717,3.28 c-0.024,0.024,0.94,4.558,2.846,6.126c-4.535,3.401-4.414,6.32-5.138,6.271c-1.617-0.193-4.197-1.014-8.972,0.725 c-2.774-5.162-6.078-4.873-5.138-7.864C26.484,36.954,26.364,36.52,28.318,35.121z"/></svg>
|
Before Width: | Height: | Size: 3.7 KiB |
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="auto">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
174
js/src/App.vue
@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<div id="mobilizon">
|
||||
<VueAnnouncer />
|
||||
<VueSkipTo to="#main" :label="$t('Skip to main content')" />
|
||||
<NavBar />
|
||||
<div v-if="config && config.demoMode">
|
||||
<b-message
|
||||
@ -9,7 +7,7 @@
|
||||
type="is-danger"
|
||||
:title="$t('Warning').toLocaleUpperCase()"
|
||||
closable
|
||||
:aria-close-label="$t('Close')"
|
||||
aria-close-label="Close"
|
||||
>
|
||||
<p>
|
||||
{{ $t("This is a demonstration site to test Mobilizon.") }}
|
||||
@ -22,11 +20,9 @@
|
||||
</p>
|
||||
</b-message>
|
||||
</div>
|
||||
<error v-if="error" :error="error" />
|
||||
|
||||
<main id="main" v-else>
|
||||
<main>
|
||||
<transition name="fade" mode="out-in">
|
||||
<router-view ref="routerView" />
|
||||
<router-view />
|
||||
</transition>
|
||||
</main>
|
||||
<mobilizon-footer />
|
||||
@ -34,7 +30,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Ref, Vue, Watch } from "vue-property-decorator";
|
||||
import { Component, Vue } from "vue-property-decorator";
|
||||
import NavBar from "./components/NavBar.vue";
|
||||
import {
|
||||
AUTH_ACCESS_TOKEN,
|
||||
@ -52,9 +48,6 @@ import { initializeCurrentActor } from "./utils/auth";
|
||||
import { CONFIG } from "./graphql/config";
|
||||
import { IConfig } from "./types/config.model";
|
||||
import { ICurrentUser } from "./types/current-user.model";
|
||||
import jwt_decode, { JwtPayload } from "jwt-decode";
|
||||
import { refreshAccessToken } from "./apollo/utils";
|
||||
import { Route } from "vue-router";
|
||||
|
||||
@Component({
|
||||
apollo: {
|
||||
@ -64,39 +57,20 @@ import { Route } from "vue-router";
|
||||
components: {
|
||||
Logo,
|
||||
NavBar,
|
||||
error: () =>
|
||||
import(/* webpackChunkName: "editor" */ "./components/Error.vue"),
|
||||
"mobilizon-footer": Footer,
|
||||
},
|
||||
metaInfo() {
|
||||
return {
|
||||
titleTemplate: "%s | Mobilizon",
|
||||
};
|
||||
},
|
||||
})
|
||||
export default class App extends Vue {
|
||||
config!: IConfig;
|
||||
|
||||
currentUser!: ICurrentUser;
|
||||
|
||||
error: Error | null = null;
|
||||
|
||||
online = true;
|
||||
|
||||
interval: number | undefined = undefined;
|
||||
|
||||
@Ref("routerView") routerView!: Vue;
|
||||
|
||||
async created(): Promise<void> {
|
||||
if (await this.initializeCurrentUser()) {
|
||||
await initializeCurrentActor(this.$apollo.provider.defaultClient);
|
||||
}
|
||||
}
|
||||
|
||||
errorCaptured(error: Error): void {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
private async initializeCurrentUser() {
|
||||
const userId = localStorage.getItem(AUTH_USER_ID);
|
||||
const userEmail = localStorage.getItem(AUTH_USER_EMAIL);
|
||||
@ -116,141 +90,6 @@ export default class App extends Vue {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mounted(): void {
|
||||
this.online = window.navigator.onLine;
|
||||
window.addEventListener("offline", () => {
|
||||
this.online = false;
|
||||
this.showOfflineNetworkWarning();
|
||||
console.debug("offline");
|
||||
});
|
||||
window.addEventListener("online", () => {
|
||||
this.online = true;
|
||||
console.debug("online");
|
||||
});
|
||||
document.addEventListener("refreshApp", (event: Event) => {
|
||||
this.$buefy.snackbar.open({
|
||||
queue: false,
|
||||
indefinite: true,
|
||||
type: "is-secondary",
|
||||
actionText: this.$t("Update app") as string,
|
||||
cancelText: this.$t("Ignore") as string,
|
||||
message: this.$t("A new version is available.") as string,
|
||||
onAction: async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const detail = event.detail;
|
||||
const registration = detail as ServiceWorkerRegistration;
|
||||
try {
|
||||
await this.refreshApp(registration);
|
||||
window.location.reload();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
this.$notifier.error(
|
||||
this.$t(
|
||||
"An error has occured while refreshing the page."
|
||||
) as string
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
this.interval = setInterval(async () => {
|
||||
const accessToken = localStorage.getItem(AUTH_ACCESS_TOKEN);
|
||||
if (accessToken) {
|
||||
const token = jwt_decode<JwtPayload>(accessToken);
|
||||
if (
|
||||
token?.exp !== undefined &&
|
||||
new Date(token.exp * 1000 - 60000) < new Date()
|
||||
) {
|
||||
refreshAccessToken(this.$apollo.getClient());
|
||||
}
|
||||
}
|
||||
}, 60000);
|
||||
}
|
||||
|
||||
private async refreshApp(
|
||||
registration: ServiceWorkerRegistration
|
||||
): Promise<any> {
|
||||
const worker = registration.waiting;
|
||||
if (!worker) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
console.debug("Doing worker.skipWaiting().");
|
||||
return new Promise((resolve, reject) => {
|
||||
const channel = new MessageChannel();
|
||||
|
||||
channel.port1.onmessage = (event) => {
|
||||
console.debug("Done worker.skipWaiting().");
|
||||
if (event.data.error) {
|
||||
reject(event.data);
|
||||
} else {
|
||||
resolve(event.data);
|
||||
}
|
||||
};
|
||||
console.debug("calling skip waiting");
|
||||
worker?.postMessage({ type: "skip-waiting" }, [channel.port2]);
|
||||
});
|
||||
}
|
||||
|
||||
showOfflineNetworkWarning(): void {
|
||||
this.$notifier.error(this.$t("You are offline") as string);
|
||||
}
|
||||
|
||||
unmounted(): void {
|
||||
clearInterval(this.interval);
|
||||
this.interval = undefined;
|
||||
}
|
||||
|
||||
@Watch("config")
|
||||
async initializeStatistics(config: IConfig) {
|
||||
if (config) {
|
||||
const { statistics } = (await import("./services/statistics")) as {
|
||||
statistics: (config: IConfig, environment: Record<string, any>) => void;
|
||||
};
|
||||
statistics(config, { router: this.$router, version: config.version });
|
||||
}
|
||||
}
|
||||
|
||||
@Watch("$route", { immediate: true })
|
||||
updateAnnouncement(route: Route): void {
|
||||
const pageTitle = this.extractPageTitleFromRoute(route);
|
||||
if (pageTitle) {
|
||||
this.$announcer.polite(
|
||||
this.$t("Navigated to {pageTitle}", {
|
||||
pageTitle,
|
||||
}) as string
|
||||
);
|
||||
}
|
||||
// Set the focus to the router view
|
||||
// https://marcus.io/blog/accessible-routing-vuejs
|
||||
setTimeout(() => {
|
||||
const focusTarget = (
|
||||
this.routerView?.$refs?.componentFocusTarget !== undefined
|
||||
? this.routerView?.$refs?.componentFocusTarget
|
||||
: this.routerView?.$el
|
||||
) as HTMLElement;
|
||||
if (focusTarget && focusTarget instanceof Element) {
|
||||
// Make focustarget programmatically focussable
|
||||
focusTarget.setAttribute("tabindex", "-1");
|
||||
|
||||
// Focus element
|
||||
focusTarget.focus();
|
||||
|
||||
// Remove tabindex from focustarget.
|
||||
// Reason: https://axesslab.com/skip-links/#update-3-a-comment-from-gov-uk
|
||||
focusTarget.removeAttribute("tabindex");
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
extractPageTitleFromRoute(route: Route): string {
|
||||
if (route.meta?.announcer?.message) {
|
||||
return route.meta?.announcer?.message();
|
||||
}
|
||||
return document.title;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -260,6 +99,7 @@ export default class App extends Vue {
|
||||
/* Icons */
|
||||
$mdi-font-path: "~@mdi/font/fonts";
|
||||
@import "~@mdi/font/scss/materialdesignicons";
|
||||
|
||||
@import "common";
|
||||
|
||||
#mobilizon {
|
||||
@ -271,8 +111,4 @@ $mdi-font-path: "~@mdi/font/fonts";
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.vue-skip-to {
|
||||
z-index: 40;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,14 +1,12 @@
|
||||
import { CURRENT_ACTOR_CLIENT } from "@/graphql/actor";
|
||||
import { CURRENT_USER_CLIENT } from "@/graphql/user";
|
||||
import { ICurrentUserRole } from "@/types/enums";
|
||||
import { ApolloCache, NormalizedCacheObject } from "@apollo/client/cache";
|
||||
import { Resolvers } from "@apollo/client/core/types";
|
||||
import { ApolloCache } from "apollo-cache";
|
||||
import { NormalizedCacheObject } from "apollo-cache-inmemory";
|
||||
import { Resolvers } from "apollo-client/core/types";
|
||||
|
||||
export default function buildCurrentUserResolver(
|
||||
cache: ApolloCache<NormalizedCacheObject>
|
||||
): Resolvers {
|
||||
cache.writeQuery({
|
||||
query: CURRENT_USER_CLIENT,
|
||||
cache.writeData({
|
||||
data: {
|
||||
currentUser: {
|
||||
__typename: "CurrentUser",
|
||||
@ -17,12 +15,6 @@ export default function buildCurrentUserResolver(
|
||||
isLoggedIn: false,
|
||||
role: ICurrentUserRole.USER,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
cache.writeQuery({
|
||||
query: CURRENT_ACTOR_CLIENT,
|
||||
data: {
|
||||
currentActor: {
|
||||
__typename: "CurrentActor",
|
||||
id: null,
|
||||
@ -55,7 +47,7 @@ export default function buildCurrentUserResolver(
|
||||
},
|
||||
};
|
||||
|
||||
localCache.writeQuery({ data, query: CURRENT_USER_CLIENT });
|
||||
localCache.writeData({ data });
|
||||
},
|
||||
updateCurrentActor: (
|
||||
_: any,
|
||||
@ -82,7 +74,7 @@ export default function buildCurrentUserResolver(
|
||||
},
|
||||
};
|
||||
|
||||
localCache.writeQuery({ data, query: CURRENT_ACTOR_CLIENT });
|
||||
localCache.writeData({ data });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -1,103 +1,34 @@
|
||||
import {
|
||||
IntrospectionFragmentMatcher,
|
||||
NormalizedCacheObject,
|
||||
} from "apollo-cache-inmemory";
|
||||
import { AUTH_ACCESS_TOKEN, AUTH_REFRESH_TOKEN } from "@/constants";
|
||||
import { REFRESH_TOKEN } from "@/graphql/auth";
|
||||
import { IFollower } from "@/types/actor/follower.model";
|
||||
import { IParticipant } from "@/types/participant.model";
|
||||
import { Paginate } from "@/types/paginate";
|
||||
import { saveTokenData } from "@/utils/auth";
|
||||
import {
|
||||
ApolloClient,
|
||||
FieldPolicy,
|
||||
NormalizedCacheObject,
|
||||
Reference,
|
||||
TypePolicies,
|
||||
} from "@apollo/client/core";
|
||||
import introspectionQueryResultData from "../../fragmentTypes.json";
|
||||
import { IMember } from "@/types/actor/member.model";
|
||||
import { IComment } from "@/types/comment.model";
|
||||
import { IEvent } from "@/types/event.model";
|
||||
import { IActivity } from "@/types/activity.model";
|
||||
import uniqBy from "lodash/uniqBy";
|
||||
import { ApolloClient } from "apollo-client";
|
||||
|
||||
type possibleTypes = { name: string };
|
||||
type schemaType = {
|
||||
kind: string;
|
||||
name: string;
|
||||
possibleTypes: possibleTypes[];
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const types = introspectionQueryResultData.__schema.types as schemaType[];
|
||||
export const possibleTypes = types.reduce((acc, type) => {
|
||||
if (type.kind === "INTERFACE") {
|
||||
acc[type.name] = type.possibleTypes.map(({ name }) => name);
|
||||
}
|
||||
return acc;
|
||||
}, {} as Record<string, string[]>);
|
||||
|
||||
const replaceMergePolicy = <TExisting = any, TIncoming = any>(
|
||||
_existing: TExisting,
|
||||
incoming: TIncoming
|
||||
): TIncoming => incoming;
|
||||
|
||||
export const typePolicies: TypePolicies = {
|
||||
Discussion: {
|
||||
fields: {
|
||||
comments: paginatedLimitPagination<IComment>(),
|
||||
export const fragmentMatcher = new IntrospectionFragmentMatcher({
|
||||
introspectionQueryResultData: {
|
||||
__schema: {
|
||||
types: [
|
||||
{
|
||||
kind: "UNION",
|
||||
name: "SearchResult",
|
||||
possibleTypes: [
|
||||
{ name: "Event" },
|
||||
{ name: "Person" },
|
||||
{ name: "Group" },
|
||||
],
|
||||
},
|
||||
{
|
||||
kind: "INTERFACE",
|
||||
name: "Actor",
|
||||
possibleTypes: [{ name: "Person" }, { name: "Group" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
Group: {
|
||||
fields: {
|
||||
organizedEvents: paginatedLimitPagination([
|
||||
"afterDatetime",
|
||||
"beforeDatetime",
|
||||
]),
|
||||
activity: paginatedLimitPagination<IActivity>(["type", "author"]),
|
||||
},
|
||||
},
|
||||
Person: {
|
||||
fields: {
|
||||
organizedEvents: paginatedLimitPagination<IEvent>(),
|
||||
participations: paginatedLimitPagination<IParticipant>(["eventId"]),
|
||||
memberships: paginatedLimitPagination<IMember>(["group"]),
|
||||
},
|
||||
},
|
||||
Event: {
|
||||
fields: {
|
||||
participants: paginatedLimitPagination<IParticipant>(["roles"]),
|
||||
comments: pageLimitPagination<IComment>(),
|
||||
relatedEvents: pageLimitPagination<IEvent>(),
|
||||
options: { merge: replaceMergePolicy },
|
||||
participantStats: { merge: replaceMergePolicy },
|
||||
},
|
||||
},
|
||||
Instance: {
|
||||
keyFields: ["domain"],
|
||||
},
|
||||
RootQueryType: {
|
||||
fields: {
|
||||
relayFollowers: paginatedLimitPagination<IFollower>(),
|
||||
relayFollowings: paginatedLimitPagination<IFollower>([
|
||||
"orderBy",
|
||||
"direction",
|
||||
]),
|
||||
events: paginatedLimitPagination(),
|
||||
groups: paginatedLimitPagination([
|
||||
"preferredUsername",
|
||||
"name",
|
||||
"domain",
|
||||
"local",
|
||||
"suspended",
|
||||
]),
|
||||
persons: paginatedLimitPagination([
|
||||
"preferredUsername",
|
||||
"name",
|
||||
"domain",
|
||||
"local",
|
||||
"suspended",
|
||||
]),
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export async function refreshAccessToken(
|
||||
apolloClient: ApolloClient<NormalizedCacheObject>
|
||||
@ -107,11 +38,6 @@ export async function refreshAccessToken(
|
||||
|
||||
const refreshToken = localStorage.getItem(AUTH_REFRESH_TOKEN);
|
||||
|
||||
if (!refreshToken) {
|
||||
console.debug("Refresh token not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log("Refreshing access token.");
|
||||
|
||||
try {
|
||||
@ -126,71 +52,6 @@ export async function refreshAccessToken(
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.debug("Failed to refresh token");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
type KeyArgs = FieldPolicy<any>["keyArgs"];
|
||||
|
||||
export function pageLimitPagination<T = Reference>(
|
||||
keyArgs: KeyArgs = false
|
||||
): FieldPolicy<T[]> {
|
||||
return {
|
||||
keyArgs,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
merge(existing, incoming, { args }) {
|
||||
if (!incoming) return existing;
|
||||
if (!existing) return incoming; // existing will be empty the first time
|
||||
|
||||
return doMerge(existing as Array<T>, incoming as Array<T>, args);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function paginatedLimitPagination<T = Paginate<any>>(
|
||||
keyArgs: KeyArgs = false
|
||||
): FieldPolicy<Paginate<T>> {
|
||||
return {
|
||||
keyArgs,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
merge(existing, incoming, { args }) {
|
||||
if (!incoming) return existing;
|
||||
if (!existing) return incoming; // existing will be empty the first time
|
||||
|
||||
return {
|
||||
total: incoming.total,
|
||||
elements: doMerge(existing.elements, incoming.elements, args),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function doMerge<T = any>(
|
||||
existing: Array<T>,
|
||||
incoming: Array<T>,
|
||||
args: Record<string, any> | null
|
||||
): Array<T> {
|
||||
const merged = existing && Array.isArray(existing) ? existing.slice(0) : [];
|
||||
const previous = incoming && Array.isArray(incoming) ? incoming.slice(0) : [];
|
||||
let res;
|
||||
if (args) {
|
||||
// Assume an page of 1 if args.page omitted.
|
||||
const { page = 1, limit = 10 } = args;
|
||||
for (let i = 0; i < previous.length; ++i) {
|
||||
merged[(page - 1) * limit + i] = previous[i];
|
||||
}
|
||||
res = merged;
|
||||
} else {
|
||||
// It's unusual (probably a mistake) for a paginated field not
|
||||
// to receive any arguments, so you might prefer to throw an
|
||||
// exception here, instead of recovering by appending incoming
|
||||
// onto the existing array.
|
||||
res = [...merged, ...previous];
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
res = uniqBy(res, (elem: any) => elem.__ref);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
4
js/src/assets/diaspora-icon.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg version="1.1" viewBox="0 0 65.131 65.131" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m28.214 64.754c-6.9441-0.80647-14.478-4.7044-19.429-10.053-8.1024-8.7516-10.823-21.337-7.0178-32.463 3.8465-11.248 12.917-19.153 24.746-21.569 7.2561-1.4817 14.813-0.27619 21.622 3.4495 7.517 4.1126 12.568 10.251 15.291 18.582 5.5678 17.038-4.1941 35.667-21.417 40.87-4.6929 1.4178-8.7675 1.7673-13.795 1.1834zm0.43913-17.263c2.0058-2.7986 3.7663-5.0883 3.9123-5.0883 0.14591 0 1.9109 2.2959 3.9221 5.102 2.0112 2.8061 3.827 5.0577 4.0349 5.0035 0.90081-0.23467 8.2871-5.9034 8.1633-6.265-0.07527-0.21984-1.7555-2.6427-3.7338-5.3842-1.9783-2.7414-3.552-5.0223-3.497-5.0686 0.05497-0.04629 2.8095-0.97845 6.1211-2.0715 3.3117-1.093 6.0224-2.1432 6.0239-2.3338 0.0073-0.92502-2.9094-9.4312-3.283-9.5746-0.23567-0.09043-2.9906 0.68953-6.1221 1.7332-3.1315 1.0437-5.8046 1.8977-5.9404 1.8977-0.13575 0-0.28828-2.9385-0.33895-6.53l-0.09213-6.53h-10.516l-0.09213 6.53c-0.05067 3.5915-0.20809 6.53-0.34982 6.53s-2.9544-0.90204-6.2504-2.0045l-5.9927-2.0045-1.5444 4.6339c-0.8494 2.5487-1.5444 4.866-1.5444 5.1496 0 0.36743 1.7311 1.087 6.0212 2.503 3.3117 1.093 6.0662 2.0252 6.1211 2.0715 0.05497 0.04629-1.5187 2.3272-3.497 5.0686-1.9783 2.7415-3.6605 5.1643-3.7382 5.3842-0.14163 0.40073 7.4833 6.2827 8.1896 6.3175 0.20673 0.01021 2.017-2.2712 4.0228-5.0698z" stroke-width=".33922"/>
|
||||
<path d="m23.631 51.953c-2.348-1.5418-6.9154-5.1737-7.0535-5.6088-0.06717-0.21164 0.45125-0.99318 3.3654-5.0734 2.269-3.177 3.7767-5.3581 3.7767-5.4637 0-0.03748-1.6061-0.60338-3.5691-1.2576-6.1342-2.0442-8.3916-2.9087-8.5288-3.2663-0.03264-0.08506 0.09511-0.68598 0.28388-1.3354 0.643-2.212 2.7038-8.4123 2.7959-8.4123 0.05052 0 2.6821 0.85982 5.848 1.9107 3.1659 1.0509 5.897 1.9222 6.0692 1.9362 0.3089 0.02514 0.31402 0.01925 0.38295-0.44107 0.09851-0.65784 0.26289-5.0029 0.2633-6.9599 1.87e-4 -0.90267 0.02801-2.5298 0.06184-3.6158l0.0615-1.9746h10.392l0.06492 4.4556c0.06287 4.3148 0.18835 7.8236 0.29865 8.3513 0.0295 0.14113 0.11236 0.2566 0.18412 0.2566 0.07176 0 1.6955-0.50861 3.6084-1.1303 4.5213-1.4693 6.2537-2.0038 7.3969-2.2822 0.87349-0.21269 0.94061-0.21704 1.0505-0.06806 0.45169 0.61222 3.3677 9.2365 3.1792 9.4025-0.33681 0.29628-2.492 1.1048-6.9823 2.6194-5.3005 1.7879-5.1321 1.7279-5.1321 1.8283 0 0.13754 0.95042 1.522 3.5468 5.1666 1.3162 1.8475 2.6802 3.7905 3.0311 4.3176l0.63804 0.95842-0.27216 0.28519c-1.1112 1.1644-7.3886 5.8693-7.8309 5.8693-0.22379 0-1.2647-1.2321-2.9284-3.4663-0.90374-1.2137-2.264-3.0402-3.0228-4.059-0.75878-1.0188-1.529-2.0203-1.7116-2.2256l-0.33201-0.37324-0.32674 0.37324c-0.43918 0.50169-2.226 2.867-3.8064 5.0388-2.1662 2.9767-3.6326 4.8055-3.8532 4.8055-0.05161 0-0.4788-0.25278-0.94931-0.56173z" fill="#fff" stroke-width=".093311"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
BIN
js/src/assets/logo.png
Normal file
After Width: | Height: | Size: 6.7 KiB |