@constructive-io/graphql-server 4.6.0 → 4.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -70,13 +70,9 @@ const API_LIST_SQL = `
70
70
  LIMIT 100
71
71
  `;
72
72
  const RLS_MODULE_SQL = `
73
- SELECT
74
- rm.authenticate,
75
- rm.authenticate_strict,
76
- ps.schema_name as private_schema_name
77
- FROM metaschema_modules_public.rls_module rm
78
- LEFT JOIN metaschema_public.schema ps ON rm.private_schema_id = ps.id
79
- WHERE rm.api_id = $1
73
+ SELECT data
74
+ FROM services_public.api_modules
75
+ WHERE api_id = $1 AND name = 'rls_module'
80
76
  LIMIT 1
81
77
  `;
82
78
  // =============================================================================
@@ -113,14 +109,22 @@ export const getSvcKey = (opts, req) => {
113
109
  return baseKey;
114
110
  };
115
111
  const toRlsModule = (row) => {
116
- if (!row || !row.private_schema_name)
112
+ if (!row?.data)
117
113
  return undefined;
114
+ const d = row.data;
118
115
  return {
119
- authenticate: row.authenticate ?? undefined,
120
- authenticateStrict: row.authenticate_strict ?? undefined,
116
+ authenticate: d.authenticate,
117
+ authenticateStrict: d.authenticate_strict,
121
118
  privateSchema: {
122
- schemaName: row.private_schema_name,
119
+ schemaName: d.authenticate_schema,
120
+ },
121
+ publicSchema: {
122
+ schemaName: d.role_schema,
123
123
  },
124
+ currentRole: d.current_role,
125
+ currentRoleId: d.current_role_id,
126
+ currentIpAddress: d.current_ip_address,
127
+ currentUserAgent: d.current_user_agent,
124
128
  };
125
129
  };
126
130
  const toApiStructure = (row, opts, rlsModuleRow) => ({
@@ -46,36 +46,41 @@ const parseFileWithErrors = (req, res, next) => {
46
46
  return res.status(400).json({ error: 'File upload failed' });
47
47
  });
48
48
  };
49
- const RLS_MODULE_BASE_SQL = `
50
- SELECT
51
- rm.authenticate,
52
- rm.authenticate_strict,
53
- ps.schema_name as private_schema_name
54
- FROM metaschema_modules_public.rls_module rm
55
- LEFT JOIN metaschema_public.schema ps ON rm.private_schema_id = ps.id`;
56
- const RLS_MODULE_BY_DATABASE_ID_SQL = `${RLS_MODULE_BASE_SQL}
57
- JOIN services_public.apis a ON rm.api_id = a.id
58
- WHERE a.database_id = $1
49
+ const RLS_MODULE_BY_DATABASE_ID_SQL = `
50
+ SELECT am.data
51
+ FROM services_public.api_modules am
52
+ JOIN services_public.apis a ON am.api_id = a.id
53
+ WHERE am.name = 'rls_module' AND a.database_id = $1
59
54
  ORDER BY a.id
60
55
  LIMIT 1
61
56
  `;
62
- const RLS_MODULE_BY_API_ID_SQL = `${RLS_MODULE_BASE_SQL}
63
- WHERE rm.api_id = $1
57
+ const RLS_MODULE_BY_API_ID_SQL = `
58
+ SELECT data
59
+ FROM services_public.api_modules
60
+ WHERE api_id = $1 AND name = 'rls_module'
64
61
  LIMIT 1
65
62
  `;
66
- const RLS_MODULE_BY_DBNAME_SQL = `${RLS_MODULE_BASE_SQL}
67
- JOIN services_public.apis a ON rm.api_id = a.id
68
- WHERE a.dbname = $1
63
+ const RLS_MODULE_BY_DBNAME_SQL = `
64
+ SELECT am.data
65
+ FROM services_public.api_modules am
66
+ JOIN services_public.apis a ON am.api_id = a.id
67
+ WHERE am.name = 'rls_module' AND a.dbname = $1
69
68
  ORDER BY a.id
70
69
  LIMIT 1
71
70
  `;
72
71
  const toRlsModule = (row) => {
73
- if (!row || !row.private_schema_name)
72
+ if (!row?.data)
74
73
  return undefined;
74
+ const d = row.data;
75
75
  return {
76
- authenticate: row.authenticate ?? undefined,
77
- authenticateStrict: row.authenticate_strict ?? undefined,
78
- privateSchema: { schemaName: row.private_schema_name },
76
+ authenticate: d.authenticate,
77
+ authenticateStrict: d.authenticate_strict,
78
+ privateSchema: { schemaName: d.authenticate_schema },
79
+ publicSchema: { schemaName: d.role_schema },
80
+ currentRole: d.current_role,
81
+ currentRoleId: d.current_role_id,
82
+ currentIpAddress: d.current_ip_address,
83
+ currentUserAgent: d.current_user_agent,
79
84
  };
80
85
  };
81
86
  const getBearerToken = (authorization) => {
@@ -167,12 +172,6 @@ export const createUploadAuthenticateMiddleware = (opts) => {
167
172
  authError(res);
168
173
  return;
169
174
  }
170
- const SAFE_IDENTIFIER = /^[a-z_][a-z0-9_]*$/;
171
- if (!SAFE_IDENTIFIER.test(privateSchema) || !SAFE_IDENTIFIER.test(authFn)) {
172
- authLog.error(`[upload-auth] Invalid SQL identifier: schema=${privateSchema} fn=${authFn}`);
173
- authError(res);
174
- return;
175
- }
176
175
  const pool = getPgPool({
177
176
  ...opts.pg,
178
177
  database: api.dbname,
package/middleware/api.js CHANGED
@@ -76,13 +76,9 @@ const API_LIST_SQL = `
76
76
  LIMIT 100
77
77
  `;
78
78
  const RLS_MODULE_SQL = `
79
- SELECT
80
- rm.authenticate,
81
- rm.authenticate_strict,
82
- ps.schema_name as private_schema_name
83
- FROM metaschema_modules_public.rls_module rm
84
- LEFT JOIN metaschema_public.schema ps ON rm.private_schema_id = ps.id
85
- WHERE rm.api_id = $1
79
+ SELECT data
80
+ FROM services_public.api_modules
81
+ WHERE api_id = $1 AND name = 'rls_module'
86
82
  LIMIT 1
87
83
  `;
88
84
  // =============================================================================
@@ -121,14 +117,22 @@ const getSvcKey = (opts, req) => {
121
117
  };
122
118
  exports.getSvcKey = getSvcKey;
123
119
  const toRlsModule = (row) => {
124
- if (!row || !row.private_schema_name)
120
+ if (!row?.data)
125
121
  return undefined;
122
+ const d = row.data;
126
123
  return {
127
- authenticate: row.authenticate ?? undefined,
128
- authenticateStrict: row.authenticate_strict ?? undefined,
124
+ authenticate: d.authenticate,
125
+ authenticateStrict: d.authenticate_strict,
129
126
  privateSchema: {
130
- schemaName: row.private_schema_name,
127
+ schemaName: d.authenticate_schema,
128
+ },
129
+ publicSchema: {
130
+ schemaName: d.role_schema,
131
131
  },
132
+ currentRole: d.current_role,
133
+ currentRoleId: d.current_role_id,
134
+ currentIpAddress: d.current_ip_address,
135
+ currentUserAgent: d.current_user_agent,
132
136
  };
133
137
  };
134
138
  const toApiStructure = (row, opts, rlsModuleRow) => ({
@@ -52,36 +52,41 @@ const parseFileWithErrors = (req, res, next) => {
52
52
  return res.status(400).json({ error: 'File upload failed' });
53
53
  });
54
54
  };
55
- const RLS_MODULE_BASE_SQL = `
56
- SELECT
57
- rm.authenticate,
58
- rm.authenticate_strict,
59
- ps.schema_name as private_schema_name
60
- FROM metaschema_modules_public.rls_module rm
61
- LEFT JOIN metaschema_public.schema ps ON rm.private_schema_id = ps.id`;
62
- const RLS_MODULE_BY_DATABASE_ID_SQL = `${RLS_MODULE_BASE_SQL}
63
- JOIN services_public.apis a ON rm.api_id = a.id
64
- WHERE a.database_id = $1
55
+ const RLS_MODULE_BY_DATABASE_ID_SQL = `
56
+ SELECT am.data
57
+ FROM services_public.api_modules am
58
+ JOIN services_public.apis a ON am.api_id = a.id
59
+ WHERE am.name = 'rls_module' AND a.database_id = $1
65
60
  ORDER BY a.id
66
61
  LIMIT 1
67
62
  `;
68
- const RLS_MODULE_BY_API_ID_SQL = `${RLS_MODULE_BASE_SQL}
69
- WHERE rm.api_id = $1
63
+ const RLS_MODULE_BY_API_ID_SQL = `
64
+ SELECT data
65
+ FROM services_public.api_modules
66
+ WHERE api_id = $1 AND name = 'rls_module'
70
67
  LIMIT 1
71
68
  `;
72
- const RLS_MODULE_BY_DBNAME_SQL = `${RLS_MODULE_BASE_SQL}
73
- JOIN services_public.apis a ON rm.api_id = a.id
74
- WHERE a.dbname = $1
69
+ const RLS_MODULE_BY_DBNAME_SQL = `
70
+ SELECT am.data
71
+ FROM services_public.api_modules am
72
+ JOIN services_public.apis a ON am.api_id = a.id
73
+ WHERE am.name = 'rls_module' AND a.dbname = $1
75
74
  ORDER BY a.id
76
75
  LIMIT 1
77
76
  `;
78
77
  const toRlsModule = (row) => {
79
- if (!row || !row.private_schema_name)
78
+ if (!row?.data)
80
79
  return undefined;
80
+ const d = row.data;
81
81
  return {
82
- authenticate: row.authenticate ?? undefined,
83
- authenticateStrict: row.authenticate_strict ?? undefined,
84
- privateSchema: { schemaName: row.private_schema_name },
82
+ authenticate: d.authenticate,
83
+ authenticateStrict: d.authenticate_strict,
84
+ privateSchema: { schemaName: d.authenticate_schema },
85
+ publicSchema: { schemaName: d.role_schema },
86
+ currentRole: d.current_role,
87
+ currentRoleId: d.current_role_id,
88
+ currentIpAddress: d.current_ip_address,
89
+ currentUserAgent: d.current_user_agent,
85
90
  };
86
91
  };
87
92
  const getBearerToken = (authorization) => {
@@ -173,12 +178,6 @@ const createUploadAuthenticateMiddleware = (opts) => {
173
178
  authError(res);
174
179
  return;
175
180
  }
176
- const SAFE_IDENTIFIER = /^[a-z_][a-z0-9_]*$/;
177
- if (!SAFE_IDENTIFIER.test(privateSchema) || !SAFE_IDENTIFIER.test(authFn)) {
178
- authLog.error(`[upload-auth] Invalid SQL identifier: schema=${privateSchema} fn=${authFn}`);
179
- authError(res);
180
- return;
181
- }
182
181
  const pool = (0, pg_cache_1.getPgPool)({
183
182
  ...opts.pg,
184
183
  database: api.dbname,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-server",
3
- "version": "4.6.0",
3
+ "version": "4.8.2",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "Constructive GraphQL Server",
6
6
  "main": "index.js",
@@ -39,55 +39,55 @@
39
39
  "backend"
40
40
  ],
41
41
  "dependencies": {
42
- "@constructive-io/graphql-env": "^3.2.2",
43
- "@constructive-io/graphql-types": "^3.1.2",
44
- "@constructive-io/s3-utils": "^2.7.0",
45
- "@constructive-io/upload-names": "^2.7.0",
46
- "@constructive-io/url-domains": "^2.7.0",
42
+ "@constructive-io/graphql-env": "^3.4.2",
43
+ "@constructive-io/graphql-types": "^3.3.2",
44
+ "@constructive-io/s3-utils": "^2.9.2",
45
+ "@constructive-io/upload-names": "^2.9.2",
46
+ "@constructive-io/url-domains": "^2.9.2",
47
47
  "@graphile-contrib/pg-many-to-many": "2.0.0-rc.1",
48
48
  "@graphile/simplify-inflection": "8.0.0-rc.3",
49
- "@pgpmjs/env": "^2.13.0",
50
- "@pgpmjs/logger": "^2.2.0",
51
- "@pgpmjs/server-utils": "^3.2.0",
52
- "@pgpmjs/types": "^2.17.0",
49
+ "@pgpmjs/env": "^2.15.2",
50
+ "@pgpmjs/logger": "^2.4.2",
51
+ "@pgpmjs/server-utils": "^3.4.2",
52
+ "@pgpmjs/types": "^2.19.2",
53
53
  "@pgsql/quotes": "^17.1.0",
54
- "cors": "^2.8.5",
54
+ "cors": "^2.8.6",
55
55
  "deepmerge": "^4.3.1",
56
56
  "express": "^5.2.1",
57
- "gql-ast": "^3.1.0",
57
+ "gql-ast": "^3.3.2",
58
58
  "grafast": "1.0.0-rc.7",
59
59
  "grafserv": "1.0.0-rc.6",
60
60
  "graphile-build": "5.0.0-rc.4",
61
61
  "graphile-build-pg": "5.0.0-rc.5",
62
- "graphile-cache": "^3.1.0",
62
+ "graphile-cache": "^3.3.2",
63
63
  "graphile-config": "1.0.0-rc.5",
64
- "graphile-settings": "^4.6.2",
64
+ "graphile-settings": "^4.8.2",
65
65
  "graphile-utils": "5.0.0-rc.5",
66
- "graphql": "^16.9.0",
66
+ "graphql": "^16.13.0",
67
67
  "graphql-upload": "^13.0.0",
68
- "lru-cache": "^11.2.4",
69
- "multer": "^2.0.1",
70
- "pg": "^8.17.1",
71
- "pg-cache": "^3.1.0",
72
- "pg-env": "^1.5.0",
73
- "pg-query-context": "^2.6.0",
68
+ "lru-cache": "^11.2.6",
69
+ "multer": "^2.1.0",
70
+ "pg": "^8.19.0",
71
+ "pg-cache": "^3.3.2",
72
+ "pg-env": "^1.7.2",
73
+ "pg-query-context": "^2.8.2",
74
74
  "pg-sql2": "5.0.0-rc.4",
75
75
  "postgraphile": "5.0.0-rc.7",
76
76
  "postgraphile-plugin-connection-filter": "3.0.0-rc.1",
77
77
  "request-ip": "^3.3.0"
78
78
  },
79
79
  "devDependencies": {
80
- "@aws-sdk/client-s3": "^3.971.0",
80
+ "@aws-sdk/client-s3": "^3.1001.0",
81
81
  "@types/cors": "^2.8.17",
82
82
  "@types/express": "^5.0.6",
83
83
  "@types/graphql-upload": "^8.0.12",
84
- "@types/multer": "^1.4.12",
85
- "@types/pg": "^8.16.0",
84
+ "@types/multer": "^2.0.0",
85
+ "@types/pg": "^8.18.0",
86
86
  "@types/request-ip": "^0.0.41",
87
- "graphile-test": "4.3.1",
87
+ "graphile-test": "4.5.2",
88
88
  "makage": "^0.1.10",
89
- "nodemon": "^3.1.10",
89
+ "nodemon": "^3.1.14",
90
90
  "ts-node": "^10.9.2"
91
91
  },
92
- "gitHead": "16e3a687cf1d629d1eff1a9146e71bec14796196"
92
+ "gitHead": "4fd2c9be786ad9ae2213453276a69723435d5315"
93
93
  }
package/types.d.ts CHANGED
@@ -25,11 +25,18 @@ export type ApiModule = {
25
25
  data?: GenericModuleData;
26
26
  };
27
27
  export interface RlsModule {
28
- authenticate?: string;
29
- authenticateStrict?: string;
28
+ authenticate: string;
29
+ authenticateStrict: string;
30
30
  privateSchema: {
31
31
  schemaName: string;
32
32
  };
33
+ publicSchema: {
34
+ schemaName: string;
35
+ };
36
+ currentRole: string;
37
+ currentRoleId: string;
38
+ currentIpAddress: string;
39
+ currentUserAgent: string;
33
40
  }
34
41
  export interface ApiStructure {
35
42
  apiId?: string;