Merge branch 'master' into feature/mark-all-notification-as-read

This commit is contained in:
Moriz Wahl 2023-03-08 16:50:02 +01:00
commit bdc1cb33da
461 changed files with 17572 additions and 5153 deletions

209
.github/dependabot.yml vendored
View File

@ -1,179 +1,68 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
rebase-strategy: "disabled"
schedule:
interval: weekly
day: "saturday"
timezone: "Europe/Berlin"
time: "03:00"
- package-ecosystem: npm
directory: "/"
rebase-strategy: "disabled"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: cypress
versions:
- 6.3.0
- 6.4.0
- 6.5.0
- 6.6.0
- 6.7.1
- 6.8.0
- 7.0.0
- 7.0.1
- 7.1.0
- dependency-name: cypress-cucumber-preprocessor
versions:
- 4.0.0
- 4.0.1
- 4.0.3
- dependency-name: date-fns
versions:
- 2.16.1
- 2.17.0
- 2.18.0
- 2.19.0
- 2.20.0
- 2.20.1
- 2.20.2
- 2.20.3
- 2.21.0
- dependency-name: cypress-file-upload
versions:
- 5.0.2
- 5.0.3
- 5.0.4
- 5.0.5
- dependency-name: neo4j-driver
versions:
- 4.2.2
interval: weekly
day: "saturday"
timezone: "Europe/Berlin"
time: "03:00"
- package-ecosystem: npm
directory: "/backend"
rebase-strategy: "disabled"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: y18n
versions:
- 4.0.1
- 4.0.2
- dependency-name: metascraper-publisher
versions:
- 5.16.16
- 5.18.1
- 5.18.12
- 5.18.2
- 5.18.4
- 5.18.5
- 5.18.6
- 5.18.9
- 5.20.0
- 5.21.0
- 5.21.2
- 5.21.3
- 5.21.4
- 5.21.5
- dependency-name: metascraper-author
versions:
- 5.16.16
- 5.18.1
- 5.18.12
- 5.18.2
- 5.18.4
- 5.18.5
- 5.18.6
- 5.18.9
- 5.20.0
- 5.21.0
- 5.21.2
- 5.21.3
- 5.21.4
- 5.21.5
- dependency-name: neo4j-driver
versions:
- 4.2.2
- dependency-name: neo4j-graphql-js
versions:
- 2.19.1
- dependency-name: mustache
versions:
- 4.1.0
interval: weekly
day: "saturday"
timezone: "Europe/Berlin"
time: "03:00"
- package-ecosystem: npm
directory: "/webapp"
rebase-strategy: "disabled"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: nuxt
versions:
- 2.14.12
- 2.15.0
- 2.15.1
- 2.15.2
- 2.15.3
- dependency-name: v-tooltip
versions:
- 2.1.2
- dependency-name: "@vue/server-test-utils"
versions:
- 1.1.2
- 1.1.3
- dependency-name: node-notifier
versions:
- 8.0.1
- package-ecosystem: docker
directory: "/webapp"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: node
versions:
- ">= 15.5.a, < 15.6"
- dependency-name: node
versions:
- 15.10.0.pre.alpine3.10
- 15.11.0.pre.alpine3.10
- 15.12.0.pre.alpine3.10
- 15.13.0.pre.alpine3.10
- 15.7.0.pre.alpine3.10
- 15.8.0.pre.alpine3.10
- 15.9.0.pre.alpine3.10
interval: weekly
day: "saturday"
timezone: "Europe/Berlin"
time: "03:00"
- package-ecosystem: docker
directory: "/backend"
rebase-strategy: "disabled"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: node
versions:
- ">= 15.4.a, < 15.5"
- dependency-name: node
versions:
- ">= 15.5.a, < 15.6"
- dependency-name: node
versions:
- 15.10.0.pre.alpine3.10
- 15.11.0.pre.alpine3.10
- 15.12.0.pre.alpine3.10
- 15.13.0.pre.alpine3.10
- 15.7.0.pre.alpine3.10
- 15.8.0.pre.alpine3.10
- 15.9.0.pre.alpine3.10
interval: weekly
day: "saturday"
timezone: "Europe/Berlin"
time: "03:00"
- package-ecosystem: docker
directory: "/webapp"
rebase-strategy: "disabled"
schedule:
interval: weekly
day: "saturday"
timezone: "Europe/Berlin"
time: "03:00"
- package-ecosystem: docker
directory: "/neo4j"
rebase-strategy: "disabled"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
ignore:
- dependency-name: neo4j
versions:
- 4.2.3
- 4.2.4
interval: weekly
day: "saturday"
timezone: "Europe/Berlin"
time: "03:00"
- package-ecosystem: docker
directory: "/deployment/legacy-migration/maintenance-worker"
directory: "/deployment/src/docker"
rebase-strategy: "disabled"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
interval: weekly
day: "saturday"
timezone: "Europe/Berlin"
time: "03:00"

View File

@ -1,7 +1,6 @@
name: "ocelot.social lint pull request CI"
on:
pull_request:
pull_request_target:
types:
- opened
@ -12,6 +11,7 @@ jobs:
main:
name: Validate PR title
runs-on: ubuntu-latest
if: ${{ github.actor != 'dependabot[bot]' }}
steps:
- uses: amannn/action-semantic-pull-request@v5
env:

74
.github/workflows/publish-branded.yml vendored Normal file
View File

@ -0,0 +1,74 @@
name: publish-branded
on:
repository_dispatch:
types: [trigger-build-success]
jobs:
build_branded:
name: Docker Build Branded
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: ${{ github.event.client_payload.ref }}
- name: Setup env
run: echo "OCELOT_VERSION=${{ github.event.client_payload.BUILD_VERSION }}" >> $GITHUB_ENV
- name: Build branded images
run: |
deployment/scripts/branded-images.build.sh
docker save "ocelotsocialnetwork/backend-branded" > /tmp/backend-branded.tar
docker save "ocelotsocialnetwork/webapp-branded" > /tmp/webapp-branded.tar
docker save "ocelotsocialnetwork/maintenance-branded" > /tmp/maintenance-branded.tar
- name: Upload Artifact (Backend)
uses: actions/upload-artifact@v2
with:
name: docker-backend-branded
path: /tmp/backend-branded.tar
- name: Upload Artifact (Webapp)
uses: actions/upload-artifact@v2
with:
name: docker-webapp-branded
path: /tmp/webapp-branded.tar
- name: Upload Artifact (Maintenance)
uses: actions/upload-artifact@v2
with:
name: docker-maintenance-branded
path: /tmp/maintenance-branded.tar
upload_to_dockerhub:
name: Upload to Dockerhub
runs-on: ubuntu-latest
needs: [build_branded]
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
steps:
- name: Download Docker Image (Backend)
uses: actions/download-artifact@v2
with:
name: docker-backend-branded
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/backend-branded.tar
- name: Download Docker Image (Webapp)
uses: actions/download-artifact@v2
with:
name: docker-webapp-branded
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/webapp-branded.tar
- name: Download Docker Image (Maintenance)
uses: actions/download-artifact@v2
with:
name: docker-maintenance-branded
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/maintenance-branded.tar
- name: Upload to dockerhub
run: deployment/scripts/branded-images.upload.sh

View File

@ -1,68 +1,40 @@
name: ocelot.social publish CI
name: publish
on:
push:
branches:
- master
# - 5059-epic-groups # for testing while developing
# template branches in repo
# - template--separate-branch-auto-deployment--5059-epic-groups
jobs:
##############################################################################
# JOB: PREPARE ###############################################################
##############################################################################
prepare:
name: Prepare
runs-on: ubuntu-latest
# needs: [nothing]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# TODO: DO STUFF ??? #####################################################
##########################################################################
- name: Check translation files
run: |
scripts/translations/sort.sh
scripts/translations/missing-keys.sh
##############################################################################
# JOB: DOCKER BUILD COMMUNITY NEO4J ##########################################
##############################################################################
build_production_neo4j:
name: Docker Build Production - Neo4J
runs-on: ubuntu-latest
needs: [prepare]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# SET ENVS ###############################################################
##########################################################################
- name: ENV - VERSION
run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
- name: ENV - BUILD_DATE
run: echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
- name: ENV - BUILD_VERSION
run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: ENV - BUILD_COMMIT
run: echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
##########################################################################
# NEO4J ##################################################################
##########################################################################
uses: actions/checkout@v3
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
- run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: Neo4J | Build `community` image
run: docker build --target community -t "ocelotsocialnetwork/neo4j-community:latest" -t "ocelotsocialnetwork/neo4j-community:${VERSION}" -t "ocelotsocialnetwork/neo4j-community:${BUILD_VERSION}" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT neo4j/
run: |
docker build --target community \
--tag "ocelotsocialnetwork/neo4j-community:latest" \
--tag "ocelotsocialnetwork/neo4j-community:${VERSION}" \
--tag "ocelotsocialnetwork/neo4j-community:${BUILD_VERSION}" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
neo4j/
- name: Neo4J | Save docker image
run: docker save "ocelotsocialnetwork/neo4j-community" > /tmp/neo4j.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: docker-neo4j-community
path: /tmp/neo4j.tar
@ -73,36 +45,45 @@ jobs:
build_production_backend:
name: Docker Build Production - Backend
runs-on: ubuntu-latest
needs: [prepare]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# SET ENVS ###############################################################
##########################################################################
- name: ENV - VERSION
run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
- name: ENV - BUILD_DATE
run: echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
- name: ENV - BUILD_VERSION
run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: ENV - BUILD_COMMIT
run: echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
##########################################################################
# BUILD BACKEND DOCKER IMAGE (production) ################################
##########################################################################
uses: actions/checkout@v3
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
- run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: Backend | Build `production` image
run: |
docker build --target base -t "ocelotsocialnetwork/backend:latest-base" -t "ocelotsocialnetwork/backend:${VERSION}-base" -t "ocelotsocialnetwork/backend:${BUILD_VERSION}-base" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT backend/
docker build --target code -t "ocelotsocialnetwork/backend:latest-code" -t "ocelotsocialnetwork/backend:${VERSION}-code" -t "ocelotsocialnetwork/backend:${BUILD_VERSION}-code" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT backend/
docker build --target production -t "ocelotsocialnetwork/backend:latest" -t "ocelotsocialnetwork/backend:${VERSION}" -t "ocelotsocialnetwork/backend:${BUILD_VERSION}" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT backend/
docker build --target base \
--tag "ocelotsocialnetwork/backend:latest-base" \
--tag "ocelotsocialnetwork/backend:${VERSION}-base" \
--tag "ocelotsocialnetwork/backend:${BUILD_VERSION}-base" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
backend/
docker build --target code \
--tag "ocelotsocialnetwork/backend:latest-code" \
--tag "ocelotsocialnetwork/backend:${VERSION}-code" \
--tag "ocelotsocialnetwork/backend:${BUILD_VERSION}-code" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
backend/
docker build --target production \
--tag "ocelotsocialnetwork/backend:latest" \
--tag "ocelotsocialnetwork/backend:${VERSION}" \
--tag "ocelotsocialnetwork/backend:${BUILD_VERSION}" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
backend/
- name: Backend | Save docker image
run: docker save "ocelotsocialnetwork/backend" > /tmp/backend.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: docker-backend-production
path: /tmp/backend.tar
@ -113,36 +94,45 @@ jobs:
build_production_webapp:
name: Docker Build Production - WebApp
runs-on: ubuntu-latest
needs: [prepare]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# SET ENVS ###############################################################
##########################################################################
- name: ENV - VERSION
run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
- name: ENV - BUILD_DATE
run: echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
- name: ENV - BUILD_VERSION
run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: ENV - BUILD_COMMIT
run: echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
##########################################################################
# BUILD WEBAPP DOCKER IMAGE (build) ######################################
##########################################################################
uses: actions/checkout@v3
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
- run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: Webapp | Build `production` image
run: |
docker build --target base -t "ocelotsocialnetwork/webapp:latest-base" -t "ocelotsocialnetwork/webapp:${VERSION}-base" -t "ocelotsocialnetwork/webapp:${BUILD_VERSION}-base" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/
docker build --target code -t "ocelotsocialnetwork/webapp:latest-code" -t "ocelotsocialnetwork/webapp:${VERSION}-code" -t "ocelotsocialnetwork/webapp:${BUILD_VERSION}-code" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/
docker build --target production -t "ocelotsocialnetwork/webapp:latest" -t "ocelotsocialnetwork/webapp:${VERSION}" -t "ocelotsocialnetwork/webapp:${BUILD_VERSION}" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/
docker build --target base \
--tag "ocelotsocialnetwork/webapp:latest-base" \
--tag "ocelotsocialnetwork/webapp:${VERSION}-base" \
--tag "ocelotsocialnetwork/webapp:${BUILD_VERSION}-base" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
webapp/
docker build --target code \
--tag "ocelotsocialnetwork/webapp:latest-code" \
--tag "ocelotsocialnetwork/webapp:${VERSION}-code" \
--tag "ocelotsocialnetwork/webapp:${BUILD_VERSION}-code" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
webapp/
docker build --target production \
--tag "ocelotsocialnetwork/webapp:latest" \
--tag "ocelotsocialnetwork/webapp:${VERSION}" \
--tag "ocelotsocialnetwork/webapp:${BUILD_VERSION}" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
webapp/
- name: Webapp | Save docker image
run: docker save "ocelotsocialnetwork/webapp" > /tmp/webapp.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: docker-webapp-production
path: /tmp/webapp.tar
@ -153,36 +143,48 @@ jobs:
build_production_maintenance:
name: Docker Build Production - Maintenance
runs-on: ubuntu-latest
needs: [prepare]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# SET ENVS ###############################################################
##########################################################################
- name: ENV - VERSION
run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
- name: ENV - BUILD_DATE
run: echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
- name: ENV - BUILD_VERSION
run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: ENV - BUILD_COMMIT
run: echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
##########################################################################
# BUILD MAINTENANCE DOCKER IMAGE (build) #################################
##########################################################################
uses: actions/checkout@v3
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
- run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: Maintenance | Build `production` image
run: |
docker build --target base -t "ocelotsocialnetwork/maintenance:latest-base" -t "ocelotsocialnetwork/maintenance:${VERSION}-base" -t "ocelotsocialnetwork/maintenance:${BUILD_VERSION}-base" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/ -f webapp/Dockerfile.maintenance
docker build --target code -t "ocelotsocialnetwork/maintenance:latest-code" -t "ocelotsocialnetwork/maintenance:${VERSION}-code" -t "ocelotsocialnetwork/maintenance:${BUILD_VERSION}-code" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/ -f webapp/Dockerfile.maintenance
docker build --target production -t "ocelotsocialnetwork/maintenance:latest" -t "ocelotsocialnetwork/maintenance:${VERSION}" -t "ocelotsocialnetwork/maintenance:${BUILD_VERSION}" --build-arg BBUILD_DATE=$BUILD_DATE --build-arg BBUILD_VERSION=$BUILD_VERSION --build-arg BBUILD_COMMIT=$BUILD_COMMIT webapp/ -f webapp/Dockerfile.maintenance
docker build --target base \
--tag "ocelotsocialnetwork/maintenance:latest-base" \
--tag "ocelotsocialnetwork/maintenance:${VERSION}-base" \
--tag "ocelotsocialnetwork/maintenance:${BUILD_VERSION}-base" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
-f webapp/Dockerfile.maintenance \
webapp/
docker build --target code \
--tag "ocelotsocialnetwork/maintenance:latest-code" \
--tag "ocelotsocialnetwork/maintenance:${VERSION}-code" \
--tag "ocelotsocialnetwork/maintenance:${BUILD_VERSION}-code" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
-f webapp/Dockerfile.maintenance \
webapp/
docker build --target production \
--tag "ocelotsocialnetwork/maintenance:latest" \
--tag "ocelotsocialnetwork/maintenance:${VERSION}" \
--tag "ocelotsocialnetwork/maintenance:${BUILD_VERSION}" \
--build-arg BBUILD_DATE=$BUILD_DATE \
--build-arg BBUILD_VERSION=$BUILD_VERSION \
--build-arg BBUILD_COMMIT=$BUILD_COMMIT \
-f webapp/Dockerfile.maintenance \
webapp/
- name: Maintenance | Save docker image
run: docker save "ocelotsocialnetwork/maintenance" > /tmp/maintenance.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: docker-maintenance-production
path: /tmp/maintenance.tar
@ -198,130 +200,39 @@ jobs:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# DOWNLOAD DOCKER IMAGES #################################################
##########################################################################
- name: Download Docker Image (Neo4J)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-neo4j-community
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/neo4j.tar
- run: docker load < /tmp/neo4j.tar
- name: Download Docker Image (Backend)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-backend-production
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/backend.tar
- run: docker load < /tmp/backend.tar
- name: Download Docker Image (WebApp)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-webapp-production
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/webapp.tar
- run: docker load < /tmp/webapp.tar
- name: Download Docker Image (Maintenance)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-maintenance-production
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/maintenance.tar
##########################################################################
# Upload #################################################################
##########################################################################
- run: docker load < /tmp/maintenance.tar
- name: login to dockerhub
run: echo "${DOCKERHUB_TOKEN}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin
- name: Push neo4j
run: docker push --all-tags ocelotsocialnetwork/neo4j-community
- name: Push backend
run: docker push --all-tags ocelotsocialnetwork/backend
- name: Push webapp
run: docker push --all-tags ocelotsocialnetwork/webapp
- name: Push maintenance
run: docker push --all-tags ocelotsocialnetwork/maintenance
##############################################################################
# JOB: KUBERNETES DEPLOY ACTUAL/LATEST VERSION ######################################
##############################################################################
kubernetes_deploy:
# see example https://github.com/do-community/example-doctl-action
# see example https://github.com/do-community/example-doctl-action/blob/main/.github/workflows/workflow.yaml
name: Kubernetes deploy of latest version to stage.ocelot.social cluster at DigitalOcean
runs-on: ubuntu-latest
needs: [upload_to_dockerhub]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# SET ENVS ###############################################################
##########################################################################
- name: ENV - VERSION
run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
- name: ENV - BUILD_VERSION
run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
##########################################################################
# Install DigitalOceans doctl and set kubeconfig #########################
##########################################################################
- name: Install doctl
uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
- name: Save DigitalOcean kubeconfig with short-lived credentials
run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 cluster-stage-ocelot-social
##########################################################################
# Deploy new Docker images to DigitalOcean Kubernetes cluster ############
##########################################################################
# - name: Deploy 'latest' to DigitalOcean Kubernetes
# run: |
# kubectl -n default set image deployment/ocelot-webapp container-ocelot-webapp=ocelotsocialnetwork/webapp:latest
# kubectl -n default rollout restart deployment/ocelot-webapp
# kubectl -n default set image deployment/ocelot-backend container-ocelot-backend=ocelotsocialnetwork/backend:latest
# kubectl -n default rollout restart deployment/ocelot-backend
# kubectl -n default set image deployment/ocelot-maintenance container-ocelot-maintenance=ocelotsocialnetwork/maintenance:latest
# kubectl -n default rollout restart deployment/ocelot-maintenance
# kubectl -n default set image deployment/ocelot-neo4j container-ocelot-neo4j=ocelotsocialnetwork/neo4j-community:latest
# kubectl -n default rollout restart deployment/ocelot-neo4j
- name: Deploy actual version '$BUILD_VERSION' to DigitalOcean Kubernetes
- name: Push images
run: |
kubectl -n default set image deployment/ocelot-webapp container-ocelot-webapp=ocelotsocialnetwork/webapp:$BUILD_VERSION
kubectl -n default rollout restart deployment/ocelot-webapp
kubectl -n default set image deployment/ocelot-backend container-ocelot-backend=ocelotsocialnetwork/backend:$BUILD_VERSION
kubectl -n default rollout restart deployment/ocelot-backend
kubectl -n default set image deployment/ocelot-maintenance container-ocelot-maintenance=ocelotsocialnetwork/maintenance:$BUILD_VERSION
kubectl -n default rollout restart deployment/ocelot-maintenance
kubectl -n default set image deployment/ocelot-neo4j container-ocelot-neo4j=ocelotsocialnetwork/neo4j-community:$BUILD_VERSION
kubectl -n default rollout restart deployment/ocelot-neo4j
# because this step 'kubectl -n default rollout status deployment/* --timeout=600s' does not work as expected
# and we need the pods to be up again for cleaning and seeding the Neo4j database and the backend.
# !!! this is not a perfect solution !!!
# deployments are regularly up again after 3 minutes and 10 seconds
- name: Sleep for 4 minutes, means 240 seconds
run: sleep 240s
shell: bash
- name: Verify deployment and wait for the pods of each deployment to get ready for cleaning and seeding of the database
run: |
kubectl -n default rollout status deployment/ocelot-backend --timeout=600s
kubectl -n default rollout status deployment/ocelot-neo4j --timeout=600s
kubectl -n default rollout status deployment/ocelot-maintenance --timeout=600s
kubectl -n default rollout status deployment/ocelot-webapp --timeout=600s
- name: Run migrations for Neo4j database via backend for staging
run: |
kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "yarn prod:migrate up"
- name: Reset and seed Neo4j database via backend for staging
# db cleaning and seeding is only possible in production if env 'PRODUCTION_DB_CLEAN_ALLOW=true' is set in deployment
run: |
kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await dist/db/clean.js && node --experimental-repl-await dist/db/seed.js"
docker push --all-tags ocelotsocialnetwork/neo4j-community
docker push --all-tags ocelotsocialnetwork/backend
docker push --all-tags ocelotsocialnetwork/webapp
docker push --all-tags ocelotsocialnetwork/maintenance
##############################################################################
# JOB: GITHUB TAG LATEST VERSION #############################################
@ -331,39 +242,16 @@ jobs:
runs-on: ubuntu-latest
needs: [upload_to_dockerhub]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetch full History for changelog
##########################################################################
# SET ENVS ###############################################################
##########################################################################
- name: ENV - VERSION
run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
- name: ENV - BUILD_DATE
run: echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
- name: ENV - BUILD_VERSION
run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: ENV - BUILD_COMMIT
run: echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
##########################################################################
# Push version tag to GitHub #############################################
##########################################################################
# TODO: this will error on duplicate
#- name: package-version-to-git-tag
# uses: pkgdeps/git-tag-action@v2
# with:
# github_token: ${{ secrets.GITHUB_TOKEN }}
# github_repo: ${{ github.repository }}
# version: ${{ env.VERSION }}
# git_commit_sha: ${{ github.sha }}
# git_tag_prefix: "v"
##########################################################################
# Push build tag to GitHub ###############################################
##########################################################################
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
- run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: package-version-to-git-tag + build number
uses: pkgdeps/git-tag-action@v2
with:
@ -372,13 +260,10 @@ jobs:
version: ${{ env.BUILD_VERSION }}
git_commit_sha: ${{ github.sha }}
git_tag_prefix: "b"
##########################################################################
# Push release tag to GitHub #############################################
##########################################################################
- name: yarn install
run: yarn install
- name: generate changelog
run: yarn auto-changelog --latest-version ${{ env.VERSION }} --unreleased-only
- name: Generate changelog
run: |
yarn install
yarn auto-changelog --latest-version ${{ env.VERSION }} --unreleased-only
- name: package-version-to-git-release
continue-on-error: true # Will fail if tag exists
id: create_release
@ -391,3 +276,101 @@ jobs:
body_path: ./CHANGELOG.md
draft: false
prerelease: false
build_trigger:
name: Trigger successful build
runs-on: ubuntu-latest
needs: [github_tag]
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetch full History for changelog
- name: Setup env
run: |
echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_ENV
echo "BUILD_COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
- run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v1
with:
token: ${{ github.token }}
event-type: trigger-build-success
repository: ${{ github.repository }}
client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "VERSION": "${VERSION}", "BUILD_DATE": "${BUILD_DATE}", "BUILD_COMMIT": "${BUILD_COMMIT}", "BUILD_VERSION": "${BUILD_VERSION}"}'
# ##############################################################################
# # JOB: KUBERNETES DEPLOY ACTUAL/LATEST VERSION ######################################
# ##############################################################################
# kubernetes_deploy:
# # see example https://github.com/do-community/example-doctl-action
# # see example https://github.com/do-community/example-doctl-action/blob/main/.github/workflows/workflow.yaml
# name: Kubernetes deploy of latest version to stage.ocelot.social cluster at DigitalOcean
# runs-on: ubuntu-latest
# needs: [upload_to_dockerhub]
# steps:
# ##########################################################################
# # CHECKOUT CODE ##########################################################
# ##########################################################################
# - name: Checkout code
# uses: actions/checkout@v3
# ##########################################################################
# # SET ENVS ###############################################################
# ##########################################################################
# - name: ENV - VERSION
# run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV
# - name: ENV - BUILD_VERSION
# run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV
# ##########################################################################
# # Install DigitalOceans doctl and set kubeconfig #########################
# ##########################################################################
# - name: Install doctl
# uses: digitalocean/action-doctl@v2
# with:
# token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
# - name: Save DigitalOcean kubeconfig with short-lived credentials
# run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 cluster-stage-ocelot-social
# ##########################################################################
# # Deploy new Docker images to DigitalOcean Kubernetes cluster ############
# ##########################################################################
# # - name: Deploy 'latest' to DigitalOcean Kubernetes
# # run: |
# # kubectl -n default set image deployment/ocelot-webapp container-ocelot-webapp=ocelotsocialnetwork/webapp:latest
# # kubectl -n default rollout restart deployment/ocelot-webapp
# # kubectl -n default set image deployment/ocelot-backend container-ocelot-backend=ocelotsocialnetwork/backend:latest
# # kubectl -n default rollout restart deployment/ocelot-backend
# # kubectl -n default set image deployment/ocelot-maintenance container-ocelot-maintenance=ocelotsocialnetwork/maintenance:latest
# # kubectl -n default rollout restart deployment/ocelot-maintenance
# # kubectl -n default set image deployment/ocelot-neo4j container-ocelot-neo4j=ocelotsocialnetwork/neo4j-community:latest
# # kubectl -n default rollout restart deployment/ocelot-neo4j
# - name: Deploy actual version '$BUILD_VERSION' to DigitalOcean Kubernetes
# run: |
# kubectl -n default set image deployment/ocelot-webapp container-ocelot-webapp=ocelotsocialnetwork/webapp:$BUILD_VERSION
# kubectl -n default rollout restart deployment/ocelot-webapp
# kubectl -n default set image deployment/ocelot-backend container-ocelot-backend=ocelotsocialnetwork/backend:$BUILD_VERSION
# kubectl -n default rollout restart deployment/ocelot-backend
# kubectl -n default set image deployment/ocelot-maintenance container-ocelot-maintenance=ocelotsocialnetwork/maintenance:$BUILD_VERSION
# kubectl -n default rollout restart deployment/ocelot-maintenance
# kubectl -n default set image deployment/ocelot-neo4j container-ocelot-neo4j=ocelotsocialnetwork/neo4j-community:$BUILD_VERSION
# kubectl -n default rollout restart deployment/ocelot-neo4j
# # because this step 'kubectl -n default rollout status deployment/* --timeout=600s' does not work as expected
# # and we need the pods to be up again for cleaning and seeding the Neo4j database and the backend.
# # !!! this is not a perfect solution !!!
# # deployments are regularly up again after 3 minutes and 10 seconds
# - name: Sleep for 4 minutes, means 240 seconds
# run: sleep 240s
# shell: bash
# - name: Verify deployment and wait for the pods of each deployment to get ready for cleaning and seeding of the database
# run: |
# kubectl -n default rollout status deployment/ocelot-backend --timeout=600s
# kubectl -n default rollout status deployment/ocelot-neo4j --timeout=600s
# kubectl -n default rollout status deployment/ocelot-maintenance --timeout=600s
# kubectl -n default rollout status deployment/ocelot-webapp --timeout=600s
# - name: Run migrations for Neo4j database via backend for staging
# run: |
# kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "yarn prod:migrate up"
# - name: Reset and seed Neo4j database via backend for staging
# # db cleaning and seeding is only possible in production if env 'PRODUCTION_DB_CLEAN_ALLOW=true' is set in deployment
# run: |
# kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await dist/db/clean.js && node --experimental-repl-await dist/db/seed.js"

View File

@ -16,7 +16,7 @@ jobs:
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
##########################################################################
# TODO: DO STUFF ??? #####################################################
##########################################################################
@ -37,7 +37,7 @@ jobs:
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
##########################################################################
# NEO4J ##################################################################
##########################################################################
@ -46,7 +46,7 @@ jobs:
docker build --target community -t "ocelotsocialnetwork/neo4j-community:test" neo4j/
docker save "ocelotsocialnetwork/neo4j-community:test" > /tmp/neo4j.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: docker-neo4j-image
path: /tmp/neo4j.tar
@ -63,7 +63,7 @@ jobs:
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
##########################################################################
# BUILD BACKEND DOCKER IMAGE (build) #####################################
##########################################################################
@ -72,7 +72,7 @@ jobs:
docker build --target test -t "ocelotsocialnetwork/backend:test" backend/
docker save "ocelotsocialnetwork/backend:test" > /tmp/backend.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: docker-backend-test
path: /tmp/backend.tar
@ -89,7 +89,7 @@ jobs:
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
##########################################################################
# BUILD WEBAPP DOCKER IMAGE (build) ######################################
##########################################################################
@ -98,7 +98,7 @@ jobs:
docker build --target test -t "ocelotsocialnetwork/webapp:test" webapp/
docker save "ocelotsocialnetwork/webapp:test" > /tmp/webapp.tar
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: docker-webapp-test
path: /tmp/webapp.tar
@ -115,12 +115,12 @@ jobs:
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
##########################################################################
# DOWNLOAD DOCKER IMAGE ##################################################
##########################################################################
- name: Download Docker Image (Backend)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-backend-test
path: /tmp
@ -144,12 +144,12 @@ jobs:
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
##########################################################################
# DOWNLOAD DOCKER IMAGE ##################################################
##########################################################################
- name: Download Docker Image (Webapp)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-webapp-test
path: /tmp
@ -168,24 +168,26 @@ jobs:
name: Unit tests - backend
runs-on: ubuntu-latest
needs: [build_test_neo4j,build_test_backend]
permissions:
checks: write
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
##########################################################################
# DOWNLOAD DOCKER IMAGES #################################################
##########################################################################
- name: Download Docker Image (Neo4J)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-neo4j-image
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/neo4j.tar
- name: Download Docker Image (Backend)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-backend-test
path: /tmp
@ -225,17 +227,19 @@ jobs:
name: Unit tests - webapp
runs-on: ubuntu-latest
needs: [build_test_webapp]
permissions:
checks: write
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
##########################################################################
# DOWNLOAD DOCKER IMAGES #################################################
##########################################################################
- name: Download Docker Image (Webapp)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-webapp-test
path: /tmp
@ -269,7 +273,7 @@ jobs:
report_name: Coverage Webapp
type: lcov
result_path: ./coverage/lcov.info
min_coverage: 63
min_coverage: 83
token: ${{ github.token }}
##############################################################################
@ -290,26 +294,26 @@ jobs:
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
##########################################################################
# DOWNLOAD DOCKER IMAGES #################################################
##########################################################################
- name: Download Docker Image (Neo4J)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-neo4j-image
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/neo4j.tar
- name: Download Docker Image (Backend)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-backend-test
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/backend.tar
- name: Download Docker Image (Webapp)
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: docker-webapp-test
path: /tmp
@ -332,12 +336,12 @@ jobs:
# UPLOAD SCREENSHOTS & VIDEO #############################################
##########################################################################
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: cypress-screenshots
path: cypress/screenshots/
- name: Upload Artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: cypress-videos
path: cypress/videos/

2
.nvmrc
View File

@ -1 +1 @@
v17.9.0
v19.4.0

View File

@ -4,8 +4,54 @@ All notable changes to this project will be documented in this file. Dates are d
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
#### [2.2.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.1.0...2.2.0)
#### [2.4.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/2.3.0...2.4.0)
- fix(webapp): post teaser width in mobile view [`#5958`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5958)
- fix(webapp): navbar disappears when scrolling to top [`#5957`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5957)
- fix(webapp): close mobile menu on all links [`#5956`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5956)
- feat(webapp): mark active filters on the posts [`#5952`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5952)
- refactor(webapp): refacchange postion add content button, refactor mobile filter menu [`#5943`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5943)
- refactor(webapp): set legend to map [`#5950`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5950)
- fix(webapp): small changes for deploy [`#5949`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5949)
- feat(webapp): hide navbar by scroll, filter button for content [`#5926`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5926)
- feat(webapp): map [`#5843`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5843)
- refactor(webapp): upgrade node version to 19.4 [`#5910`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5910)
- fix(webapp): texts for groups [`#5923`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5923)
- fix(webapp): add category name in tooltip [`#5884`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5884)
- refactor(webapp): 🍰 Refactor Social Media And `MySomethingList` [`#5138`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5138)
- fix(backend): do not expose registered emails on registration [`#5909`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5909)
- refactor(backend): node 19 with fixed image upload [`#5897`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5897)
- refactor(webapp): nump docker version to `16.19.0` in webapp & maintenance [`#5842`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5842)
- updated required packages for node19, fix fs-capacitator [`11087cb`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/11087cbaefde604668ac192b710666df09cb813c)
- fixed build error [`3889204`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/3889204f871df97b307401032900db7940913038)
- linting [`8bfe486`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/8bfe486034badd55a8096982f81aba08207b9e83)
#### [2.3.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/2.2.0...2.3.0)
> 5 December 2022
- chore(release): v2.3.0 [`#5768`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5768)
- feat(webapp): 🍰 Sort Categories By Name [`#5709`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5709)
- fix(backend): sanitize group description [`#5707`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5707)
- fix(webapp): clean up webapp unit tests [`#5711`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5711)
- feat(webapp): 🍰 Search Users To Add To Group [`#5652`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5652)
- feat(webapp): 🍰 Params For Category Filter [`#5699`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5699)
- fix(backend): 🍰 Misspelled Notification [`#5703`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5703)
- test(other): jest coverage report in console [`#5637`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5637)
- fix(webapp): centralize mobile hamburger menu [`#5674`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5674)
- refactor(backend): 🍰 Move `db/graphql` Folder Content To `graphql` Folder [`#5661`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5661)
- feat(other): semantic pullrequest workflow [`#5634`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5634)
- fix: Cannot Add Group Members as New Members to Group [`#5635`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5635)
- fix: My Groups Count Includes Pending Membership [`#5631`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5631)
- frontend: jest coverage [`f57e11d`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/f57e11dd021dbb156b33fbd5538cf5ca32df7334)
- reverted yarn lock [`a01aee8`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/a01aee89a92bbc9885e2895c577eb3c63042ba22)
- reverted all package updates [`a520089`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/a5200893f4508d45619447231b6789178a51daf7)
#### [2.2.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/2.1.0...2.2.0)
> 28 October 2022
- chore: 🍰 Release v2.2.0 [`#5610`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5610)
- refactor: 🍰 Refactor Design Of Category Filter In Filter Menu [`#5597`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5597)
- feat: 🍰 Footer And Header Links Configurable To Have External Link Target [`#5590`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5590)
- feat: 🍰 Header Menu To Component And Other Refinements [`#5546`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5546)
@ -19,10 +65,26 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- fix: 🍰 Fix Group Teaser [`#5584`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5584)
- feat: 🍰 List All Groups [`#5582`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5582)
- feat: 🍰 Header Logo Routing Update [`#5579`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5579)
- add header menu to component, central variabl for screen width [`401f59a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/401f59ae8de5b1c27f0e26e1f71778d3257d2180)
- comment out LanguagesFilter, EmotionsFilter, fix tests, fix lint [`52dcd77`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/52dcd772fa81e02a0d95e89a9fc8232e70a09d28)
- fix lint [`15561cb`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/15561cb94f8768e93846c25945c935ae83977553)
#### [2.1.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/2.0.0...2.1.0)
> 25 October 2022
- chore: 🍰 Release v2.1.0 [`#5574`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5574)
- feat: 🍰 EPIC Groups [`#5132`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5132)
- chore: 🍰 Remove Group Branchs `5059-epic-groups` Separate Auto-Deployment [`#5552`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5552)
- fix: [WIP] 🍰 Long Words Are Being Wrapped Now [`#5559`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5559)
- Remove groups separate auto-deployment [`c8d8168`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/c8d816887b2d49293d1b8ee2805d452fe10d907e)
- Release v2.1.0 [`dc085e9`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/dc085e9e69b288fce6dd06e8d7eb05ef34bd9a7b)
- Add database migration to auto-deployment on publish [`ef06f1a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/ef06f1a67d2654aaeb55d0434d3324a3ac37a380)
### [2.0.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.1.1...2.0.0)
> 23 October 2022
- feat: 🍰 Search For Groups [`#5543`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5543)
- feat: 🍰 Mobile Footer Menu To Header Menu [`#5524`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5524)
- feat: 🍰 Implement `LOGO_HEADER_CLICK` As Configuration [`#5525`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5525)
@ -39,25 +101,35 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- feat: 🍰 Group Members Management [`#5345`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5345)
- feat: 🍰 Have My Groups In The User Menu And Configure Groups Button In Header [`#5411`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5411)
- chore: 🍰 Implement Automatic Deployment For Groups Branch '5059-epic-groups' [`#5408`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5408)
- Chore: 🍰 Release v1.1.1 Refactor Rebranding [`#5392`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5392)
- chore: 🍰 Refactor Rebranding [`#5390`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5390)
- feat: 🍰 Group Profile Description Etc [`#5368`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5368)
- feat: 🍰 Tooltips For Topics [`#5350`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5350)
- feat: 🍰 Group Profile Members List Etc [`#5335`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5335)
- feat: 🍰 Implement Group Profile Visibility [`#5332`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5332)
- feat: 🍰 Save Categories In Frontend [`#5284`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5284)
- feat: 🍰 Add New Yunite Icons [`#5319`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5319)
- chore: 🍰 Update Neode From v^0.4.7 To v^0.4.8 In Backend [`#5334`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5334)
- feat: 🍰 My Groups Page [`#5148`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5148)
- feat: 🍰 Hidden Groups Shall Not Be Visible For None Or Pending Members In Backend [`#5317`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5317)
- feat: 🍰 Implement Group Profile [`#5197`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5197)
- feat: 🍰 Implement `UpdateGroup` Resolver [`#5224`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5224)
- feat: 🍰 Implement `JoinGroup`, `GroupMember`, `SwitchGroupMemberRole` Resolvers [`#5199`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5199)
- chore: 🍰 Add Groups To Seeding [`#5185`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5185)
- feat: 🍰 Implement Group GQL Model And CRUD Resolvers First Step [`#5139`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5139)
- Refine design and functionality of group list and create, edit group [`7b11122`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/7b11122bea4868624dd1c1641219e71070412e20)
- improved code and tests as suggested by @tirokk, thanks for the great review! [`631f34a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/631f34a2e5224d68279337a92e7535794b670d70)
- implement and test post visibilty when leaving or changing the role in a group [`76bfe48`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/76bfe484768cf9b20b2dced865d5d3e3eb999235)
#### [1.1.1](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.1.0...1.1.1)
> 22 September 2022
- Chore: 🍰 Release v1.1.1 Refactor Rebranding [`#5392`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5392)
- chore: 🍰 Refactor Rebranding [`#5390`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5390)
- feat: 🍰 Tooltips For Topics [`#5350`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5350)
- feat: 🍰 Save Categories In Frontend [`#5284`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5284)
- feat: 🍰 Add New Yunite Icons [`#5319`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5319)
- chore: 🍰 Update Neode From v^0.4.7 To v^0.4.8 In Backend [`#5334`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5334)
- fix: Category Filter Menu Client Only [`#5301`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5301)
- feat: Save Category Settings [`#5261`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5261)
- feat: 🍰 Implement `UpdateGroup` Resolver [`#5224`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5224)
- feat: Topics Menu [`#5248`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5248)
- docs: 🍰 Document GraqhQL Playground [`#5253`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5253)
- feat: Categories Filter Menu [`#5198`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5198)
- feat: 🍰 Implement `JoinGroup`, `GroupMember`, `SwitchGroupMemberRole` Resolvers [`#5199`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5199)
- fix: 🍰 Fix Test Description From `enter-nonce.vue` To `change-password` [`#5217`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5217)
- Bump cookie-universal-nuxt from 2.1.5 to 2.2.2 in /webapp [`#5218`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5218)
- Bump prettier from 2.2.1 to 2.7.1 in /webapp [`#5170`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5170)
@ -69,12 +141,10 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- feat: 🍰 Change Error Message With `Authorised` To `Authorized` All Over The Place To Have American English [`#5206`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5206)
- Bump cross-env from 7.0.2 to 7.0.3 in /webapp [`#5168`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5168)
- chore: 🍰 Add `--logHeapUsage` To Jest Test Call [`#5182`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5182)
- chore: 🍰 Add Groups To Seeding [`#5185`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5185)
- feat: 🍰 Implement Group GQL Model And CRUD Resolvers First Step [`#5139`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5139)
- refactor: 🍰 Rename `UserGroup` To `UserRole` [`#5143`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/5143)
- improved code and tests as suggested by @tirokk, thanks for the great review! [`631f34a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/631f34a2e5224d68279337a92e7535794b670d70)
- implement and test post visibilty when leaving or changing the role in a group [`76bfe48`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/76bfe484768cf9b20b2dced865d5d3e3eb999235)
- comment out LanguagesFilter, EmotionsFilter, fix tests, fix lint [`52dcd77`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/52dcd772fa81e02a0d95e89a9fc8232e70a09d28)
- add new yunite icons [`bb0d632`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/bb0d6329e7e36ea03671318ea8dd128a6d5a5a7a)
- cleanup refactor rebranding [`5f5c0fa`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/5f5c0faa1f28cd4df7681eba335ae5998b2d9cca)
- change color and scss in branding [`52070b8`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/52070b8c570970bf48df561134bf67cb4111b640)
#### [1.1.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/1.0.9...1.1.0)

View File

@ -105,7 +105,7 @@ Sprint retrospective
## Philosophy
We practise [collective code ownership](http://www.extremeprogramming.org/rules/collective.html) rather than strong code ownership, which means that:
We practice [collective code ownership](http://www.extremeprogramming.org/rules/collective.html) rather than strong code ownership, which means that:
* developers can make contributions to other people's PRs (after checking in with them)
* we avoid blocking because someone else isn't working, so we sometimes take over PRs from other developers
@ -115,7 +115,7 @@ We believe in open source contributions as a learning experience everyone is
We use pair programming sessions as a tool for knowledge sharing. We can learn a lot from each other and only by sharing what we know and overcoming challenges together can we grow as a team and truly own this project collectively.
As a volunteeer you have no commitment except your own self development and your awesomeness by contributing to this free and open-source software project. Cheers to you!
As a volunteer you have no commitment except your own self development and your awesomeness by contributing to this free and open-source software project. Cheers to you!
<!--
## Open-Source Bounties
@ -149,3 +149,86 @@ Our Open-Source bounty program is a work-in-progress. Based on our future
experience we will make changes and improvements. So keep an eye on this
contribution guide.
-->
## Programming
### Localization
#### Quotation Marks
The following characters are different from the programming quotation mark:
`"` or `\"`
Please copy and paste the following quotes for the languages:
* de: „Dies ist ein Beispielsatz.“
* en: “This is a sample sentence.”
* See <https://grammar.collinsdictionary.com/easy-learning/when-do-you-use-quotation-marks-or-in-english>
## Docker More Closely
### Apple M1 Platform
***Attention:** For using Docker commands in Apple M1 environments!*
#### Environment Variable For Apple M1 Platform
If you encounter trouble building the docker containers on an Apple M1 chip you can try to explicitly define the target platform docker builds and pulls images for:
```bash
# set env variable for your shell
$ export DOCKER_DEFAULT_PLATFORM=linux/amd64
```
Or alternatively use a `YAML` docker compose overwrite file with `platform: linux/amd64`.
### Analyzing Docker Builds
To analyze a Docker build, there is a wonderful tool called [dive](https://github.com/wagoodman/dive). Please sponsor if you're using it!
The `dive build` command is exactly the right one to fulfill what we are looking for.
We can use it just like the `docker build` command and get an analysis afterwards.
So, in our main folder, we use it in the following way:
```bash
# in main folder
$ dive build --target <layer-name> -t "ocelotsocialnetwork/<app-name>:local-<layer-name>" --build-arg BBUILD_DATE="<build-date>" --build-arg BBUILD_VERSION="<build-version>" --build-arg BBUILD_COMMIT="<build-commit>" <app-folder-name-or-dot>/
```
The build arguments are optional.
For the specific applications, we use them as follows.
#### Backend
##### Production For Backend
```bash
# in main folder
$ dive build --target production -t "ocelotsocialnetwork/backend:local-production" backend/
```
##### Development For Backend
```bash
# in main folder
$ dive build --target development -t "ocelotsocialnetwork/backend:local-development" backend/
```
#### Webapp
##### Production For Webapp
```bash
# in main folder
$ dive build --target production -t "ocelotsocialnetwork/webapp:local-production" webapp/
```
##### Development For Webapp
```bash
# in main folder
$ dive build --target development -t "ocelotsocialnetwork/webapp:local-development" webapp/
```

View File

@ -1,86 +0,0 @@
# Docker More Closely
## Apple M1 Platform
***Attention:** For using Docker commands in Apple M1 environments!*
### Enviroment Variable For Apple M1 Platform
To set the Docker platform environment variable in your terminal tab, run:
```bash
# set env variable for your shell
$ export DOCKER_DEFAULT_PLATFORM=linux/amd64
```
### Docker Compose Override File For Apple M1 Platform
For Docker compose `up` or `build` commands, you can use our Apple M1 override file that specifies the M1 platform:
```bash
# in main folder
# for development
$ docker compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.apple-m1.override.yml up
# only once: init admin user and create indexes and contraints in Neo4j database
$ docker compose exec backend yarn prod:migrate init
# clean db
$ docker compose exec backend yarn db:reset
# seed db
$ docker compose exec backend yarn db:seed
# for production
$ docker compose -f docker-compose.yml -f docker-compose.apple-m1.override.yml up
# only once: init admin user and create indexes and contraints in Neo4j database
$ docker compose exec backend /bin/sh -c "yarn prod:migrate init"
```
## Analysing Docker Builds
To analyze a Docker build, there is a wonderful tool called [dive](https://github.com/wagoodman/dive). Please sponsor if you're using it!
The `dive build` command is exactly the right one to fulfill what we are looking for.
We can use it just like the `docker build` command and get an analysis afterwards.
So, in our main folder, we use it in the following way:
```bash
# in main folder
$ dive build --target <layer-name> -t "ocelotsocialnetwork/<app-name>:local-<layer-name>" --build-arg BBUILD_DATE="<build-date>" --build-arg BBUILD_VERSION="<build-version>" --build-arg BBUILD_COMMIT="<build-commit>" <app-folder-name-or-dot>/
```
The build arguments are optional.
For the specific applications, we use them as follows.
### Backend
#### Production For Backend
```bash
# in main folder
$ dive build --target production -t "ocelotsocialnetwork/backend:local-production" backend/
```
#### Development For Backend
```bash
# in main folder
$ dive build --target development -t "ocelotsocialnetwork/backend:local-development" backend/
```
### Webapp
#### Production For Webapp
```bash
# in main folder
$ dive build --target production -t "ocelotsocialnetwork/webapp:local-production" webapp/
```
#### Development For Webapp
```bash
# in main folder
$ dive build --target development -t "ocelotsocialnetwork/webapp:local-development" webapp/
```

View File

@ -20,12 +20,71 @@ At the same time, it should be possible in the future to link these networks wit
In other words, we are interested in a network of networks and in keeping the data as close as possible to the user and the operator they trusts.
## Introduction
## Screenshots
<img src="https://user-images.githubusercontent.com/17728384/218597429-554e4082-3906-4721-8f68-0c13146fc218.png" alt="Post feed" title="Post feed" />
Check out more screenshots [here](/wiki/en:Screenshots).
## Features
Ocelot.social networks feature:
* <strong>user accounts</strong>
* <strong>user roles</strong>
* <strong>posts</strong> and <strong>comments</strong>
* <strong>groups</strong>
* <strong>maps</strong>
* <strong>search</strong>
* <strong>filters</strong>
* and more …
Check out the [full feature list](/wiki/en:FAQ#what-are-the-features).
## User Guide and Frequently Asked Questions
In the [wiki](/wiki) you can find more information.
* [User Guide](/wiki/en:User-Guide)
* [Frequently Asked Questions](/wiki/en:FAQ)
## Demo
Try out our live demo network, see [here](#live-demo-and-developer-logins).
## Help us
If you're wondering how you could help, there are plenty of ways, e.g.:
* Spread the good word about ocelot.social to make it more popular:
* Add the link [ocelot.social](https://ocelot.social) to your website.
* Give ocelot.social a Like at https://alternativeto.net/software/ocelot-social/.
* Star our project on GitHub at https://github.com/Ocelot-Social-Community/Ocelot-Social/.
* Promote it on your social networks.
* Tell your friends about it by word-of-mouth.
* Write a press article on ocelot.social or contact the editorial office of your local newspage or radio station.
* Take a [good first issue](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) or issues that need help. Make sure to read [CONTRIBUTING.md](/CONTRIBUTING.md) first though.
* Testing and [reporting](/issues/new/choose) bugs.
* Translating: Please [contact us](#contact).
* Reviewing and testing pull requests.
## Donate
Your donation is very welcome and helps to enhance and improve the network. This software is mostly developped and maintained by the association [busFaktor() e.V.](https://www.busfaktor.org/en). Please support us with a [donation](https://www.busfaktor.org/en/donations) to busFaktor() e.V.. Thanks a lot! ❤️
## Contact
Are you interested in operating your own ocelot.social network or becoming a user? Please contact us here:
* [hello@ocelot.social](mailto:hello@ocelot.social)
* [Discord](https://discord.com/invite/DFSjPaX)
## For Developers and Contributors
### Introduction
Have a look into our short video:
[ocelot.social - GitHub - Developer Welcome - Tutorial (english)](https://www.youtube.com/watch?v=gZSL6KvBIiY&list=PLFMD5liPP01kbuReHxYXxv_1fI5rIgS1f&index=1)
## Directory Layout
### Directory Layout
There are three important directories:
@ -41,9 +100,9 @@ There are two approaches:
1. [Local](#local-installation) installation, which means you have to take care of dependencies yourself.
2. **Or** Install everything through [Docker](#docker-installation) which takes care of dependencies for you.
## Installation
### Installation
### Clone the Repository
#### Clone the Repository
Clone the repository, this will create a new folder called `Ocelot-Social`:
@ -65,7 +124,7 @@ Change into the new folder.
$ cd Ocelot-Social
```
## Live Demo And Developer Logins
### Live Demo And Developer Logins
**Try out our deployed [development environment](https://stage.ocelot.social).**
@ -74,7 +133,7 @@ Visit our staging networks:
* central staging network: [stage.ocelot.social](https://stage.ocelot.social)
<!-- - rebranded staging network: [rebrand.ocelot.social](https://stage.ocelot.social). -->
### Login
#### Login
Logins for the live demos and developers (local developers after the following installations) in the browser:
@ -84,11 +143,11 @@ Logins for the live demos and developers (local developers after the following i
| `moderator@example.org` | 1234 | moderator |
| `admin@example.org` | 1234 | admin |
### Docker Installation
#### Docker Installation
Docker is a software development container tool that combines software and its dependencies into one standardized unit that contains everything needed to run it. This helps us to avoid problems with dependencies and makes installation easier.
#### General Installation of Docker
##### General Installation of Docker
There are [several ways to install Docker CE](https://docs.docker.com/install/) on your computer or server.
@ -105,7 +164,7 @@ $ docker-compose --version
docker-compose version 1.23.2
```
#### Start Ocelot-Social via Docker-Compose
##### Start Ocelot-Social via Docker-Compose
Prepare ENVs once beforehand:
@ -152,11 +211,11 @@ $ docker-compose exec backend yarn run db:seed
For a closer description see [backend README.md](./backend/README.md).
For a full documentation see [SUMMARY](./SUMMARY.md).
### Local Installation
#### Local Installation
For a full documentation see [SUMMARY](./SUMMARY.md).
## Contributing
### Contributing
Choose an issue (consider our label [good-first-issue](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)) and leave a comment there. We will then invite you to join our volunteers team.
To have the necessary permission to push directly to this repository, please accept our invitation to join our volunteers team, you will receive via the email, Github will send you, once invited. If we did not invite you yet, please request an invitation via Discord.
@ -182,7 +241,7 @@ $ yarn test
Check out our [contribution guideline](./CONTRIBUTING.md), too!
### Developer Chat
#### Developer Chat
Join our friendly open-source community on [Discord](https://discord.gg/AJSX9DCSUA) :heart_eyes_cat:
Just introduce yourself at `#introduce-yourself` and mention a mentor or `@@Mentors` to get you onboard :neckbeard:
@ -190,13 +249,13 @@ Just introduce yourself at `#introduce-yourself` and mention a mentor or `@@Ment
We give write permissions to every developer who asks for it. Just text us on
[Discord](https://discord.gg/AJSX9DCSUA).
## Deployment
### Deployment
Deployment methods can be found in the [Ocelot-Social-Deploy-Rebranding](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding) repository.
The only deployment method in this repository for development purposes as described above is `docker-compose`.
## Technology Stack
### Technology Stack
* [VueJS](https://vuejs.org/)
* [NuxtJS](https://nuxtjs.org/)
@ -204,7 +263,7 @@ The only deployment method in this repository for development purposes as descri
* [NodeJS](https://nodejs.org/en/)
* [Neo4J](https://neo4j.com/)
### For Testing
#### For Testing
* [Cypress](https://docs.cypress.io/)
* [Storybook](https://storybook.js.org/)
@ -212,7 +271,7 @@ The only deployment method in this repository for development purposes as descri
* [Vue Test Utils](https://vue-test-utils.vuejs.org/)
* [ESLint](https://eslint.org/)
## Attributions
### Attributions
Locale Icons made by [Freepik](http://www.freepik.com/) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).
@ -220,6 +279,6 @@ Browser compatibility testing with [BrowserStack](https://www.browserstack.com/)
<img alt="BrowserStack Logo" src=".gitbook/assets/browserstack-logo.svg" width="256">
## License
### License
See the [LICENSE](LICENSE.md) file for license rights and limitations (MIT).

View File

@ -1 +1 @@
v12.19.0
v19.4.0

View File

@ -1,7 +1,7 @@
##################################################################################
# BASE (Is pushed to DockerHub for rebranding) ###################################
##################################################################################
FROM node:12.19.0-alpine3.10 as base
FROM node:19.4.0-alpine3.17 as base
# ENVs
## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame
@ -35,7 +35,7 @@ LABEL maintainer="devops@ocelot.social"
# Install Additional Software
## install: git
RUN apk --no-cache add git
RUN apk --no-cache add git python3 make g++
# Settings
## Expose Container Port

View File

@ -19,12 +19,19 @@ Wait a little until your backend is up and running at [http://localhost:4000/](h
## Installation without Docker
For the local installation you need a recent version of
[node](https://nodejs.org/en/) (&gt;= `v10.12.0`). We are using
`12.19.0` and therefore we recommend to use the same version
[Node](https://nodejs.org/en/) (&gt;= `v16.19.0`). We are using
`v19.4.0` and therefore we recommend to use the same version
([see](https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4082)
some known problems with more recent node versions). You can use the
[node version manager](https://github.com/nvm-sh/nvm) to switch
between different local node versions.
[node version manager](https://github.com/nvm-sh/nvm) `nvm` to switch
between different local Node versions:
```bash
# install Node
$ cd backend
$ nvm install v19.4.0
$ nvm use v19.4.0
```
Install node dependencies with [yarn](https://yarnpkg.com/en/):
@ -32,6 +39,10 @@ Install node dependencies with [yarn](https://yarnpkg.com/en/):
# in main folder
$ cd backend
$ yarn install
# or just
$ yarn
# or just later on to use version of ".nvmrc" file
$ nvm use && yarn
```
Copy Environment Variables:
@ -68,9 +79,9 @@ More details about our GraphQL playground and how to use it with ocelot.social c
![GraphQL Playground](../.gitbook/assets/graphql-playground.png)
### Database Indices and Constraints
### Database Indexes and Constraints
Database indices and constraints need to be created when the database and the
Database indexes and constraints need to be created when the database and the
backend is running:
{% tabs %}
@ -78,7 +89,13 @@ backend is running:
```bash
# in main folder while docker-compose is running
$ docker-compose exec backend yarn run db:migrate init
$ docker exec backend yarn run db:migrate init
# only once: init admin user and create indexes and constraints in Neo4j database
# for development
$ docker compose exec backend yarn prod:migrate init
# in production mode use command
$ docker compose exec backend /bin/sh -c "yarn prod:migrate init"
```
{% endtab %}
@ -105,18 +122,18 @@ In another terminal run:
```bash
# in main folder while docker-compose is running
$ docker-compose exec backend yarn run db:seed
$ docker exec backend yarn run db:seed
```
To reset the database run:
```bash
# in main folder while docker-compose is running
$ docker-compose exec backend yarn run db:reset
$ docker exec backend yarn run db:reset
# you could also wipe out your neo4j database and delete all volumes with:
$ docker-compose down -v
# if container is not running, run this command to set up your database indeces and contstraints
$ docker-compose exec backend yarn run db:migrate init
# if container is not running, run this command to set up your database indexes and constraints
$ docker exec backend yarn run db:migrate init
```
{% endtab %}
@ -159,7 +176,7 @@ To run the migration:
```bash
# in main folder while docker-compose is running
$ docker-compose exec backend yarn run db:migrate up
$ docker exec backend yarn run db:migrate up
```
{% endtab %}
@ -195,7 +212,7 @@ Run the unit tests:
```bash
# in main folder while docker-compose is running
$ docker-compose exec backend yarn run test
$ docker exec backend yarn run test
```
{% endtab %}

14
backend/jest.config.js Normal file
View File

@ -0,0 +1,14 @@
module.exports = {
verbose: true,
collectCoverage: true,
collectCoverageFrom: [
'**/*.js',
'!**/node_modules/**',
'!**/test/**',
'!**/dist/**',
'!**/src/**/?(*.)+(spec|test).js?(x)'
],
coverageReporters: ['lcov', 'text'],
testMatch: ['**/src/**/?(*.)+(spec|test).js?(x)'],
setupFilesAfterEnv: ['<rootDir>/test/setup.js']
}

View File

@ -1,6 +1,6 @@
{
"name": "ocelot-social-backend",
"version": "2.2.0",
"version": "2.4.0",
"description": "GraphQL Backend for ocelot.social",
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
"author": "ocelot.social Community",
@ -15,29 +15,13 @@
"dev": "nodemon --exec babel-node src/ -e js,gql",
"dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/ -e js,gql",
"lint": "eslint src --config .eslintrc.js",
"test": "cross-env NODE_ENV=test NODE_OPTIONS=--max-old-space-size=8192 jest --forceExit --detectOpenHandles --runInBand --coverage --logHeapUsage",
"test": "cross-env NODE_ENV=test NODE_OPTIONS=--max-old-space-size=8192 jest --runInBand --coverage --forceExit --detectOpenHandles",
"db:clean": "babel-node src/db/clean.js",
"db:reset": "yarn run db:clean",
"db:seed": "babel-node src/db/seed.js",
"db:migrate": "yarn run __migrate --store ./src/db/migrate/store.js",
"db:migrate:create": "yarn run __migrate --template-file ./src/db/migrate/template.js --date-format 'yyyymmddHHmmss' create"
},
"jest": {
"verbose": true,
"collectCoverageFrom": [
"**/*.js",
"!**/node_modules/**",
"!**/test/**",
"!**/dist/**",
"!**/src/**/?(*.)+(spec|test).js?(x)"
],
"coverageReporters": [
"lcov"
],
"testMatch": [
"**/src/**/?(*.)+(spec|test).js?(x)"
]
},
"dependencies": {
"@babel/cli": "~7.8.4",
"@babel/core": "~7.9.0",
@ -81,22 +65,22 @@
"linkifyjs": "~2.1.8",
"lodash": "~4.17.14",
"merge-graphql-schemas": "^1.7.8",
"metascraper": "^5.11.8",
"metascraper-audio": "^5.14.26",
"metascraper-author": "^5.14.22",
"metascraper": "^5.33.5",
"metascraper-audio": "^5.33.5",
"metascraper-author": "^5.33.5",
"metascraper-clearbit-logo": "^5.3.0",
"metascraper-date": "^5.11.8",
"metascraper-description": "^5.23.1",
"metascraper-image": "^5.11.8",
"metascraper-lang": "^5.23.1",
"metascraper-date": "^5.33.5",
"metascraper-description": "^5.33.5",
"metascraper-image": "^5.33.5",
"metascraper-lang": "^5.33.5",
"metascraper-lang-detector": "^4.10.2",
"metascraper-logo": "^5.14.26",
"metascraper-publisher": "^5.23.0",
"metascraper-soundcloud": "^5.23.0",
"metascraper-title": "^5.11.8",
"metascraper-url": "^5.14.26",
"metascraper-video": "^5.11.8",
"metascraper-youtube": "^5.23.0",
"metascraper-logo": "^5.33.5",
"metascraper-publisher": "^5.33.5",
"metascraper-soundcloud": "^5.33.5",
"metascraper-title": "^5.33.5",
"metascraper-url": "^5.33.5",
"metascraper-video": "^5.33.5",
"metascraper-youtube": "^5.33.5",
"migrate": "^1.7.0",
"mime-types": "^2.1.26",
"minimatch": "^3.0.4",
@ -132,13 +116,15 @@
"eslint-plugin-prettier": "~3.4.1",
"eslint-plugin-promise": "~4.3.1",
"eslint-plugin-standard": "~4.0.1",
"jest": "~25.3.0",
"jest": "29.4",
"nodemon": "~2.0.2",
"prettier": "~2.3.2",
"rosie": "^2.0.1",
"supertest": "~4.0.2"
},
"resolutions": {
"fs-capacitor": "6.0.0"
"**/**/fs-capacitor": "^6.2.0",
"**/graphql-upload": "^11.0.0",
"nan": "2.17.0"
}
}

View File

@ -33,6 +33,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543

View File

@ -1,3 +1,3 @@
// this file is duplicated in `backend/src/constants/group.js` and `webapp/constants/group.js`
export const DESCRIPTION_WITHOUT_HTML_LENGTH_MIN = 100 // with removed HTML tags
export const DESCRIPTION_WITHOUT_HTML_LENGTH_MIN = 50 // with removed HTML tags
export const DESCRIPTION_EXCERPT_HTML_LENGTH = 250 // with removed HTML tags

View File

@ -65,7 +65,6 @@ Factory.define('basicUser')
name: faker.name.findName,
password: '1234',
role: 'user',
about: faker.lorem.paragraph,
termsAndConditionsAgreedVersion: '0.0.1',
termsAndConditionsAgreedAt: '2019-08-01T10:47:19.212Z',
allowEmbedIframes: false,
@ -82,12 +81,28 @@ Factory.define('basicUser')
Factory.define('userWithoutEmailAddress')
.extend('basicUser')
.option('about', faker.lorem.paragraph)
.after(async (buildObject, options) => {
return neode.create('User', buildObject)
})
Factory.define('userWithAboutNull')
.extend('basicUser')
.option('about', null)
.after(async (buildObject, options) => {
return neode.create('User', buildObject)
})
Factory.define('userWithAboutEmpty')
.extend('basicUser')
.option('about', '')
.after(async (buildObject, options) => {
return neode.create('User', buildObject)
})
Factory.define('user')
.extend('basicUser')
.option('about', faker.lorem.paragraph)
.option('email', faker.internet.exampleEmail)
.option('avatar', () =>
Factory.build('image', {

View File

@ -85,7 +85,7 @@ class Store {
await createDefaultAdminUser(session)
if (CONFIG.CATEGORIES_ACTIVE) await createCategories(session)
const writeTxResultPromise = session.writeTransaction(async (txc) => {
await txc.run('CALL apoc.schema.assert({},{},true)') // drop all indices and contraints
await txc.run('CALL apoc.schema.assert({},{},true)') // drop all indices and constraints
return Promise.all(
[
'CALL db.index.fulltext.createNodeIndex("user_fulltext_search",["User"],["name", "slug"])',

View File

@ -1,13 +1,3 @@
// TODO: can be replaced with: (which is no a fake)
// import gql from 'graphql-tag'
// See issue: https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/5152
//* This is a fake ES2015 template string, just to benefit of syntax
// highlighting of `gql` template strings in certain editors.
export function gql(strings) {
return strings.join('')
}
// sometime we have to wait to check a db state by having a look into the db in a certain moment
// or we wait a bit to check if we missed to set an await somewhere
// see: https://www.sitepoint.com/delay-sleep-pause-wait/

View File

@ -2,24 +2,26 @@
* iterate through all fields and replace it with the callback result
* @property data Array
* @property fields Array
* @property fieldName String
* @property callback Function
*/
function walkRecursive(data, fields, callback, _key) {
function walkRecursive(data, fields, fieldName, callback, _key) {
if (!Array.isArray(fields)) {
throw new Error('please provide an fields array for the walkRecursive helper')
}
if (data && typeof data === 'string' && fields.includes(_key)) {
// well we found what we searched for, lets replace the value with our callback result
data = callback(data, _key)
const key = _key.split('!')
if (key.length === 1 || key[1] !== fieldName) data = callback(data, key[0])
} else if (data && Array.isArray(data)) {
// go into the rabbit hole and dig through that array
data.forEach((res, index) => {
data[index] = walkRecursive(data[index], fields, callback, index)
data[index] = walkRecursive(data[index], fields, fieldName, callback, index)
})
} else if (data && typeof data === 'object') {
// lets get some keys and stir them
Object.keys(data).forEach((k) => {
data[k] = walkRecursive(data[k], fields, callback, k)
data[k] = walkRecursive(data[k], fields, fieldName, callback, k)
})
}
return data

View File

@ -36,6 +36,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543

View File

@ -1,4 +1,4 @@
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { cleanDatabase } from '../../db/factories'
import { createTestClient } from 'apollo-server-testing'
import { getNeode, getDriver } from '../../db/neo4j'
@ -50,6 +50,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -80,14 +80,6 @@ const testEmailData = (emailTemplate, templateBuilder, templateData, texts) => {
return emailTemplate
}
// beforeAll(async () => {
// await cleanDatabase()
// })
// afterAll(async () => {
// await cleanDatabase()
// })
describe('templateBuilder', () => {
describe('signupTemplate', () => {
describe('multi language', () => {

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
@ -28,6 +28,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
const createPostMutation = gql`

View File

@ -10,10 +10,13 @@ const sendSignupMail = async (resolve, root, args, context, resolveInfo) => {
const { inviteCode } = args
const response = await resolve(root, args, context, resolveInfo)
const { email, nonce } = response
if (inviteCode) {
await sendMail(signupTemplate({ email, variables: { nonce, inviteCode } }))
} else {
await sendMail(signupTemplate({ email, variables: { nonce } }))
if (nonce) {
// emails that already exist do not have a nonce
if (inviteCode) {
await sendMail(signupTemplate({ email, variables: { nonce, inviteCode } }))
} else {
await sendMail(signupTemplate({ email, variables: { nonce } }))
}
}
delete response.nonce
return response
@ -30,7 +33,9 @@ const sendPasswordResetMail = async (resolve, root, args, context, resolveInfo)
const sendEmailVerificationMail = async (resolve, root, args, context, resolveInfo) => {
const response = await resolve(root, args, context, resolveInfo)
const { email, nonce, name } = response
await sendMail(emailVerificationTemplate({ email, variables: { nonce, name } }))
if (nonce) {
await sendMail(emailVerificationTemplate({ email, variables: { nonce, name } }))
}
delete response.nonce
return response
}

View File

@ -1,4 +1,4 @@
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { cleanDatabase } from '../../db/factories'
import { createTestClient } from 'apollo-server-testing'
import { getNeode, getDriver } from '../../db/neo4j'
@ -56,6 +56,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -1,4 +1,4 @@
import { gql } from '../helpers/jest'
import gql from 'graphql-tag'
import { cleanDatabase } from '../db/factories'
import { getNeode, getDriver } from '../db/neo4j'
import { createTestClient } from 'apollo-server-testing'
@ -24,6 +24,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -1,7 +1,7 @@
import { createTestClient } from 'apollo-server-testing'
import createServer from '../server'
import Factory, { cleanDatabase } from '../db/factories'
import { gql } from '../helpers/jest'
import gql from 'graphql-tag'
import { getDriver, getNeode } from '../db/neo4j'
import CONFIG from '../config'
@ -28,6 +28,7 @@ describe('authorization', () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543

View File

@ -33,6 +33,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {
@ -152,7 +153,7 @@ describe('slugifyMiddleware', () => {
})
describe('but if the client specifies a slug', () => {
it('rejects CreateGroup', async (done) => {
it('rejects CreateGroup', async () => {
try {
await expect(
mutate({
@ -171,7 +172,6 @@ describe('slugifyMiddleware', () => {
},
],
})
done()
} catch (error) {
throw new Error(`
${error}
@ -258,7 +258,7 @@ describe('slugifyMiddleware', () => {
})
describe('setting slug explicitly', () => {
it('rejects UpdateGroup', async (done) => {
it('rejects UpdateGroup', async () => {
try {
await expect(
mutate({
@ -275,7 +275,6 @@ describe('slugifyMiddleware', () => {
},
],
})
done()
} catch (error) {
throw new Error(`
${error}
@ -382,7 +381,7 @@ describe('slugifyMiddleware', () => {
})
describe('but if the client specifies a slug', () => {
it('rejects CreatePost', async (done) => {
it('rejects CreatePost', async () => {
try {
await expect(
mutate({
@ -402,7 +401,6 @@ describe('slugifyMiddleware', () => {
},
],
})
done()
} catch (error) {
throw new Error(`
${error}

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
@ -195,6 +195,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
describe('softDeleteMiddleware', () => {

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../db/factories'
import { gql } from '../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../db/neo4j'
import createServer from '../server'
import { createTestClient } from 'apollo-server-testing'
@ -42,6 +42,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
describe('middleware/userInteractions', () => {

View File

@ -1,4 +1,4 @@
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import Factory, { cleanDatabase } from '../../db/factories'
import { getNeode, getDriver } from '../../db/neo4j'
import { createTestClient } from 'apollo-server-testing'
@ -75,6 +75,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -1,15 +1,22 @@
import walkRecursive from '../helpers/walkRecursive'
import { cleanHtml } from '../middleware/helpers/cleanHtml.js'
const fields = ['content', 'contentExcerpt', 'reasonDescription']
// exclamation mark separetes field names, that should not be sanitized
const fields = [
'content',
'contentExcerpt',
'reasonDescription',
'description!embed',
'descriptionExcerpt',
]
export default {
Mutation: async (resolve, root, args, context, info) => {
args = walkRecursive(args, fields, cleanHtml)
args = walkRecursive(args, fields, info.fieldName, cleanHtml)
return resolve(root, args, context, info)
},
Query: async (resolve, root, args, context, info) => {
const result = await resolve(root, args, context, info)
return walkRecursive(result, fields, cleanHtml)
return walkRecursive(result, fields, info.fieldName, cleanHtml)
},
}

View File

@ -1,6 +1,7 @@
import { cleanDatabase } from '../db/factories'
import { getNeode } from '../db/neo4j'
import { getNeode, getDriver } from '../db/neo4j'
const driver = getDriver()
const neode = getNeode()
beforeAll(async () => {
@ -9,6 +10,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
@ -37,11 +39,10 @@ describe('slug', () => {
)
})
it('must be unique', async (done) => {
it('must be unique', async () => {
await neode.create('User', { slug: 'Matt' })
try {
await expect(neode.create('User', { slug: 'Matt' })).rejects.toThrow('already exists')
done()
} catch (error) {
throw new Error(`
${error}

View File

@ -11,7 +11,7 @@ export default makeAugmentedSchema({
'Badge',
'Embed',
'EmailAddress',
'Notfication',
'Notification',
'Statistics',
'LoggedInUser',
'Location',

View File

@ -0,0 +1,7 @@
import { GraphQLUpload } from 'graphql-upload'
export default {
// This maps the `Upload` scalar to the implementation provided
// by the `graphql-upload` package.
Upload: GraphQLUpload,
}

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { createTestClient } from 'apollo-server-testing'
import createServer from '../../server'
import { getNeode, getDriver } from '../../db/neo4j'
@ -25,6 +25,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -1,6 +1,6 @@
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
@ -37,6 +37,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
describe('donations', () => {

View File

@ -40,7 +40,9 @@ export default {
}
// check email does not belong to anybody
await existingEmailAddress({ args, context })
const existingEmail = await existingEmailAddress({ args, context })
if (existingEmail && existingEmail.alreadyExistingEmail && existingEmail.user)
return existingEmail.alreadyExistingEmail
const nonce = generateNonce()
const {

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getDriver, getNeode } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
@ -30,6 +30,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {
@ -134,11 +135,17 @@ describe('AddEmailAddress', () => {
})
describe('but if another user owns an `EmailAddress` already with that email', () => {
it('throws UserInputError because of unique constraints', async () => {
it('does not throw UserInputError', async () => {
await Factory.build('user', {}, { email: 'new-email@example.org' })
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
data: { AddEmailAddress: null },
errors: [{ message: 'A user account with this email already exists.' }],
data: {
AddEmailAddress: {
createdAt: expect.any(String),
verifiedAt: null,
email: 'new-email@example.org',
},
},
errors: undefined,
})
})
})

View File

@ -3,7 +3,7 @@ import fs from 'fs'
import path from 'path'
import { createTestClient } from 'apollo-server-testing'
import createServer from '../../server'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
jest.mock('node-fetch')
const { Response } = jest.requireActual('node-fetch')
@ -96,7 +96,7 @@ describe('Query', () => {
description: null,
html: null,
image: null,
lang: null,
lang: 'false',
publisher: null,
sources: ['resource'],
title: null,

View File

@ -2,7 +2,7 @@ import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { getDriver, getNeode } from '../../db/neo4j'
import createServer from '../../server'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
const driver = getDriver()
const neode = getNeode()
@ -71,6 +71,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -252,6 +252,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
describe('in mode', () => {

View File

@ -1,5 +1,3 @@
import { UserInputError } from 'apollo-server'
export default async function alreadyExistingMail({ args, context }) {
const session = context.driver.session()
try {
@ -20,9 +18,11 @@ export default async function alreadyExistingMail({ args, context }) {
})
})
const [emailBelongsToUser] = await existingEmailAddressTxPromise
const { alreadyExistingEmail, user } = emailBelongsToUser || {}
if (user) throw new UserInputError('A user account with this email already exists.')
return alreadyExistingEmail
/*
const { alreadyExistingEmail, user } =
if (user) throw new UserInputError('A user account with this email already exists.')
*/
return emailBelongsToUser || {}
} finally {
session.close()
}

View File

@ -0,0 +1,40 @@
import { mergeWith, isArray } from 'lodash'
const getMyGroupIds = async (context) => {
const { user } = context
if (!(user && user.id)) return []
const session = context.driver.session()
const readTxResultPromise = await session.readTransaction(async (transaction) => {
const cypher = `
MATCH (group:Group)<-[membership:MEMBER_OF]-(:User { id: $userId })
WHERE membership.role IN ['usual', 'admin', 'owner']
RETURN collect(group.id) AS myGroupIds`
const getMyGroupIdsResponse = await transaction.run(cypher, { userId: user.id })
return getMyGroupIdsResponse.records.map((record) => record.get('myGroupIds'))
})
try {
const [myGroupIds] = readTxResultPromise
return myGroupIds
} finally {
session.close()
}
}
export const filterPostsOfMyGroups = async (params, context) => {
if (!(params.filter && params.filter.postsInMyGroups)) return params
delete params.filter.postsInMyGroups
const myGroupIds = await getMyGroupIds(context)
params.filter = mergeWith(
params.filter,
{
group: { id_in: myGroupIds },
},
(objValue, srcValue) => {
if (isArray(objValue)) {
return objValue.concat(srcValue)
}
},
)
return params
}

View File

@ -113,10 +113,11 @@ const sanitizeRelationshipType = (relationshipType) => {
const localFileUpload = ({ createReadStream, uniqueFilename }) => {
const destination = `/uploads/${uniqueFilename}`
return new Promise((resolve, reject) =>
createReadStream()
.pipe(createWriteStream(`public${destination}`))
.on('finish', () => resolve(destination))
.on('error', reject),
createReadStream().pipe(
createWriteStream(`public${destination}`)
.on('finish', () => resolve(destination))
.on('error', (error) => reject(error)),
),
)
}

View File

@ -15,6 +15,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {
@ -78,7 +79,7 @@ describe('deleteImage', () => {
await expect(someString).toEqual('Hello')
})
it('rolls back the transaction in case of errors', async (done) => {
it('rolls back the transaction in case of errors', async () => {
await expect(neode.all('Image')).resolves.toHaveLength(1)
const session = driver.session()
try {
@ -93,7 +94,6 @@ describe('deleteImage', () => {
// nothing has been deleted
await expect(neode.all('Image')).resolves.toHaveLength(1)
// all good
done()
} finally {
session.close()
}
@ -239,7 +239,7 @@ describe('mergeImage', () => {
})
})
it('rolls back the transaction in case of errors', async (done) => {
it('rolls back the transaction in case of errors', async () => {
const session = driver.session()
try {
await session.writeTransaction(async (transaction) => {
@ -254,7 +254,6 @@ describe('mergeImage', () => {
// nothing has been created
await expect(neode.all('Image')).resolves.toHaveLength(0)
// all good
done()
} finally {
session.close()
}

View File

@ -1,6 +1,6 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { getDriver } from '../../db/neo4j'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
import CONSTANTS_REGISTRATION from './../../constants/registration'
@ -52,6 +52,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
describe('inviteCodes', () => {

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
@ -26,6 +26,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543

View File

@ -1,6 +1,6 @@
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
@ -70,6 +70,7 @@ describe('moderate resources', () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getDriver } from '../../db/neo4j'
import { createTestClient } from 'apollo-server-testing'
import createServer from '../.././server'
@ -34,6 +34,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import CONSTANTS_REGISTRATION from './../../constants/registration'
import createPasswordReset from './helpers/createPasswordReset'
@ -38,6 +38,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(() => {

View File

@ -6,6 +6,7 @@ import { mergeImage, deleteImage } from './images/images'
import Resolver from './helpers/Resolver'
import { filterForMutedUsers } from './helpers/filterForMutedUsers'
import { filterInvisiblePosts } from './helpers/filterInvisiblePosts'
import { filterPostsOfMyGroups } from './helpers/filterPostsOfMyGroups'
import CONFIG from '../../config'
const maintainPinnedPosts = (params) => {
@ -21,12 +22,14 @@ const maintainPinnedPosts = (params) => {
export default {
Query: {
Post: async (object, params, context, resolveInfo) => {
params = await filterPostsOfMyGroups(params, context)
params = await filterInvisiblePosts(params, context)
params = await filterForMutedUsers(params, context)
params = await maintainPinnedPosts(params)
return neo4jgraphql(object, params, context, resolveInfo)
},
profilePagePosts: async (object, params, context, resolveInfo) => {
params = await filterPostsOfMyGroups(params, context)
params = await filterInvisiblePosts(params, context)
params = await filterForMutedUsers(params, context)
return neo4jgraphql(object, params, context, resolveInfo)

View File

@ -1,6 +1,6 @@
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
@ -56,6 +56,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -61,6 +61,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
describe('Posts in Groups', () => {
@ -1677,5 +1678,59 @@ describe('Posts in Groups', () => {
})
})
})
describe('filter posts in my groups', () => {
describe('without any posts in groups', () => {
beforeAll(async () => {
authenticatedUser = await anyUser.toJson()
})
it('finds no posts', async () => {
const result = await query({
query: filterPosts(),
variables: { filter: { postsInMyGroups: true } },
})
expect(result.data.Post).toHaveLength(0)
expect(result).toMatchObject({
data: {
Post: [],
},
errors: undefined,
})
})
})
describe('with posts in groups', () => {
beforeAll(async () => {
// member of hidden-group and closed-group
authenticatedUser = await allGroupsUser.toJson()
})
it('finds two posts', async () => {
const result = await query({
query: filterPosts(),
variables: { filter: { postsInMyGroups: true } },
})
expect(result.data.Post).toHaveLength(2)
expect(result).toMatchObject({
data: {
Post: expect.arrayContaining([
{
id: 'post-to-closed-group',
title: 'A post to a closed group',
content: 'I am posting into a closed group as a member of the group',
},
{
id: 'post-to-hidden-group',
title: 'A post to a hidden group',
content: 'I am posting into a hidden group as a member of the group',
},
]),
},
errors: undefined,
})
})
})
})
})
})

View File

@ -13,7 +13,12 @@ export default {
args.nonce = generateNonce()
args.email = normalizeEmail(args.email)
let emailAddress = await existingEmailAddress({ args, context })
if (emailAddress) return emailAddress
/*
if (emailAddress.user) {
// what to do?
}
*/
if (emailAddress.alreadyExistingEmail) return emailAddress.alreadyExistingEmail
try {
emailAddress = await neode.create('EmailAddress', args)
return emailAddress.toJson()

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getDriver, getNeode } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
@ -29,6 +29,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {
@ -118,9 +119,9 @@ describe('Signup', () => {
await emailAddress.relateTo(user, 'belongsTo')
})
it('throws UserInputError error because of unique constraint violation', async () => {
it('does not throw UserInputError error', async () => {
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
errors: [{ message: 'A user account with this email already exists.' }],
data: { Signup: { email: 'someuser@example.org' } },
})
})
})

View File

@ -1,7 +1,7 @@
import { createTestClient } from 'apollo-server-testing'
import createServer from '../.././server'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getDriver, getNeode } from '../../db/neo4j'
const instance = getNeode()
@ -117,6 +117,7 @@ describe('file a report on a resource', () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543

View File

@ -1,6 +1,6 @@
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
@ -33,6 +33,7 @@ describe('rewards', () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
@ -26,6 +26,8 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
neode.close()
})
const searchQuery = gql`

View File

@ -1,6 +1,6 @@
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
@ -51,6 +51,7 @@ describe('shout and unshout posts', () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(async () => {

View File

@ -1,7 +1,7 @@
import { createTestClient } from 'apollo-server-testing'
import createServer from '../../server'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getDriver } from '../../db/neo4j'
const driver = getDriver()
@ -12,6 +12,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
describe('SocialMedia', () => {

View File

@ -1,6 +1,6 @@
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
@ -39,6 +39,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
@ -60,6 +60,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
describe('resolvers/userData', () => {

View File

@ -1,15 +1,17 @@
import jwt from 'jsonwebtoken'
import CONFIG from './../../config'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { loginMutation } from '../../graphql/userManagement'
import { createTestClient } from 'apollo-server-testing'
import createServer, { context } from '../../server'
import encode from '../../jwt/encode'
import { getNeode } from '../../db/neo4j'
import { getNeode, getDriver } from '../../db/neo4j'
import { categories } from '../../constants/categories'
const neode = getNeode()
const driver = getDriver()
let query, mutate, variables, req, user
const disable = async (id) => {
@ -47,6 +49,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(() => {
@ -137,7 +140,12 @@ describe('currentUser', () => {
describe('authenticated', () => {
describe('and corresponding user in the database', () => {
let avatar
beforeEach(async () => {
avatar = await Factory.build('image', {
url: 'https://s3.amazonaws.com/uifaces/faces/twitter/jimmuirhead/128.jpg',
})
await Factory.build(
'user',
{
@ -149,9 +157,7 @@ describe('currentUser', () => {
},
{
email: 'test@example.org',
avatar: Factory.build('image', {
url: 'https://s3.amazonaws.com/uifaces/faces/twitter/jimmuirhead/128.jpg',
}),
avatar,
},
)
const userBearerToken = encode({ id: 'u3' })
@ -163,9 +169,11 @@ describe('currentUser', () => {
data: {
currentUser: {
id: 'u3',
avatar: Factory.build('image', {
url: 'https://s3.amazonaws.com/uifaces/faces/twitter/jimmuirhead/128.jpg',
}),
avatar: {
url: expect.stringContaining(
'https://s3.amazonaws.com/uifaces/faces/twitter/jimmuirhead/128.jpg',
),
},
email: 'test@example.org',
name: 'Matilde Hermiston',
slug: 'matilde-hermiston',
@ -243,7 +251,7 @@ describe('login', () => {
describe('ask for a `token`', () => {
describe('with a valid email/password combination', () => {
it('responds with a JWT bearer token', async (done) => {
it('responds with a JWT bearer token', async () => {
const {
data: { login: token },
} = await mutate({ mutation: loginMutation, variables })
@ -252,7 +260,6 @@ describe('login', () => {
id: 'acb2d923-f3af-479e-9f00-61b12e864666',
})
expect(err).toBeNull()
done()
})
})

View File

@ -1,5 +1,5 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
@ -81,6 +81,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543

View File

@ -1,4 +1,4 @@
import { gql } from '../../../helpers/jest'
import gql from 'graphql-tag'
import Factory, { cleanDatabase } from '../../../db/factories'
import { getNeode, getDriver } from '../../../db/neo4j'
import { createTestClient } from 'apollo-server-testing'
@ -90,6 +90,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(() => {

View File

@ -1,7 +1,7 @@
import { createTestClient } from 'apollo-server-testing'
import createServer from '../../../server'
import { cleanDatabase } from '../../../db/factories'
import { gql } from '../../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../../db/neo4j'
const driver = getDriver()
@ -18,6 +18,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
beforeEach(() => {

View File

@ -1,6 +1,6 @@
import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import gql from 'graphql-tag'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
@ -28,6 +28,7 @@ beforeAll(async () => {
afterAll(async () => {
await cleanDatabase()
driver.close()
})
describe('count post teaser views', () => {

View File

@ -82,6 +82,7 @@ input _PostFilter {
emotions_single: _PostEMOTEDFilter
emotions_every: _PostEMOTEDFilter
group: _GroupFilter
postsInMyGroups: Boolean
}
enum _PostOrdering {

View File

@ -12,6 +12,7 @@ import { RedisPubSub } from 'graphql-redis-subscriptions'
import { PubSub } from 'graphql-subscriptions'
import Redis from 'ioredis'
import bodyParser from 'body-parser'
import { graphqlUploadExpress } from 'graphql-upload'
export const NOTIFICATION_ADDED = 'NOTIFICATION_ADDED'
const { REDIS_DOMAIN, REDIS_PORT, REDIS_PASSWORD } = CONFIG
@ -67,6 +68,7 @@ const createServer = (options) => {
},
},
debug: !!CONFIG.DEBUG,
uploads: false,
tracing: !!CONFIG.DEBUG,
formatError: (error) => {
if (error.message === 'ERROR_VALIDATION') {
@ -85,6 +87,7 @@ const createServer = (options) => {
app.use(express.static('public'))
app.use(bodyParser.json({ limit: '10mb' }))
app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }))
app.use(graphqlUploadExpress())
server.applyMiddleware({ app, path: '/' })
const httpServer = http.createServer(app)
server.installSubscriptionHandlers(httpServer)

8
backend/test/setup.js Normal file
View File

@ -0,0 +1,8 @@
// Polyfill missing encoders in jsdom
// https://stackoverflow.com/questions/68468203/why-am-i-getting-textencoder-is-not-defined-in-jest
import { TextEncoder, TextDecoder } from 'util'
global.TextEncoder = TextEncoder
global.TextDecoder = TextDecoder
// Metascraper takes longer nowadays, double time
jest.setTimeout(10000)

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
{
"projectId": "qa7fe2",
"defaultCommandTimeout": 10000,
"ignoreTestFiles": "*.js",
"chromeWebSecurity": false,
"baseUrl": "http://localhost:3000",

View File

@ -1,5 +1,4 @@
import { Given } from "cypress-cucumber-preprocessor/steps";
import { gql } from '../../../backend/src/helpers/jest'
Given('somebody reported the following posts:', table => {
table.hashes().forEach(({ submitterEmail, resourceId, reasonCategory, reasonDescription }) => {
@ -10,7 +9,7 @@ Given('somebody reported the following posts:', table => {
cy.factory()
.build('user', {}, submitter)
.authenticateAs(submitter)
.mutate(gql`mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) {
.mutate(`mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) {
fileReport(resourceId: $resourceId, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription) {
reportId
}

View File

@ -1,7 +1,13 @@
import { Then } from "cypress-cucumber-preprocessor/steps";
Then('I can see my new name {string} when I click on my profile picture in the top right', name => {
cy.get(".avatar-menu").then(($menu) => {
if (!$menu.is(':visible')){
cy.scrollTo("top");
cy.wait(500);
}
})
cy.get('.avatar-menu').click() // open
cy.get('.avatar-menu-popover').contains(name)
cy.get('.avatar-menu').click() // close again
})
})

View File

@ -13,29 +13,29 @@ Feature: User profile - list social media accounts
When I navigate to page "/settings/my-social-media"
Then I am on page "/settings/my-social-media"
When I add a social media link
Then I see a toaster with "Added social media"
Then I see a toaster with status "success"
And the new social media link shows up on the page
Scenario: Other users viewing my Social Media
Given I have added a social media link
Given I have added the social media link "https://freeradical.zone/peter-pan"
When I navigate to page "/profile/peter-pan"
Then they should be able to see my social media links
Scenario: Deleting Social Media
When I navigate to page "/settings/my-social-media"
Then I am on page "/settings/my-social-media"
Given I have added a social media link
When I delete a social media link
Then I see a toaster with "Deleted social media"
Given I have added the social media link "https://freeradical.zone/peter-pan"
When I delete the social media link "https://freeradical.zone/peter-pan"
Then I see a toaster with status "success"
Scenario: Editing Social Media
When I navigate to page "/settings/my-social-media"
Then I am on page "/settings/my-social-media"
Given I have added a social media link
Given I have added the social media link "https://freeradical.zone/peter-pan"
When I start editing a social media link
Then I can cancel editing
When I start editing a social media link
And I edit and save the link
Then I see a toaster with "Added social media"
Then I see a toaster with status "success"
And the new url is displayed
But the old url is not displayed

View File

@ -1,12 +1,10 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When('I add a social media link', () => {
cy.get('button')
.contains('Add link')
cy.get('[data-test="add-save-button"]')
.click()
.get('#editSocialMedia')
.type('https://freeradical.zone/peter-pan')
.get('button')
.contains('Save')
.get('[data-test="add-save-button"]')
.click()
})

View File

@ -1,6 +0,0 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When('I delete a social media link', () => {
cy.get(".base-button[title='Delete']")
.click()
})

View File

@ -0,0 +1,12 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When('I delete the social media link {string}', (link) => {
cy.get('[data-test="delete-button"]')
.click()
cy.get('[data-test="confirm-modal"]')
.should("be.visible")
cy.get('[data-test="confirm-button"]')
.click()
cy.get('.ds-list-item-content > a')
.contains(link).should('not.exist')
})

View File

@ -4,7 +4,6 @@ When('I edit and save the link', () => {
cy.get('input#editSocialMedia')
.clear()
.type('https://freeradical.zone/tinkerbell')
.get('button')
.contains('Save')
.get('[data-test="add-save-button"]')
.click()
})

View File

@ -1,13 +0,0 @@
import { Given } from "cypress-cucumber-preprocessor/steps";
Given('I have added a social media link', () => {
cy.visit('/settings/my-social-media')
.get('button')
.contains('Add link')
.click()
.get('#editSocialMedia')
.type('https://freeradical.zone/peter-pan')
.get('button')
.contains('Save')
.click()
})

View File

@ -0,0 +1,13 @@
import { Given } from "cypress-cucumber-preprocessor/steps";
Given('I have added the social media link {string}', (link) => {
cy.visit('/settings/my-social-media')
.get('[data-test="add-save-button"]')
.click()
.get('#editSocialMedia')
.type(link)
.get('[data-test="add-save-button"]')
.click()
cy.get('.ds-list-item-content > a')
.contains(link)
})

View File

@ -1,6 +1,6 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When('I start editing a social media link', () => {
cy.get(".base-button[title='Edit']")
cy.get('[data-test="edit-button"]')
.click()
})

View File

@ -1,8 +1,8 @@
import { Then } from "cypress-cucumber-preprocessor/steps";
Then('they should be able to see my social media links', () => {
cy.get('.base-card')
.contains('Where else can I find Peter Pan?')
cy.get('[data-test="social-media-list-headline"]')
.contains('Peter Pan')
.get('a[href="https://freeradical.zone/peter-pan"]')
.should('have.length', 1)
})

View File

@ -1,9 +1,15 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When("I log out", () => {
cy.get(".avatar-menu").then(($menu) => {
if (!$menu.is(':visible')){
cy.scrollTo("top");
cy.wait(500);
}
})
cy.get(".avatar-menu")
.click();
cy.get(".avatar-menu-popover")
.find('a[href="/logout"]')
.click();
});
});

View File

@ -0,0 +1,9 @@
import { Then } from "cypress-cucumber-preprocessor/steps";
Then("I see a toaster with status {string}", (status) => {
switch (status) {
case "success":
cy.get(".iziToast.iziToast-color-green").should("be.visible");
break;
}
})

View File

@ -15,11 +15,10 @@
/* globals Cypress cy */
import "cypress-file-upload";
import { GraphQLClient, request } from 'graphql-request'
import { gql } from '../../backend/src/helpers/jest'
import config from '../../backend/src/config'
const authenticatedHeaders = (variables) => {
const mutation = gql`
const mutation = `
mutation($email: String!, $password: String!) {
login(email: $email, password: $password)
}

1
deployment/.env.dist Normal file
View File

@ -0,0 +1 @@
CONFIGURATION=example

25
deployment/Minikube.md Normal file
View File

@ -0,0 +1,25 @@
# Minikube
There are many Kubernetes providers, but if you're just getting started, Minikube is a tool that you can use to get your feet wet.
After you [installed Minikube](https://kubernetes.io/docs/tasks/tools/install-minikube/)
open your minikube dashboard:
```text
$ minikube dashboard
```
This will give you an overview. Some of the steps below need some timing to make resources available to other dependent deployments. Keeping an eye on the dashboard is a great way to check that.
Follow the installation instruction for [Kubernetes with Helm](./kubernetes/README.md).
If all the pods and services have settled and everything looks green in your
minikube dashboard, expose the services you want on your host system.
For example:
```text
$ minikube service webapp --namespace=ocelotsocialnetwork
# optionally
$ minikube service backend --namespace=ocelotsocialnetwork
```

View File

@ -0,0 +1,23 @@
# Deployment
Before you start the deployment you have to do preparations.
## Deployment Preparations
Since all deployment methods described here depend on [Docker](https://docker.com) and [DockerHub](https://hub.docker.com), you need to create your own organisation on DockerHub and put its name in the [package.json](/package.json) file as your `dockerOrganisation`.
Read more details in the [main README](/README.md) under [Usage](/README.md#usage).
## Deployment Methods
You have the following options for a deployment:
- [Kubernetes with Helm](./kubernetes/README.md)
## After Deployment
After the first deployment of the new network on your server, the database is initialized with the default administrator:
- E-mail: admin@example.org
- Password: 1234
***ATTENTION:*** When you are logged in for the first time, please change your (the admin's) e-mail to an existing one and change your password to a secure one !!!

136
deployment/README.md Normal file
View File

@ -0,0 +1,136 @@
# Ocelot.Social Deploy And Rebranding
[![Build Status Publish](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/actions/workflows/publish.yml/badge.svg)](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/actions)
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/blob/LICENSE.md)
[![Discord Channel](https://img.shields.io/discord/489522408076738561.svg)](https://discord.gg/AJSX9DCSUA)
[![Open Source Helpers](https://www.codetriage.com/ocelot-social-community/ocelot-social-deploy-rebranding/badges/users.svg)](https://www.codetriage.com/ocelot-social-community/ocelot-social-deploy-rebranding)
This repository is an in use template to rebrand, configure, and deploy [ocelot.social](https://github.com/Ocelot-Social-Community/Ocelot-Social) networks.
The forked original repository is [Ocelot-Social-Deploy-Rebranding](https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding).
<!-- markdownlint-disable MD033 -->
<p align="center">
<a href="https://ocelot.social" target="_blank"><img src="branding/static/img/custom/logo-squared.svg" alt="Ocelot-Social" width="40%" height="40%"></a>
</p>
<!-- markdownlint-enable MD033 -->
## Live demo
__Try out our deployed [development environment](https://stage.ocelot.social).__
Visit our staging networks:
- central staging network: [stage.ocelot.social](https://stage.ocelot.social)
<!-- - rebranded staging network: [rebrand.ocelot.social](https://stage.ocelot.social). -->
Logins:
| email | password | role |
| :--- | :--- | :--- |
| `user@example.org` | 1234 | user |
| `moderator@example.org` | 1234 | moderator |
| `admin@example.org` | 1234 | admin |
## Usage
Fork this repository to configure and rebrand it for your own [ocelot.social](https://github.com/Ocelot-Social-Community/Ocelot-Social) network.
### Package.Json And DockerHub Organisation
Write your own data into the main configuration file:
- [package.json](/package.json)
Since all deployment methods described here depend on [Docker](https://docker.com) and [DockerHub](https://hub.docker.com), you need to create your own organisation on DockerHub and put its name in the [package.json](/package.json) file as your `dockerOrganisation`.
### Configure And Branding
The next step is:
- [Configure And Branding](/branding/README.md)
### Optional: Locally Testing Configuration And Branding
Just in case you have Docker installed and run the following, you can check your branding locally:
```bash
# in main folder
$ docker-compose up
# fill the database with an initial admin
$ docker-compose exec backend yarn run prod:migrate init
```
The database is then initialised with the default administrator:
- E-mail: admin@example.org
- Password: 1234
For login or registration have a look in your browser at `http://localhost:3000/`.
For the maintenance page have a look in your browser at `http://localhost:5000/`.
### Push Changes To GitHub
Before merging these changes into the "master" branch on your GitHub fork repository, you need to configure the GitHub repository secrets. This is necessary to [publish](/.github/workflows/publish.yml) the Docker images by pushing them via GitHub actions to repositories belonging to your DockerHub organisation.
First, go to your DockerHub profile under `Account Settings` and click on the `Security` tab. There you create an access token called `<your-organisation>-access-token` and copy the token to a safe place.
Secondly, in your GitHub repository, click on the 'Settings' tab and go to the 'Secrets' tab. There you create two secrets by clicking on `New repository secret`:
1. Named `DOCKERHUB_TOKEN` with the newly created DockerHub token (only the code, not the token name).
2. Named `DOCKERHUB_USERNAME` with your DockerHub username.
### Optional: Locally Testing Your DockerHub Images
Just in case you like to check your pushed Docker images in your organisation's DockerHub repositories locally:
- rename the file `docker-compose.ocelotsocial-branded.yml` with your network name
- in the file, rename the ocelot.social DockerHub organisation `ocelotsocialnetwork` to your organisations name
Remove any local Docker images if necessary and do the following:
```bash
# in main folder
$ docker-compose -f docker-compose.<your-organisation>-branded.yml up
# fill the database with an initial admin
$ docker-compose exec backend yarn run prod:migrate init
```
See the login details and browser addresses above.
### Deployment
Afterwards you can [deploy](/deployment/README.md) it on your server:
- [Kubernetes with Helm](/deployment/kubernetes/README.md)
## Developer Chat
Join our friendly open-source community on [Discord](https://discord.gg/AJSX9DCSUA) :heart_eyes_cat:
Just introduce yourself at `#introduce-yourself` and mention `@@Mentor` to get you onboard :neckbeard:
Check out the [contribution guideline](https://github.com/Ocelot-Social-Community/Ocelot-Social/blob/master/CONTRIBUTING.md), too!
We give write permissions to every developer who asks for it. Just text us on
[Discord](https://discord.gg/AJSX9DCSUA).
## Technology Stack
- [Docker](https://www.docker.com)
- [Kubernetes](https://kubernetes.io)
- [Helm](https://helm.sh)
<!--
## Attributions
Locale Icons made by [Freepik](http://www.freepik.com/) from [www.flaticon.com](https://www.flaticon.com/) is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/).
Browser compatibility testing with [BrowserStack](https://www.browserstack.com/).
<img alt="BrowserStack Logo" src=".gitbook/assets/browserstack-logo.svg" width="256">
-->
## License
See the [LICENSE](/LICENSE.md) file for license rights and limitations (MIT).
We need `DOCKER_BUILDKIT=0` for this to work.

View File

@ -0,0 +1,86 @@
# Todo For Next Update
When you overtake this deploy and rebrand repo to your network you have to recognize the following changes and doings:
## Version >= 2.4.0 with 'ocelotDockerVersionTag' 2.4.0-XXX
### Main Code PR feat(webapp): map #5843
- Create your own [Mapbox](https://mapbox.com/) account at [https://mapbox.com/](https://mapbox.com/) for your organization to get your own Mapbox token.
- You have to add the `MAPBOX_TOKEN` from the `deployment/kubernetes/values.template.yaml` to your `deployment/kubernetes/values.yaml` and set it to your own Mapbox token.
## Version >= 2.2.0 with 'ocelotDockerVersionTag' 2.2.0-267
### Main Code PR feat: 🍰 Footer And Header Links Configurable To Have External Link Target #5590
- You have to add property `target` to all array elements with value `url` to your preferred value in `branding/constants/headerMenu.js` originally in main code file `webapp/constants/headerMenu.js`.
- You have to move value of all `externalLink` to new property `externalLink.url` and set new property `externalLink.target` to your preferred value in `branding/constants/links.js` originally in main code file `webapp/constants/links.js`.
### Main Code PR feat: 🍰 Make Donation Progress Bar Color Configurable #5593
- You have to set `PROGRESS_BAR_COLOR_TYPE` in `branding/constants/donation.js` originally in main code file `webapp/constants/donation.js` to your preferred value.
### Main Code PR feat: 🍰 Header Logo Routing Update #5579
- You have to move value of `LOGO_HEADER_CLICK.externalLink` to new property `LOGO_HEADER_CLICK.externalLink.url` and set new property `LOGO_HEADER_CLICK.externalLink.target` to your preferred value in `branding/constants/logos.js` originally in main code file `webapp/constants/logos.js`.
## Version >= 2.0.0 with 'ocelotDockerVersionTag' 2.0.0-250
### Main Code PR feat: 🍰 Implement LOGO_HEADER_CLICK As Configuration #5525
- You have to set `LOGO_HEADER_CLICK` in `branding/constants/logos.js` originally in main code file `webapp/constants/logos.js` to your preferred value.
### Main Code Issue 🌟 [EPIC] Release v2.0.0 Beta Test → Final #5547
- You have to set `SHOW_GROUP_BUTTON_IN_HEADER` in `branding/constants/groups.js` originally in main code file `webapp/constants/groups.js` to your preferred value.
## Version >= 1.1.0 with 'ocelotDockerVersionTag' 1.1.0-205
### Deployment/Rebranding PR chore: 🍰 Release v1.1.0 - Implement Categories Again #63
- You have to add the `CATEGORIES_ACTIVE` from the `deployment/kubernetes/values.template.yaml` to your `deployment/kubernetes/values.yaml` and set it to your preferred value.
- Make sure the correct categories are in your Neo4j database on the server.
## Version >= 1.0.9 with 'ocelotDockerVersionTag' 1.0.9-199
### Deployment/Rebranding PR chore: 🍰 Implement PRODUCTION_DB_CLEAN_ALLOW for Staging Production Environments #56
- Copy `PRODUCTION_DB_CLEAN_ALLOW` from `deployment/kubernetes/values.template.yaml` to `values.yaml` and set it to `false` for production environments and only for several stage test servers to `true`.
### Deployment/Rebranding PR chore: [WIP] 🍰 Refine docs, first step #46
Upgrade the cert-manager, but install CRDs of the version 1.0.0-alpha to actually be able to upgrade ocelot. Then uninstall the legacy CRDs and install the correct ones.
```bash
# upgrade cert-manager to 1.9.1
> helm upgrade --set installCRDs=true --version 1.9.1 --namespace cert-manager cert-manager jetstack/cert-manager
# apply legacy CRDs
> kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.0.0-alpha.1/cert-manager.crds.yaml
# upgrade ocelot
> helm upgrade ocelot ./
# delete legacy CRDs
> kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v1.0.0-alpha.1/cert-manager.crds.yaml
# apply CRDs for cert-manager 1.9.1
> kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml
```
Background: We had to upgrade cert-manager due to an external dependency - therefore we had to update cert-manager apiVersion `cert-manager.io/v1alpha2` to `cert-manager.io/v1`.
The error occurring when not doing this is the following:
```bash
Error: UPGRADE FAILED: unable to build kubernetes objects from current release manifest: [resource mapping not found for name: "letsencrypt-production" namespace: "" from "": no matches for kind "ClusterIssuer" in version "cert-manager.io/v1alpha2"
ensure CRDs are installed first, resource mapping not found for name: "letsencrypt-staging" namespace: "" from "": no matches for kind "ClusterIssuer" in version "cert-manager.io/v1alpha2"
ensure CRDs are installed first]
```
## Version >= 1.0.8 with 'ocelotDockerVersionTag' 1.0.8-182
### PR feat: 🍰 Configure Cookie Expire Time #43
- You have to add the `COOKIE_EXPIRE_TIME` from the `deployment/kubernetes/values.template.yaml` to your `deployment/kubernetes/values.yaml` and set it to your preferred value.
- Correct `locale` cookie exploration time in data privacy.
## Version 1.0.7 with 'ocelotDockerVersionTag' 1.0.7-171
- No information.

3
deployment/configurations/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/*
!/example
!.gitignore

View File

@ -0,0 +1,5 @@
# Configure And Branding
In this folder you will find all configuration files and logo images to customise the configuration and branding of the [ocelot.social](https://github.com/Ocelot-Social-Community/Ocelot-Social) network code to your own needs.
Please change these and they will be used automatically as part of the [deployment](/deployment/README.md) process.

View File

@ -0,0 +1,5 @@
/*
*
* Here, all SCSS variables and classes can be adapted to your custom design.
*
*/

View File

@ -0,0 +1 @@
export const PROGRESS_BAR_COLOR_TYPE = 'gradient' // 'uni' is the other option

View File

@ -0,0 +1,8 @@
// this file is duplicated in `backend/src/config/` and `webapp/constants/` and replaced on rebranding by https://github.com/Ocelot-Social-Community/Ocelot-Social-Deploy-Rebranding/tree/master/branding/constants/
export default {
SUPPORT_EMAIL: 'hello@ocelot.social',
MODERATION_EMAIL: 'hello@ocelot.social',
// ATTENTION: the following links have to be defined even for internal pages with full URLs as example like 'https://staging.ocelot.social/support', because they are used in e-mails!
ORGANIZATION_LINK: 'https://ocelot.social',
SUPPORT_LINK: 'https://ocelot.social',
}

Some files were not shown because too many files have changed in this diff Show More