mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
Merge branch 'master' into update-database
This commit is contained in:
commit
23c2be3093
4
.github/workflows/test-e2e.yml
vendored
4
.github/workflows/test-e2e.yml
vendored
@ -27,6 +27,10 @@ jobs:
|
||||
- name: cypress | Fullstack tests
|
||||
id: e2e-tests
|
||||
run: |
|
||||
cd backend
|
||||
yarn install
|
||||
yarn build
|
||||
cd ..
|
||||
yarn install
|
||||
yarn run cypress:run --spec $(cypress/parallel-features.sh ${{ matrix.job }} ${{ env.jobs }} )
|
||||
|
||||
|
||||
60
CHANGELOG.md
60
CHANGELOG.md
@ -4,8 +4,68 @@ 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.7.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/2.6.0...2.7.0)
|
||||
|
||||
- fix(webapp): fix event teaser date from start to end by new components [`#6385`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6385)
|
||||
- refactor(webapp): optimize create and update event form [`#6381`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6381)
|
||||
- feat(backend): show events not ended yet [`#6405`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6405)
|
||||
- feat(backend): migration to add postType property to existing posts [`#6396`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6396)
|
||||
- feat(backend): seed events [`#6391`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6391)
|
||||
- feat(backend): seed posts as article [`#6227`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6227)
|
||||
- refactor(webapp): fix coverage [`#6361`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6361)
|
||||
- test(other): migrate cypress to v12 [`#6008`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6008)
|
||||
- refactor(backend): copy files in external script [`#6364`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6364)
|
||||
- feat(webapp): alternative solution for filter and order posts [`#6367`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6367)
|
||||
- refactor(webapp): changed color for event-ribbon. [`#6362`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6362)
|
||||
- fix(webapp): warnings in unit tests [`#6359`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6359)
|
||||
- Bump metascraper-title from 5.33.5 to 5.34.7 in /backend [`#6372`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6372)
|
||||
- Bump @babel/preset-env from 7.21.5 to 7.22.4 [`#6369`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6369)
|
||||
- fix(other): typescript fix regarding dist/build folder 2 [`#6366`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6366)
|
||||
- fix(backend): corrected path in branded images for backend build folder(former dist) [`#6365`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6365)
|
||||
- chore(other): upgrade node version in '.nvmrc' files to v20.2.0 [`#6331`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6331)
|
||||
- feat(backend): typescript [`#6321`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6321)
|
||||
- fix(webapp): fix group list number to six [`#6319`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6319)
|
||||
- fix(webapp): fix notification menu comment hash [`#6335`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6335)
|
||||
- feat(other): 🍰 epic events – master [`#6199`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6199)
|
||||
- fix(other): fix avatar seeding [`#6260`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6260)
|
||||
- chore(other): set 'DEBUG=true' in backend '.env.template' to use GraphQL Playground [`#6333`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6333)
|
||||
- refactor(other): unused packages ocelot [`#6326`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6326)
|
||||
- refactor(backend): unused packages backend [`#6325`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6325)
|
||||
- docs(other): add description for script usage in deployment readme [`#6329`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6329)
|
||||
- fix(webapp): fix newsfeed layout [`#6154`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6154)
|
||||
- fix(webapp): adds white space after user handle in comment editor [`#6308`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6308)
|
||||
- Bump validator from 13.0.0 to 13.9.0 in /backend [`#6076`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6076)
|
||||
- Bump metascraper-soundcloud from 5.34.2 to 5.34.4 in /backend [`#6312`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6312)
|
||||
- Bump metascraper-audio from 5.33.5 to 5.34.4 in /backend [`#6287`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6287)
|
||||
- Bump node from 19.9.0-alpine3.17 to 20.2.0-alpine3.17 in /backend [`#6310`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6310)
|
||||
- docs(other): add missing todo in deployment readme 'TODO-next-update.md' [`#6324`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6324)
|
||||
- Bump node from 20.1.0-alpine3.17 to 20.2.0-alpine3.17 in /webapp [`#6309`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6309)
|
||||
- fix(backend): helmet fix [`#6318`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6318)
|
||||
- fix(backend): helmet + graphiql [`#6303`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6303)
|
||||
- Bump @babel/preset-env from 7.21.4 to 7.21.5 [`#6273`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6273)
|
||||
- Bump date-fns from 2.25.0 to 2.30.0 [`#6283`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6283)
|
||||
- Bump node from 19.9.0-alpine3.17 to 20.1.0-alpine3.17 in /webapp [`#6280`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6280)
|
||||
- Bump @babel/core from 7.21.4 to 7.21.8 [`#6284`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6284)
|
||||
- Bump helmet from 3.22.0 to 7.0.0 in /backend [`#6296`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6296)
|
||||
- fix(webapp): fix z layer of header elements [`#6279`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6279)
|
||||
- fix(webapp): properly render avatars in group settings [`#6289`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6289)
|
||||
- fix(backend): post type on notifications [`#6257`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6257)
|
||||
- fix(backend): recover missing commit [`#6262`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6262)
|
||||
- feat(backend): filter posts by post type [`#6255`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6255)
|
||||
- feat(backend): save location address [`#6240`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6240)
|
||||
- feat(backend): add further event params [`#6231`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6231)
|
||||
- feat(backend): event parameters [`#6198`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6198)
|
||||
- feat(backend): create and update posts with labels [`#6197`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6197)
|
||||
- feat(backend): add article label to posts [`#6196`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6196)
|
||||
- Cypress: update packaage info [`b38769b`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/b38769b048e9cb9ca07862a61ea810f21b4ce82a)
|
||||
- update cypress related packageges in package.json [`692ec2a`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/692ec2a11555600647ec8d95b8296c9869948b02)
|
||||
- fixed coverage reporting [`540cd40`](https://github.com/Ocelot-Social-Community/Ocelot-Social/commit/540cd40e10ec0461ef17379cb93d914839f3a84f)
|
||||
|
||||
#### [2.6.0](https://github.com/Ocelot-Social-Community/Ocelot-Social/compare/2.5.1...2.6.0)
|
||||
|
||||
> 27 April 2023
|
||||
|
||||
- chore(release): v2.6.0 [`#6271`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6271)
|
||||
- fix(other): docker-compose for rebranding deployment [`#6265`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6265)
|
||||
- feat(webapp): default categories of group for posts in group [`#6259`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6259)
|
||||
- refactor(webapp): make action radius select in group form a reusable component [`#6244`](https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/6244)
|
||||
|
||||
@ -12,8 +12,7 @@ docker-compose*.yml
|
||||
./*.log
|
||||
|
||||
node_modules/
|
||||
scripts/
|
||||
dist/
|
||||
build/
|
||||
|
||||
maintenance-worker/
|
||||
neo4j/
|
||||
|
||||
2
backend/.gitignore
vendored
2
backend/.gitignore
vendored
@ -3,7 +3,7 @@ node_modules/
|
||||
.vscode
|
||||
.idea
|
||||
yarn-error.log
|
||||
dist/*
|
||||
build/*
|
||||
coverage.lcov
|
||||
.nyc_output/
|
||||
public/uploads/*
|
||||
|
||||
@ -1 +1 @@
|
||||
v19.4.0
|
||||
v20.2.0
|
||||
@ -74,7 +74,7 @@ FROM code as build
|
||||
# yarn install
|
||||
RUN yarn install --production=false --frozen-lockfile --non-interactive
|
||||
# yarn build
|
||||
RUN yarn run build
|
||||
RUN /bin/sh -c "yarn run build"
|
||||
|
||||
##################################################################################
|
||||
# TEST ###########################################################################
|
||||
@ -90,7 +90,7 @@ CMD /bin/sh -c "yarn run dev"
|
||||
FROM base as production
|
||||
|
||||
# Copy "binary"-files from build image
|
||||
COPY --from=build ${DOCKER_WORKDIR}/dist ./dist
|
||||
COPY --from=build ${DOCKER_WORKDIR}/build ./build
|
||||
COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules
|
||||
# Copy static files
|
||||
# TODO - externalize the uploads so we can copy the whole folder
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
module.exports = {
|
||||
verbose: true,
|
||||
preset: 'ts-jest',
|
||||
collectCoverage: true,
|
||||
collectCoverageFrom: [
|
||||
'**/*.js',
|
||||
'**/*.ts',
|
||||
'!**/node_modules/**',
|
||||
'!**/test/**',
|
||||
'!**/dist/**',
|
||||
'!**/src/**/?(*.)+(spec|test).js?(x)'
|
||||
'!**/build/**',
|
||||
'!**/src/**/?(*.)+(spec|test).ts?(x)'
|
||||
],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
lines: 57,
|
||||
},
|
||||
},
|
||||
testMatch: ['**/src/**/?(*.)+(spec|test).js?(x)'],
|
||||
setupFilesAfterEnv: ['<rootDir>/test/setup.js']
|
||||
testMatch: ['**/src/**/?(*.)+(spec|test).ts?(x)'],
|
||||
setupFilesAfterEnv: ['<rootDir>/test/setup.ts']
|
||||
}
|
||||
|
||||
@ -1,26 +1,26 @@
|
||||
{
|
||||
"name": "ocelot-social-backend",
|
||||
"version": "2.6.0",
|
||||
"version": "2.7.0",
|
||||
"description": "GraphQL Backend for ocelot.social",
|
||||
"repository": "https://github.com/Ocelot-Social-Community/Ocelot-Social",
|
||||
"author": "ocelot.social Community",
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"main": "src/index.js",
|
||||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
"__migrate": "migrate --compiler 'js:@babel/register' --migrations-dir ./src/db/migrations",
|
||||
"prod:migrate": "migrate --migrations-dir ./dist/db/migrations --store ./dist/db/migrate/store.js",
|
||||
"start": "node dist/",
|
||||
"build": "babel src/ -d dist/ --copy-files",
|
||||
"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",
|
||||
"__migrate": "migrate --compiler 'ts:./src/db/compiler.ts' --migrations-dir ./src/db/migrations",
|
||||
"prod:migrate": "migrate --migrations-dir ./build/db/migrations --store ./build/db/migrate/store.js",
|
||||
"start": "node build/",
|
||||
"build": "tsc && ./scripts/build.copy.files.sh",
|
||||
"dev": "nodemon --exec ts-node src/ -e js,ts,gql",
|
||||
"dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/ -e js,ts,gql",
|
||||
"lint": "eslint src --config .eslintrc.js",
|
||||
"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:clean": "ts-node src/db/clean.ts",
|
||||
"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"
|
||||
"db:seed": "ts-node src/db/seed.ts",
|
||||
"db:migrate": "yarn run __migrate --store ./src/db/migrate/store.ts",
|
||||
"db:migrate:create": "yarn run __migrate --template-file ./src/db/migrate/template.ts --date-format 'yyyymmddHHmmss' create"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/cli": "~7.8.4",
|
||||
@ -72,11 +72,11 @@
|
||||
"metascraper-logo": "^5.33.5",
|
||||
"metascraper-publisher": "^5.33.5",
|
||||
"metascraper-soundcloud": "^5.34.4",
|
||||
"metascraper-title": "^5.33.5",
|
||||
"metascraper-title": "^5.34.7",
|
||||
"metascraper-url": "^5.34.2",
|
||||
"metascraper-video": "^5.33.5",
|
||||
"metascraper-youtube": "^5.33.5",
|
||||
"migrate": "^1.7.0",
|
||||
"migrate": "^2.0.0",
|
||||
"mime-types": "^2.1.26",
|
||||
"minimatch": "^3.0.4",
|
||||
"mustache": "^4.2.0",
|
||||
@ -97,6 +97,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "7.6.0",
|
||||
"@types/jest": "^29.5.2",
|
||||
"@types/node": "^20.2.5",
|
||||
"apollo-server-testing": "~2.11.0",
|
||||
"chai": "~4.2.0",
|
||||
"cucumber": "~6.0.5",
|
||||
@ -112,7 +114,10 @@
|
||||
"jest": "29.4",
|
||||
"nodemon": "~2.0.2",
|
||||
"prettier": "~2.3.2",
|
||||
"rosie": "^2.0.1"
|
||||
"rosie": "^2.0.1",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.0.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"**/**/fs-capacitor": "^6.2.0",
|
||||
|
||||
24
backend/scripts/build.copy.files.sh
Executable file
24
backend/scripts/build.copy.files.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
# html files
|
||||
mkdir -p build/middleware/helpers/email/templates/
|
||||
cp -r src/middleware/helpers/email/templates/*.html build/middleware/helpers/email/templates/
|
||||
|
||||
mkdir -p build/middleware/helpers/email/templates/en/
|
||||
cp -r src/middleware/helpers/email/templates/en/*.html build/middleware/helpers/email/templates/en/
|
||||
|
||||
mkdir -p build/middleware/helpers/email/templates/de/
|
||||
cp -r src/middleware/helpers/email/templates/de/*.html build/middleware/helpers/email/templates/de/
|
||||
|
||||
# gql files
|
||||
mkdir -p build/schema/types/
|
||||
cp -r src/schema/types/*.gql build/schema/types/
|
||||
|
||||
mkdir -p build/schema/types/enum/
|
||||
cp -r src/schema/types/enum/*.gql build/schema/types/enum/
|
||||
|
||||
mkdir -p build/schema/types/scalar/
|
||||
cp -r src/schema/types/scalar/*.gql build/schema/types/scalar/
|
||||
|
||||
mkdir -p build/schema/types/type/
|
||||
cp -r src/schema/types/type/*.gql build/schema/types/type/
|
||||
@ -11,11 +11,15 @@ import { v4 as uuid } from 'uuid'
|
||||
import CONFIG from '../config'
|
||||
const debug = require('debug')('ea')
|
||||
|
||||
let activityPub = null
|
||||
let activityPub: any = null
|
||||
|
||||
export { activityPub }
|
||||
|
||||
export default class ActivityPub {
|
||||
endpoint: any
|
||||
dataSource: any
|
||||
collections: any
|
||||
host: any
|
||||
constructor(activityPubEndpointUri, internalGraphQlUri) {
|
||||
this.endpoint = activityPubEndpointUri
|
||||
this.dataSource = new NitroDataSource(internalGraphQlUri)
|
||||
@ -211,16 +215,16 @@ export default class ActivityPub {
|
||||
// serve the rest
|
||||
activity.to.map(async (recipient) => {
|
||||
debug('serve rest')
|
||||
const actorObject = await this.getActorObject(recipient)
|
||||
const actorObject: any = await this.getActorObject(recipient)
|
||||
return this.trySend(activity, fromName, new URL(recipient).host, actorObject.inbox)
|
||||
})
|
||||
} else if (typeof activity.to === 'string') {
|
||||
debug('is string')
|
||||
const actorObject = await this.getActorObject(activity.to)
|
||||
const actorObject: any = await this.getActorObject(activity.to)
|
||||
return this.trySend(activity, fromName, new URL(activity.to).host, actorObject.inbox)
|
||||
} else if (Array.isArray(activity.to)) {
|
||||
activity.to.map(async (recipient) => {
|
||||
const actorObject = await this.getActorObject(recipient)
|
||||
const actorObject: any = await this.getActorObject(recipient)
|
||||
return this.trySend(activity, fromName, new URL(recipient).host, actorObject.inbox)
|
||||
})
|
||||
}
|
||||
@ -231,7 +235,7 @@ export default class ActivityPub {
|
||||
return await signAndSend(activity, fromName, host, url)
|
||||
} catch (e) {
|
||||
if (tries > 0) {
|
||||
setTimeout(function () {
|
||||
setTimeout(() => {
|
||||
return this.trySend(activity, fromName, host, url, --tries)
|
||||
}, 20000)
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
export default class Collections {
|
||||
dataSource: any
|
||||
constructor(dataSource) {
|
||||
this.dataSource = dataSource
|
||||
}
|
||||
@ -17,15 +17,17 @@ import trunc from 'trunc-html'
|
||||
const debug = require('debug')('ea:datasource')
|
||||
|
||||
export default class NitroDataSource {
|
||||
uri: any
|
||||
client: any
|
||||
constructor(uri) {
|
||||
this.uri = uri
|
||||
const defaultOptions = {
|
||||
const defaultOptions: any = {
|
||||
query: {
|
||||
fetchPolicy: 'network-only',
|
||||
errorPolicy: 'all',
|
||||
},
|
||||
}
|
||||
const link = createHttpLink({ uri: this.uri, fetch: fetch }) // eslint-disable-line
|
||||
const link = createHttpLink({ uri: this.uri, fetch: fetch } as any) // eslint-disable-line
|
||||
const cache = new InMemoryCache()
|
||||
const authLink = setContext((_, { headers }) => {
|
||||
// generate the authentication token (maybe from env? Which user?)
|
||||
@ -95,7 +97,7 @@ export default class NitroDataSource {
|
||||
const followers = actor.followedBy
|
||||
const followersCount = actor.followedByCount
|
||||
|
||||
const followersCollection = createOrderedCollectionPage(slug, 'followers')
|
||||
const followersCollection: any = createOrderedCollectionPage(slug, 'followers')
|
||||
followersCollection.totalItems = followersCount
|
||||
debug(`followers = ${JSON.stringify(followers, null, 2)}`)
|
||||
await Promise.all(
|
||||
@ -157,7 +159,7 @@ export default class NitroDataSource {
|
||||
const following = actor.following
|
||||
const followingCount = actor.followingCount
|
||||
|
||||
const followingCollection = createOrderedCollectionPage(slug, 'following')
|
||||
const followingCollection: any = createOrderedCollectionPage(slug, 'following')
|
||||
followingCollection.totalItems = followingCount
|
||||
|
||||
await Promise.all(
|
||||
@ -235,7 +237,7 @@ export default class NitroDataSource {
|
||||
const actor = result.data.User[0]
|
||||
const posts = actor.contributions
|
||||
|
||||
const outboxCollection = createOrderedCollectionPage(slug, 'outbox')
|
||||
const outboxCollection: any = createOrderedCollectionPage(slug, 'outbox')
|
||||
outboxCollection.totalItems = posts.length
|
||||
await Promise.all(
|
||||
posts.map(async (post) => {
|
||||
@ -11,8 +11,8 @@ export default function () {
|
||||
cors(),
|
||||
express.json({
|
||||
type: ['application/activity+json', 'application/ld+json', 'application/json'],
|
||||
}),
|
||||
express.urlencoded({ extended: true }),
|
||||
}) as any,
|
||||
express.urlencoded({ extended: true }) as any,
|
||||
user,
|
||||
)
|
||||
router.use(
|
||||
@ -20,8 +20,8 @@ export default function () {
|
||||
cors(),
|
||||
express.json({
|
||||
type: ['application/activity+json', 'application/ld+json', 'application/json'],
|
||||
}),
|
||||
express.urlencoded({ extended: true }),
|
||||
}) as any,
|
||||
express.urlencoded({ extended: true }) as any,
|
||||
verify,
|
||||
inbox,
|
||||
)
|
||||
@ -54,6 +54,6 @@ export async function handler(req, res) {
|
||||
|
||||
export default function () {
|
||||
const router = express.Router()
|
||||
router.use('/webfinger', cors(), express.urlencoded({ extended: true }), handler)
|
||||
router.use('/webfinger', cors(), express.urlencoded({ extended: true }) as any, handler)
|
||||
return router
|
||||
}
|
||||
@ -8,7 +8,7 @@ const debug = require('debug')('ea:security')
|
||||
// TODO Does this reference a local config? Why?
|
||||
// dotenv.config({ path: resolve('src', 'activitypub', '.env') })
|
||||
|
||||
export function generateRsaKeyPair(options = {}) {
|
||||
export function generateRsaKeyPair(options: any = {}) {
|
||||
const { passphrase = CONFIG.PRIVATE_KEY_PASSPHRASE } = options
|
||||
return crypto.generateKeyPairSync('rsa', {
|
||||
modulusLength: 4096,
|
||||
@ -100,18 +100,19 @@ export async function getActorId(name) {
|
||||
// }
|
||||
|
||||
export function isPublicAddressed(postObject) {
|
||||
const result: { to: any[]} = { to: []}
|
||||
if (typeof postObject.to === 'string') {
|
||||
postObject.to = [postObject.to]
|
||||
result.to = [postObject.to]
|
||||
}
|
||||
if (typeof postObject === 'string') {
|
||||
postObject.to = [postObject]
|
||||
result.to = [postObject]
|
||||
}
|
||||
if (Array.isArray(postObject)) {
|
||||
postObject.to = postObject
|
||||
result.to = postObject
|
||||
}
|
||||
return (
|
||||
postObject.to.includes('Public') ||
|
||||
postObject.to.includes('as:Public') ||
|
||||
postObject.to.includes('https://www.w3.org/ns/activitystreams#Public')
|
||||
result.to.includes('Public') ||
|
||||
result.to.includes('as:Public') ||
|
||||
result.to.includes('https://www.w3.org/ns/activitystreams#Public')
|
||||
)
|
||||
}
|
||||
@ -101,7 +101,7 @@ export function signAndSend(activity, fromName, targetDomain, url) {
|
||||
} else {
|
||||
debug('Response Headers:', JSON.stringify(response.headers, null, 2))
|
||||
debug('Response Body:', JSON.stringify(response.body, null, 2))
|
||||
resolve()
|
||||
resolve(response)
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -1,6 +1,6 @@
|
||||
import dotenv from 'dotenv'
|
||||
import emails from './emails.js'
|
||||
import metadata from './metadata.js'
|
||||
import emails from './emails'
|
||||
import metadata from './metadata'
|
||||
|
||||
// Load env file
|
||||
if (require.resolve) {
|
||||
@ -15,10 +15,11 @@ if (require.resolve) {
|
||||
}
|
||||
|
||||
// Use Cypress env or process.env
|
||||
declare var Cypress: any | undefined
|
||||
const env = typeof Cypress !== 'undefined' ? Cypress.env() : process.env // eslint-disable-line no-undef
|
||||
|
||||
const environment = {
|
||||
NODE_ENV: env.NODE_ENV || process.NODE_ENV,
|
||||
NODE_ENV: env.NODE_ENV || process.env.NODE_ENV,
|
||||
DEBUG: env.NODE_ENV !== 'production' && env.DEBUG,
|
||||
TEST: env.NODE_ENV === 'test',
|
||||
PRODUCTION: env.NODE_ENV === 'production',
|
||||
@ -90,14 +91,11 @@ const options = {
|
||||
}
|
||||
|
||||
// Check if all required configs are present
|
||||
if (require.resolve) {
|
||||
// are we in a nodejs environment?
|
||||
Object.entries(required).map((entry) => {
|
||||
if (!entry[1]) {
|
||||
throw new Error(`ERROR: "${entry[0]}" env variable is missing.`)
|
||||
}
|
||||
})
|
||||
}
|
||||
Object.entries(required).map((entry) => {
|
||||
if (!entry[1]) {
|
||||
throw new Error(`ERROR: "${entry[0]}" env variable is missing.`)
|
||||
}
|
||||
})
|
||||
|
||||
export default {
|
||||
...environment,
|
||||
@ -1,4 +1,4 @@
|
||||
// this file is duplicated in `backend/src/config/logos.js` and `webapp/constants/logos.js` and replaced on rebranding
|
||||
// this file is duplicated in `backend/src/config/logos` and `webapp/constants/logos.js` and replaced on rebranding
|
||||
// this are the paths in the webapp
|
||||
export default {
|
||||
LOGO_HEADER_PATH: '/img/custom/logo-horizontal.svg',
|
||||
@ -1,4 +1,4 @@
|
||||
// this file is duplicated in `backend/src/config/metadata.js` and `webapp/constants/metadata.js` and replaced on rebranding
|
||||
// this file is duplicated in `backend/src/config/metadata` and `webapp/constants/metadata.js` and replaced on rebranding
|
||||
export default {
|
||||
APPLICATION_NAME: 'ocelot.social',
|
||||
APPLICATION_SHORT_NAME: 'ocelot',
|
||||
@ -1,4 +1,4 @@
|
||||
// this file is duplicated in `backend/src/constants/metadata.js` and `webapp/constants/metadata.js`
|
||||
// this file is duplicated in `backend/src/constants/metadata` and `webapp/constants/metadata.js`
|
||||
export const CATEGORIES_MIN = 1
|
||||
export const CATEGORIES_MAX = 3
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
// this file is duplicated in `backend/src/constants/group.js` and `webapp/constants/group.js`
|
||||
// this file is duplicated in `backend/src/constants/group` and `webapp/constants/group.js`
|
||||
export const DESCRIPTION_WITHOUT_HTML_LENGTH_MIN = 50 // with removed HTML tags
|
||||
export const DESCRIPTION_EXCERPT_HTML_LENGTH = 250 // with removed HTML tags
|
||||
@ -1,5 +0,0 @@
|
||||
// this file is duplicated in `backend/src/config/metadata.js` and `webapp/constants/metadata.js`
|
||||
export default {
|
||||
NONCE_LENGTH: 5,
|
||||
INVITE_CODE_LENGTH: 6,
|
||||
}
|
||||
5
backend/src/constants/registration.ts
Normal file
5
backend/src/constants/registration.ts
Normal file
@ -0,0 +1,5 @@
|
||||
// this file is duplicated in `backend/src/config/metadata` and `webapp/constants/metadata.js`
|
||||
export default {
|
||||
NONCE_LENGTH: 5,
|
||||
INVITE_CODE_LENGTH: 6,
|
||||
}
|
||||
2
backend/src/db/compiler.ts
Normal file
2
backend/src/db/compiler.ts
Normal file
@ -0,0 +1,2 @@
|
||||
const tsNode = require('ts-node');
|
||||
module.exports = tsNode.register;
|
||||
@ -4,8 +4,8 @@ import { hashSync } from 'bcryptjs'
|
||||
import { Factory } from 'rosie'
|
||||
import { faker } from '@faker-js/faker'
|
||||
import { getDriver, getNeode } from './neo4j'
|
||||
import CONFIG from '../config/index.js'
|
||||
import generateInviteCode from '../schema/resolvers/helpers/generateInviteCode.js'
|
||||
import CONFIG from '../config/index'
|
||||
import generateInviteCode from '../schema/resolvers/helpers/generateInviteCode'
|
||||
|
||||
const neode = getNeode()
|
||||
|
||||
@ -15,7 +15,7 @@ const uniqueImageUrl = (imageUrl) => {
|
||||
return newUrl.toString()
|
||||
}
|
||||
|
||||
export const cleanDatabase = async (options = {}) => {
|
||||
export const cleanDatabase = async (options: any = {}) => {
|
||||
const { driver = getDriver() } = options
|
||||
const session = driver.session()
|
||||
try {
|
||||
@ -165,7 +165,7 @@ Factory.define('post')
|
||||
})
|
||||
.after(async (buildObject, options) => {
|
||||
const [post, author, image, /* categories, */ tags] = await Promise.all([
|
||||
neode.create('Post', buildObject),
|
||||
neode.create('Article', buildObject),
|
||||
options.author,
|
||||
options.image,
|
||||
// options.categories,
|
||||
@ -18,13 +18,13 @@ export function up(next) {
|
||||
rxSession
|
||||
.beginTransaction()
|
||||
.pipe(
|
||||
flatMap((txc) =>
|
||||
flatMap((txc: any) =>
|
||||
concat(
|
||||
txc
|
||||
.run('MATCH (email:EmailAddress) RETURN email {.email}')
|
||||
.records()
|
||||
.pipe(
|
||||
map((record) => {
|
||||
map((record: any) => {
|
||||
const { email } = record.get('email')
|
||||
const normalizedEmail = normalizeEmail(email)
|
||||
return { email, normalizedEmail }
|
||||
@ -45,7 +45,7 @@ export function up(next) {
|
||||
)
|
||||
.records()
|
||||
.pipe(
|
||||
map((r) => ({
|
||||
map((r: any) => ({
|
||||
oldEmail: email,
|
||||
email: r.get('email'),
|
||||
user: r.get('user'),
|
||||
@ -12,7 +12,7 @@ export function up(next) {
|
||||
rxSession
|
||||
.beginTransaction()
|
||||
.pipe(
|
||||
flatMap((transaction) =>
|
||||
flatMap((transaction: any) =>
|
||||
concat(
|
||||
transaction
|
||||
.run(
|
||||
@ -23,7 +23,7 @@ export function up(next) {
|
||||
)
|
||||
.records()
|
||||
.pipe(
|
||||
map((record) => {
|
||||
map((record: any) => {
|
||||
const { id: locationId } = record.get('location')
|
||||
return { locationId }
|
||||
}),
|
||||
@ -40,7 +40,7 @@ export function up(next) {
|
||||
)
|
||||
.records()
|
||||
.pipe(
|
||||
map((record) => ({
|
||||
map((record: any) => ({
|
||||
location: record.get('location'),
|
||||
updatedLocation: record.get('updatedLocation'),
|
||||
})),
|
||||
@ -3,7 +3,7 @@ import { existsSync, createReadStream } from 'fs'
|
||||
import path from 'path'
|
||||
import { S3 } from 'aws-sdk'
|
||||
import mime from 'mime-types'
|
||||
import { s3Configs } from '../../config'
|
||||
import s3Configs from '../../config'
|
||||
import https from 'https'
|
||||
|
||||
export const description = `
|
||||
@ -0,0 +1,53 @@
|
||||
import { getDriver } from '../../db/neo4j'
|
||||
|
||||
export const description = 'Add postType property Article to all posts'
|
||||
|
||||
export async function up(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
try {
|
||||
await transaction.run(`
|
||||
MATCH (post:Post)
|
||||
SET post.postType = 'Article'
|
||||
RETURN post
|
||||
`)
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
try {
|
||||
await transaction.run(`
|
||||
MATCH (post:Post)
|
||||
REMOVE post.postType
|
||||
RETURN post
|
||||
`)
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,7 @@ export function getNeode(options = {}) {
|
||||
if (!neodeInstance) {
|
||||
const { uri, username, password } = { ...defaultOptions, ...options }
|
||||
neodeInstance = new Neode(uri, username, password).with(models)
|
||||
neodeInstance.extend('Post', 'Article', {})
|
||||
return neodeInstance
|
||||
}
|
||||
return neodeInstance
|
||||
@ -596,7 +596,79 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
|
||||
}),
|
||||
])
|
||||
|
||||
// Create Posts
|
||||
// Create Events (by peter lustig)
|
||||
authenticatedUser = await peterLustig.toJson()
|
||||
const now = new Date()
|
||||
|
||||
await Promise.all([
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
id: 'e0',
|
||||
title: 'Illegaler Kindergeburtstag',
|
||||
content: 'Elli hat nächste Woche Geburtstag. Wir feiern das!',
|
||||
categoryIds: ['cat4'],
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(
|
||||
now.getFullYear(),
|
||||
now.getMonth(),
|
||||
now.getDate() + 7,
|
||||
).toISOString(),
|
||||
eventVenue: 'Ellis Kinderzimmer',
|
||||
eventLocationName: 'Deutschland',
|
||||
},
|
||||
},
|
||||
}),
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
id: 'e1',
|
||||
title: 'Wir Schützen den Stuttgarter Schlossgarten',
|
||||
content: 'Kein Baum wird gefällt werden!',
|
||||
categoryIds: ['cat5'],
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(
|
||||
now.getFullYear(),
|
||||
now.getMonth(),
|
||||
now.getDate() + 1,
|
||||
).toISOString(),
|
||||
eventVenue: 'Schlossgarten',
|
||||
eventLocationName: 'Stuttgart',
|
||||
},
|
||||
},
|
||||
}),
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
id: 'e2',
|
||||
title: 'IT 4 Change Treffen',
|
||||
content: 'Wir sitzen eine Woche zusammen rum und glotzen uns blöde an.',
|
||||
categoryIds: ['cat5'],
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(
|
||||
now.getFullYear(),
|
||||
now.getMonth(),
|
||||
now.getDate() + 1,
|
||||
).toISOString(),
|
||||
eventEnd: new Date(now.getFullYear(), now.getMonth(), now.getDate() + 4).toISOString(),
|
||||
eventVenue: 'Ferienlager',
|
||||
eventLocationName: 'Bahra, Sachsen',
|
||||
},
|
||||
},
|
||||
}),
|
||||
])
|
||||
|
||||
let passedEvent = await neode.find('Post', 'e1')
|
||||
await passedEvent.update({ eventStart: new Date(2010, 8, 30, 10).toISOString() })
|
||||
passedEvent = await neode.find('Post', 'e2')
|
||||
await passedEvent.update({
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth(), now.getDate() - 3).toISOString(),
|
||||
})
|
||||
|
||||
// Create Posts (Articles)
|
||||
|
||||
const [p0, p1, p3, p4, p5, p6, p9, p10, p11, p13, p14, p15] = await Promise.all([
|
||||
Factory.build(
|
||||
@ -5,7 +5,7 @@
|
||||
* @property fieldName String
|
||||
* @property callback Function
|
||||
*/
|
||||
function walkRecursive(data, fields, fieldName, 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')
|
||||
}
|
||||
@ -8,7 +8,7 @@ import { exec, build } from 'xregexp/xregexp-all.js'
|
||||
// 2. If it starts with a digit '0-9' than a unicode letter has to follow.
|
||||
const regX = build('^((\\pL+[\\pL0-9]*)|([0-9]+\\pL+[\\pL0-9]*))$')
|
||||
|
||||
export default function (content) {
|
||||
export default function (content?) {
|
||||
if (!content) return []
|
||||
const $ = cheerio.load(content)
|
||||
// We can not search for class '.hashtag', because the classes are removed at the 'xss' middleware.
|
||||
@ -18,7 +18,7 @@ export default function (content) {
|
||||
return $(el).attr('data-hashtag-id')
|
||||
})
|
||||
.get()
|
||||
const hashtags = []
|
||||
const hashtags: any = []
|
||||
ids.forEach((id) => {
|
||||
const match = exec(id, regX)
|
||||
if (match != null) {
|
||||
@ -1,12 +1,12 @@
|
||||
import CONFIG from '../../../config'
|
||||
import { cleanHtml } from '../../../middleware/helpers/cleanHtml.js'
|
||||
import { cleanHtml } from '../../../middleware/helpers/cleanHtml'
|
||||
import nodemailer from 'nodemailer'
|
||||
import { htmlToText } from 'nodemailer-html-to-text'
|
||||
|
||||
const hasEmailConfig = CONFIG.SMTP_HOST && CONFIG.SMTP_PORT
|
||||
const hasAuthData = CONFIG.SMTP_USERNAME && CONFIG.SMTP_PASSWORD
|
||||
|
||||
let sendMailCallback = async () => {}
|
||||
let sendMailCallback: any = async () => {}
|
||||
if (!hasEmailConfig) {
|
||||
if (!CONFIG.TEST) {
|
||||
// eslint-disable-next-line no-console
|
||||
@ -29,7 +29,7 @@ if (!hasEmailConfig) {
|
||||
cleanHtml(templateArgs.html, 'dummyKey', {
|
||||
allowedTags: ['a'],
|
||||
allowedAttributes: { a: ['href'] },
|
||||
}).replace(/&/g, '&'),
|
||||
} as any).replace(/&/g, '&'),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
import CONFIG from '../../../config'
|
||||
import logosWebapp from '../../../config/logos.js'
|
||||
import logosWebapp from '../../../config/logos'
|
||||
import {
|
||||
signupTemplate,
|
||||
emailVerificationTemplate,
|
||||
@ -1,7 +1,7 @@
|
||||
import mustache from 'mustache'
|
||||
import CONFIG from '../../../config'
|
||||
import metadata from '../../../config/metadata.js'
|
||||
import logosWebapp from '../../../config/logos.js'
|
||||
import metadata from '../../../config/metadata'
|
||||
import logosWebapp from '../../../config/logos'
|
||||
|
||||
import * as templates from './templates'
|
||||
import * as templatesEN from './templates/en'
|
||||
@ -1,5 +1,5 @@
|
||||
import LanguageDetect from 'languagedetect'
|
||||
import { removeHtmlTags } from '../helpers/cleanHtml.js'
|
||||
import { removeHtmlTags } from '../helpers/cleanHtml'
|
||||
|
||||
const setPostLanguage = (text) => {
|
||||
const lngDetector = new LanguageDetect()
|
||||
@ -576,7 +576,7 @@ describe('notifications', () => {
|
||||
read: false,
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject(expected, { errors: undefined })
|
||||
).resolves.toMatchObject({ ...expected, errors: undefined })
|
||||
})
|
||||
})
|
||||
|
||||
@ -238,7 +238,7 @@ const notifyUsersOfMention = async (label, id, idsOfUsers, reason, context) => {
|
||||
[(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors,
|
||||
[(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] AS posts
|
||||
WITH resource, user, notification, authors, posts,
|
||||
resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} AS finalResource
|
||||
resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group'])[0], author: authors[0], post: posts[0]} AS finalResource
|
||||
SET notification.read = FALSE
|
||||
SET notification.createdAt = COALESCE(notification.createdAt, toString(datetime()))
|
||||
SET notification.updatedAt = toString(datetime())
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user