diff --git a/backend/.env.template b/backend/.env.template index 0227b93d4..6697f09c4 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -14,3 +14,6 @@ JWT_SECRET="b/&&7b78BF&fv/Vd" MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ" PRIVATE_KEY_PASSPHRASE="a7dsf78sadg87ad87sfagsadg78" + +SENTRY_DSN_BACKEND= +COMMIT= diff --git a/backend/package.json b/backend/package.json index da76c385d..846bbc8f3 100644 --- a/backend/package.json +++ b/backend/package.json @@ -43,6 +43,7 @@ }, "dependencies": { "@hapi/joi": "^15.1.1", + "@sentry/node": "^5.6.1", "activitystrea.ms": "~2.1.3", "apollo-cache-inmemory": "~1.6.3", "apollo-client": "~2.6.4", @@ -64,6 +65,7 @@ "graphql-custom-directives": "~0.2.14", "graphql-iso-date": "~3.6.1", "graphql-middleware": "~3.0.5", + "graphql-middleware-sentry": "^3.2.0", "graphql-shield": "~6.0.4", "graphql-tag": "~2.10.1", "helmet": "~3.20.0", diff --git a/backend/src/config/index.js b/backend/src/config/index.js index daba745c8..3709b5cc3 100644 --- a/backend/src/config/index.js +++ b/backend/src/config/index.js @@ -11,6 +11,8 @@ const { SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, + SENTRY_DSN_BACKEND, + COMMIT, NEO4J_URI = 'bolt://localhost:7687', NEO4J_USERNAME = 'neo4j', NEO4J_PASSWORD = 'neo4j', @@ -31,15 +33,18 @@ export const neo4jConfigs = { NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD } export const serverConfigs = { GRAPHQL_PORT, CLIENT_URI, GRAPHQL_URI } export const developmentConfigs = { - DEBUG: process.env.NODE_ENV !== 'production' && process.env.DEBUG === 'true', + DEBUG: process.env.NODE_ENV !== 'production' && process.env.DEBUG, DISABLED_MIDDLEWARES: (process.env.NODE_ENV !== 'production' && process.env.DISABLED_MIDDLEWARES) || '', } +export const sentryConfigs = { SENTRY_DSN_BACKEND, COMMIT } + export default { ...requiredConfigs, ...smtpConfigs, ...neo4jConfigs, ...serverConfigs, ...developmentConfigs, + ...sentryConfigs, } diff --git a/backend/src/middleware/index.js b/backend/src/middleware/index.js index ba5b9d324..3407c6874 100644 --- a/backend/src/middleware/index.js +++ b/backend/src/middleware/index.js @@ -14,10 +14,12 @@ import orderBy from './orderByMiddleware' import validation from './validation/validationMiddleware' import handleContentData from './handleHtmlContent/handleContentData' import email from './email/emailMiddleware' +import sentry from './sentryMiddleware' export default schema => { const middlewares = { permissions: permissions, + sentry: sentry, activityPub: activityPub, dateTime: dateTime, validation: validation, @@ -33,6 +35,7 @@ export default schema => { } let order = [ + 'sentry', 'permissions', // 'activityPub', disabled temporarily 'dateTime', diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index 0f6f9e1c5..83c29d19d 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -1,12 +1,12 @@ import { rule, shield, deny, allow, and, or, not } from 'graphql-shield' import { neode } from '../bootstrap/neo4j' +import CONFIG from '../config' + +const debug = !!CONFIG.DEBUG +const allowExternalErrors = true const instance = neode() -/* - * TODO: implement - * See: https://github.com/Human-Connection/Nitro-Backend/pull/40#pullrequestreview-180898363 - */ const isAuthenticated = rule({ cache: 'contextual', })(async (_parent, _args, ctx, _info) => { @@ -204,6 +204,8 @@ const permissions = shield( }, }, { + debug, + allowExternalErrors, fallbackRule: allow, }, ) diff --git a/backend/src/middleware/sentryMiddleware.js b/backend/src/middleware/sentryMiddleware.js new file mode 100644 index 000000000..b1130ad37 --- /dev/null +++ b/backend/src/middleware/sentryMiddleware.js @@ -0,0 +1,26 @@ +import { sentry } from 'graphql-middleware-sentry' +import { sentryConfigs } from '../config' + +let sentryMiddleware = (resolve, root, args, context, resolveInfo) => + resolve(root, args, context, resolveInfo) + +if (sentryConfigs.SENTRY_DSN_BACKEND) { + sentryMiddleware = sentry({ + forwardErrors: true, + config: { + dsn: sentryConfigs.SENTRY_DSN_BACKEND, + release: sentryConfigs.COMMIT, + environment: process.env.NODE_ENV, + }, + withScope: (scope, error, context) => { + scope.setUser({ + id: context.user.id, + }) + scope.setExtra('body', context.req.body) + scope.setExtra('origin', context.req.headers.origin) + scope.setExtra('user-agent', context.req.headers['user-agent']) + }, + }) +} + +export default sentryMiddleware diff --git a/backend/src/schema/index.js b/backend/src/schema/index.js index 2b24178e1..b8f120057 100644 --- a/backend/src/schema/index.js +++ b/backend/src/schema/index.js @@ -35,7 +35,7 @@ export default applyScalars( ], // add 'User' here as soon as possible }, - debug: CONFIG.DEBUG, + debug: !!CONFIG.DEBUG, }, }), ), diff --git a/backend/src/server.js b/backend/src/server.js index 752cd96fb..f92e77fed 100644 --- a/backend/src/server.js +++ b/backend/src/server.js @@ -33,8 +33,8 @@ const createServer = options => { } }, schema: middleware(schema), - debug: CONFIG.DEBUG, - tracing: CONFIG.DEBUG, + debug: !!CONFIG.DEBUG, + tracing: !!CONFIG.DEBUG, } const server = new ApolloServer(Object.assign({}, defaults, options)) diff --git a/backend/yarn.lock b/backend/yarn.lock index 77c92db0c..3e9d1f862 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -1074,6 +1074,62 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= +"@sentry/core@5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.6.1.tgz#946f064cc500bf4cd2a1bac580192fe440b614c7" + integrity sha512-gK8XfkJIZLsBEQehkr2q2fdHI50B3yo4RXiixSZiNBVIzQ+1z3JcMssDzGwhbY81NHUzHZ7of3oQ4Ab4OGRI/g== + dependencies: + "@sentry/hub" "5.6.1" + "@sentry/minimal" "5.6.1" + "@sentry/types" "5.6.1" + "@sentry/utils" "5.6.1" + tslib "^1.9.3" + +"@sentry/hub@5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.6.1.tgz#9f355c0abcc92327fbd10b9b939608aa4967bece" + integrity sha512-m+OhkIV5yTAL3R1+XfCwzUQka0UF/xG4py8sEfPXyYIcoOJ2ZTX+1kQJLy8QQJ4RzOBwZA+DzRKP0cgzPJ3+oQ== + dependencies: + "@sentry/types" "5.6.1" + "@sentry/utils" "5.6.1" + tslib "^1.9.3" + +"@sentry/minimal@5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.6.1.tgz#09d92b26de0b24555cd50c3c33ba4c3e566009a1" + integrity sha512-ercCKuBWHog6aS6SsJRuKhJwNdJ2oRQVWT2UAx1zqvsbHT9mSa8ZRjdPHYOtqY3DoXKk/pLUFW/fkmAnpdMqRw== + dependencies: + "@sentry/hub" "5.6.1" + "@sentry/types" "5.6.1" + tslib "^1.9.3" + +"@sentry/node@^5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.6.1.tgz#745adde66e78a605d3edfd3b4108a9e2a6859cc4" + integrity sha512-8gNjFRrTOG3vu2RpWZnUSxNx6Ui2Dthq2VHeVImt7PYtVaSddlYZvt0xl8L/fJC/TvFZEPfX0d8Is9v8yvsgRQ== + dependencies: + "@sentry/core" "5.6.1" + "@sentry/hub" "5.6.1" + "@sentry/types" "5.6.1" + "@sentry/utils" "5.6.1" + cookie "0.3.1" + https-proxy-agent "2.2.1" + lru_map "0.3.3" + tslib "^1.9.3" + +"@sentry/types@5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.6.1.tgz#5915e1ee4b7a678da3ac260c356b1cb91139a299" + integrity sha512-Kub8TETefHpdhvtnDj3kKfhCj0u/xn3Zi2zIC7PB11NJHvvPXENx97tciz4roJGp7cLRCJsFqCg4tHXniqDSnQ== + +"@sentry/utils@5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.6.1.tgz#69d9e151e50415bc91f2428e3bcca8beb9bc2815" + integrity sha512-rfgha+UsHW816GqlSRPlniKqAZylOmQWML2JsujoUP03nPu80zdN43DK9Poy/d9OxBxv0gd5K2n+bFdM2kqLQQ== + dependencies: + "@sentry/types" "5.6.1" + tslib "^1.9.3" + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -1440,6 +1496,13 @@ activitystreams-context@>=3.0.0, activitystreams-context@^3.0.0: resolved "https://registry.yarnpkg.com/activitystreams-context/-/activitystreams-context-3.1.0.tgz#28334e129f17cfb937e8c702c52c1bcb1d2830c7" integrity sha512-KBQ+igwf1tezMXGVw5MvRSEm0gp97JI1hTZ45I6MEkWv25lEgNoA9L6wqfaOiCX8wnMRWw9pwRsPZKypdtxAtg== +agent-base@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + aggregate-error@3.0.0, aggregate-error@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.0.tgz#5b5a3c95e9095f311c9ab16c19fb4f3527cd3f79" @@ -2632,6 +2695,11 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + cookie@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" @@ -3227,6 +3295,11 @@ es6-promise@^2.0.0: resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-2.3.0.tgz#96edb9f2fdb01995822b263dd8aadab6748181bc" integrity sha1-lu258v2wGZWCKyY92KratnSBgbw= +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + es6-promise@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-2.0.1.tgz#ccc4963e679f0ca9fb187c777b9e583d3c7573c2" @@ -3237,6 +3310,13 @@ es6-promise@~4.0.5: resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.0.5.tgz#7882f30adde5b240ccfa7f7d78c548330951ae42" integrity sha1-eILzCt3lskDM+n99eMVIMwlRrkI= +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + es6-symbol@^3.1.1, es6-symbol@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" @@ -4084,6 +4164,11 @@ graphql-iso-date@~3.6.1: resolved "https://registry.yarnpkg.com/graphql-iso-date/-/graphql-iso-date-3.6.1.tgz#bd2d0dc886e0f954cbbbc496bbf1d480b57ffa96" integrity sha512-AwFGIuYMJQXOEAgRlJlFL4H1ncFM8n8XmoVDTNypNOZyQ8LFDG2ppMFlsS862BSTCDcSUfHp8PD3/uJhv7t59Q== +graphql-middleware-sentry@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/graphql-middleware-sentry/-/graphql-middleware-sentry-3.2.0.tgz#a72872ae4b9fbe286980023a3c531286b8258df7" + integrity sha512-tIrxJIL+MRh2pxoot+EYJIrFfPgB3OF4nqmmh1gi54q/V1rgv7w46Ahn2jgl2nTu4bKw6mtGVF4CKikWCMPa5Q== + graphql-middleware@~3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/graphql-middleware/-/graphql-middleware-3.0.5.tgz#8cbce45ce4be95bd4600ffe5332e1936ec721e10" @@ -4383,6 +4468,14 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +https-proxy-agent@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -5728,6 +5821,11 @@ lru-cache@^5.0.0: dependencies: yallist "^3.0.2" +lru_map@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" + integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= + make-dir@^1.0.0, make-dir@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" diff --git a/webapp/nuxt.config.js b/webapp/nuxt.config.js index f6b6f42ec..00bd701ee 100644 --- a/webapp/nuxt.config.js +++ b/webapp/nuxt.config.js @@ -13,7 +13,7 @@ const styleguideStyles = process.env.STYLEGUIDE_DEV const buildDir = process.env.NUXT_BUILD || '.nuxt' const additionalSentryConfig = {} -if(process.env.COMMIT) additionalSentryConfig.release = process.env.COMMIT +if (process.env.COMMIT) additionalSentryConfig.release = process.env.COMMIT module.exports = { buildDir,