Mirror of https://github.com/roostorg/coop github.com/roostorg/coop
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Setting GraphQL depth limit to 10 (#109)

* Setting GraphQL depth limit to 10

* Set env var for GraphQL depth

Used safe var helper to ensure proper integer is being used for GraphQL depth

Using Node 24.14.0, as directed to make CI happy

* Cleared merge conflict

* Logging error instead of throwing error

* Use jsonStringify for logging invalid env var

This change addresses ESLint warning about type safety of JSON.stringify.

Co-authored-by: Paweł Wieczorek <pawiecz@collabora.com>

authored by

Matthew McMorries
Paweł Wieczorek
and committed by
GitHub
adb0eebd dc18da58

+87 -2
+1
.env.githubci
··· 47 47 SCYLLA_COMPACTION_STRATEGY='SizeTieredCompactionStrategy' 48 48 SCYLLA_HAS_ENTERPRISE_FEATURES='false' 49 49 50 + GRAPHQL_MAX_DEPTH=10 50 51 EXPOSE_SENSITIVE_IMPLEMENTATION_DETAILS_IN_ERRORS=true 51 52 ALLOW_USER_INPUT_LOCALHOST_URIS=true 52 53 SEQUELIZE_PRINT_LOGS=true
+1
server/.env.example
··· 81 81 82 82 ITEM_QUEUE_TRAFFIC_PERCENTAGE='0.05' 83 83 UI_URL=http://localhost:3000 84 + GRAPHQL_MAX_DEPTH=10
+3
server/api.ts
··· 24 24 import express, { type ErrorRequestHandler } from 'express'; 25 25 import session from 'express-session'; 26 26 import { buildContext, GraphQLLocalStrategy } from 'graphql-passport'; 27 + import depthLimit from 'graphql-depth-limit'; 27 28 import helmet from 'helmet'; 28 29 import passport from 'passport'; 29 30 import { MultiSamlStrategy } from '@node-saml/passport-saml'; ··· 37 38 import typeDefs from './graphql/schema.js'; 38 39 import { authSchemaWrapper } from './graphql/utils/authorization.js'; 39 40 import { type Dependencies } from './iocContainer/index.js'; 41 + import { safeGetEnvInt } from './iocContainer/utils.js'; 40 42 import controllers from './routes/index.js'; 41 43 import { jsonStringify } from './utils/encoding.js'; 42 44 import { ··· 373 375 : ApolloServerPluginLandingPageGraphQLPlayground()), 374 376 }, 375 377 ], 378 + validationRules: [depthLimit(safeGetEnvInt('GRAPHQL_MAX_DEPTH', 10))], 376 379 introspection: process.env.NODE_ENV !== 'production', 377 380 formatError(e) { 378 381 // `e` can be an ApolloError instance, but will only be one if such an
+19
server/iocContainer/utils.ts
··· 3 3 import type Bottle from '@ethanresnick/bottlejs'; 4 4 5 5 import { __throw } from '../utils/misc.js'; 6 + import { jsonStringify } from '../utils/encoding.js'; 6 7 import { type Dependencies as Deps } from './index.js'; 7 8 8 9 const DEPENDENCIES = Symbol(); ··· 661 662 process.env[varName] ?? __throw(new Error(`Missing env var ${varName}`)) 662 663 ); 663 664 } 665 + 666 + /** 667 + * Gets an env var and parses it as a positive integer. Returns `defaultValue` 668 + * if the variable is unset or invalid, logging an error on misconfiguration. 669 + */ 670 + export function safeGetEnvInt(varName: string, defaultValue: number): number { 671 + const raw = process.env[varName]; 672 + if (raw === undefined) return defaultValue; 673 + const parsed = parseInt(raw, 10); 674 + if (!Number.isInteger(parsed) || parsed <= 0) { 675 + // eslint-disable-next-line no-console 676 + console.error( 677 + `Invalid env var ${varName}: expected a positive integer, got ${jsonStringify(raw)}. Using default value ${defaultValue}.`, 678 + ); 679 + return defaultValue; 680 + } 681 + return parsed; 682 + }
+61 -2
server/package-lock.json
··· 65 65 "fuzzball": "^2.1.2", 66 66 "generic-pool": "^3.8.2", 67 67 "graphql": "^16.0.1", 68 + "graphql-depth-limit": "^1.1.0", 68 69 "graphql-passport": "^0.6.4", 69 70 "graphql-scalars": "^1.19.0", 70 71 "helmet": "^4.6.0", ··· 105 106 "@eslint/js": "^9.39.4", 106 107 "@faker-js/faker": "^7.5.0", 107 108 "@types/cls-hooked": "^4.3.3", 109 + "@types/graphql-depth-limit": "^1.1.6", 108 110 "@types/jest": "^29.2.4", 109 111 "@types/js-yaml": "^4.0.5", 110 112 "@types/stream-json": "^1.7.7", ··· 10620 10622 "@types/node": "*" 10621 10623 } 10622 10624 }, 10625 + "node_modules/@types/graphql-depth-limit": { 10626 + "version": "1.1.6", 10627 + "resolved": "https://registry.npmjs.org/@types/graphql-depth-limit/-/graphql-depth-limit-1.1.6.tgz", 10628 + "integrity": "sha512-WU4bjoKOzJ8CQE32Pbyq+YshTMcLJf2aJuvVtSLv1BQPwDUGa38m2Vr8GGxf0GZ0luCQcfxlhZeHKu6nmTBvrw==", 10629 + "dev": true, 10630 + "license": "MIT", 10631 + "dependencies": { 10632 + "graphql": "^14.5.3" 10633 + } 10634 + }, 10635 + "node_modules/@types/graphql-depth-limit/node_modules/graphql": { 10636 + "version": "14.7.0", 10637 + "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.7.0.tgz", 10638 + "integrity": "sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==", 10639 + "deprecated": "No longer supported; please update to a newer version. Details: https://github.com/graphql/graphql-js#version-support", 10640 + "dev": true, 10641 + "license": "MIT", 10642 + "dependencies": { 10643 + "iterall": "^1.2.2" 10644 + }, 10645 + "engines": { 10646 + "node": ">= 6.x" 10647 + } 10648 + }, 10623 10649 "node_modules/@types/http-errors": { 10624 10650 "version": "2.0.1", 10625 10651 "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", ··· 10722 10748 "node_modules/@types/node": { 10723 10749 "version": "18.17.3", 10724 10750 "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.3.tgz", 10725 - "integrity": "sha512-2x8HWtFk0S99zqVQABU9wTpr8wPoaDHZUcAkoTKH+nL7kPv3WUI9cRi/Kk5Mz4xdqXSqTkKP7IWNoQQYCnDsTA==" 10751 + "integrity": "sha512-2x8HWtFk0S99zqVQABU9wTpr8wPoaDHZUcAkoTKH+nL7kPv3WUI9cRi/Kk5Mz4xdqXSqTkKP7IWNoQQYCnDsTA==", 10752 + "peer": true 10726 10753 }, 10727 10754 "node_modules/@types/node-fetch": { 10728 10755 "version": "2.6.4", ··· 11811 11838 "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", 11812 11839 "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", 11813 11840 "license": "MIT", 11841 + "peer": true, 11814 11842 "bin": { 11815 11843 "acorn": "bin/acorn" 11816 11844 }, ··· 12400 12428 "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", 12401 12429 "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", 12402 12430 "license": "MIT", 12431 + "peer": true, 12403 12432 "dependencies": { 12404 12433 "follow-redirects": "^1.15.11", 12405 12434 "form-data": "^4.0.5", ··· 14564 14593 "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", 14565 14594 "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", 14566 14595 "license": "MIT", 14596 + "peer": true, 14567 14597 "dependencies": { 14568 14598 "accepts": "~1.3.8", 14569 14599 "array-flatten": "1.1.1", ··· 15522 15552 "version": "16.8.2", 15523 15553 "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.2.tgz", 15524 15554 "integrity": "sha512-cvVIBILwuoSyD54U4cF/UXDh5yAobhNV/tPygI4lZhgOIJQE/WLWC4waBRb4I6bDVYb3OVx3lfHbaQOEoUD5sg==", 15555 + "peer": true, 15525 15556 "engines": { 15526 15557 "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" 15527 15558 } 15528 15559 }, 15560 + "node_modules/graphql-depth-limit": { 15561 + "version": "1.1.0", 15562 + "resolved": "https://registry.npmjs.org/graphql-depth-limit/-/graphql-depth-limit-1.1.0.tgz", 15563 + "integrity": "sha512-+3B2BaG8qQ8E18kzk9yiSdAa75i/hnnOwgSeAxVJctGQPvmeiLtqKOYF6HETCyRjiF7Xfsyal0HbLlxCQkgkrw==", 15564 + "license": "MIT", 15565 + "dependencies": { 15566 + "arrify": "^1.0.1" 15567 + }, 15568 + "engines": { 15569 + "node": ">=6.0.0" 15570 + }, 15571 + "peerDependencies": { 15572 + "graphql": "*" 15573 + } 15574 + }, 15575 + "node_modules/graphql-depth-limit/node_modules/arrify": { 15576 + "version": "1.0.1", 15577 + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", 15578 + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", 15579 + "license": "MIT", 15580 + "engines": { 15581 + "node": ">=0.10.0" 15582 + } 15583 + }, 15529 15584 "node_modules/graphql-passport": { 15530 15585 "version": "0.6.7", 15531 15586 "resolved": "https://registry.npmjs.org/graphql-passport/-/graphql-passport-0.6.7.tgz", ··· 15939 15994 "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.9.2.tgz", 15940 15995 "integrity": "sha512-tAAg/72/VxOUW7RQSX1pIxJVucYKcjFjfvj60L57jrZpYCHC3XN0WCQ3sNYL4Gmvv+7GPvTAjc+KSdeNuE8oWQ==", 15941 15996 "license": "MIT", 15997 + "peer": true, 15942 15998 "dependencies": { 15943 15999 "@ioredis/commands": "1.5.0", 15944 16000 "cluster-key-slot": "^1.1.0", ··· 16486 16542 "version": "1.3.0", 16487 16543 "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", 16488 16544 "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", 16489 - "optional": true 16545 + "devOptional": true 16490 16546 }, 16491 16547 "node_modules/jackspeak": { 16492 16548 "version": "3.4.3", ··· 18457 18513 "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", 18458 18514 "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", 18459 18515 "license": "MIT", 18516 + "peer": true, 18460 18517 "dependencies": { 18461 18518 "passport-strategy": "1.x.x", 18462 18519 "pause": "0.0.1", ··· 20647 20704 "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", 20648 20705 "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", 20649 20706 "dev": true, 20707 + "peer": true, 20650 20708 "dependencies": { 20651 20709 "@cspotcode/source-map-support": "^0.8.0", 20652 20710 "@tsconfig/node10": "^1.0.7", ··· 20879 20937 "version": "5.5.2", 20880 20938 "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", 20881 20939 "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", 20940 + "peer": true, 20882 20941 "bin": { 20883 20942 "tsc": "bin/tsc", 20884 20943 "tsserver": "bin/tsserver"
+2
server/package.json
··· 79 79 "fuzzball": "^2.1.2", 80 80 "generic-pool": "^3.8.2", 81 81 "graphql": "^16.0.1", 82 + "graphql-depth-limit": "^1.1.0", 82 83 "graphql-passport": "^0.6.4", 83 84 "graphql-scalars": "^1.19.0", 84 85 "helmet": "^4.6.0", ··· 119 120 "@eslint/js": "^9.39.4", 120 121 "@faker-js/faker": "^7.5.0", 121 122 "@types/cls-hooked": "^4.3.3", 123 + "@types/graphql-depth-limit": "^1.1.6", 122 124 "@types/jest": "^29.2.4", 123 125 "@types/js-yaml": "^4.0.5", 124 126 "@types/stream-json": "^1.7.7",