@axinom/mosaic-id-guard 0.18.0-rc.15 → 0.18.0-rc.16
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.
- package/dist/common/helpers/guard-authorization.d.ts +22 -0
- package/dist/common/helpers/guard-authorization.d.ts.map +1 -0
- package/dist/common/helpers/guard-authorization.js +49 -0
- package/dist/common/helpers/guard-authorization.js.map +1 -0
- package/dist/common/id-guard-error.d.ts +1 -0
- package/dist/common/id-guard-error.d.ts.map +1 -1
- package/dist/common/id-guard-error.js +7 -1
- package/dist/common/id-guard-error.js.map +1 -1
- package/dist/common/id-guard-errors.d.ts +8 -0
- package/dist/common/id-guard-errors.d.ts.map +1 -1
- package/dist/common/id-guard-errors.js +8 -0
- package/dist/common/id-guard-errors.js.map +1 -1
- package/dist/graphql/ax-guard-plugin.d.ts +23 -0
- package/dist/graphql/ax-guard-plugin.d.ts.map +1 -0
- package/dist/graphql/ax-guard-plugin.js +29 -0
- package/dist/graphql/ax-guard-plugin.js.map +1 -0
- package/dist/graphql/enforce-strict-permissions.plugin.d.ts +1 -1
- package/dist/graphql/enforce-strict-permissions.plugin.d.ts.map +1 -1
- package/dist/graphql/index.d.ts +3 -2
- package/dist/graphql/index.d.ts.map +1 -1
- package/dist/graphql/index.js +3 -2
- package/dist/graphql/index.js.map +1 -1
- package/dist/graphql/{guard-plugin.d.ts → query-mutation-guard-plugin.d.ts} +2 -2
- package/dist/graphql/query-mutation-guard-plugin.d.ts.map +1 -0
- package/dist/graphql/{guard-plugin.js → query-mutation-guard-plugin.js} +5 -26
- package/dist/graphql/query-mutation-guard-plugin.js.map +1 -0
- package/dist/graphql/subscription-guard-plugin.d.ts +20 -0
- package/dist/graphql/subscription-guard-plugin.d.ts.map +1 -0
- package/dist/graphql/subscription-guard-plugin.js +81 -0
- package/dist/graphql/subscription-guard-plugin.js.map +1 -0
- package/package.json +9 -10
- package/src/common/helpers/guard-authorization.ts +76 -0
- package/src/common/id-guard-error.ts +13 -0
- package/src/common/id-guard-errors.ts +10 -0
- package/src/graphql/ax-guard-plugin.ts +29 -0
- package/src/graphql/enforce-strict-permissions.plugin.ts +1 -1
- package/src/graphql/index.ts +3 -2
- package/src/graphql/{guard-plugin.spec.ts → query-mutation-guard-plugin.spec.ts} +3 -3
- package/src/graphql/{guard-plugin.ts → query-mutation-guard-plugin.ts} +12 -36
- package/src/graphql/subscription-guard-plugin.spec.ts +257 -0
- package/src/graphql/subscription-guard-plugin.ts +112 -0
- package/dist/graphql/guard-plugin.d.ts.map +0 -1
- package/dist/graphql/guard-plugin.js.map +0 -1
- package/dist/graphql/subscription-authorization-hook-factory.d.ts +0 -13
- package/dist/graphql/subscription-authorization-hook-factory.d.ts.map +0 -1
- package/dist/graphql/subscription-authorization-hook-factory.js +0 -182
- package/dist/graphql/subscription-authorization-hook-factory.js.map +0 -1
- package/src/graphql/subscription-authorization-hook-factory.spec.ts +0 -749
- package/src/graphql/subscription-authorization-hook-factory.ts +0 -286
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MosaicErrorInfo } from '@axinom/mosaic-service-common';
|
|
2
|
+
import { GraphQLFieldResolver, GraphQLResolveInfo } from 'graphql';
|
|
3
|
+
import { AxGuardOptions } from '../guard-utils';
|
|
4
|
+
import { GenericAuthenticatedSubject } from '../types/authenticated-subject-models';
|
|
5
|
+
/**
|
|
6
|
+
* Handles authorization for a given GraphQL mutation/query/subscription against a
|
|
7
|
+
* user token.
|
|
8
|
+
*
|
|
9
|
+
* @param subject Authenticated Subject
|
|
10
|
+
* @param authErrorInfo Authentication Error Info
|
|
11
|
+
* @param options AxGuardOptions
|
|
12
|
+
* @param resolveFunc Resolver function from guard-plugin or subscription-guard-plugin.
|
|
13
|
+
* @param parent
|
|
14
|
+
* @param args
|
|
15
|
+
* @param context
|
|
16
|
+
* @param info
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
export declare const handleAuthorization: (subject: GenericAuthenticatedSubject | undefined, authErrorInfo: MosaicErrorInfo | undefined, options: AxGuardOptions, resolveFunc: GraphQLFieldResolver<unknown, unknown, {
|
|
20
|
+
[argName: string]: unknown;
|
|
21
|
+
}>, parent: unknown, args: Record<string, unknown>, context: unknown, info: GraphQLResolveInfo) => unknown;
|
|
22
|
+
//# sourceMappingURL=guard-authorization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard-authorization.d.ts","sourceRoot":"","sources":["../../../src/common/helpers/guard-authorization.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIhD,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAEpF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,YACrB,2BAA2B,GAAG,SAAS,iBACjC,eAAe,GAAG,SAAS,WACjC,cAAc;;YAQf,OAAO,QACT,OAAO,MAAM,EAAE,OAAO,CAAC,WACpB,OAAO,QACV,kBAAkB,KACvB,OAqCF,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleAuthorization = void 0;
|
|
4
|
+
const mosaic_service_common_1 = require("@axinom/mosaic-service-common");
|
|
5
|
+
const __1 = require("..");
|
|
6
|
+
const handle_end_user_authorization_1 = require("../handle-end-user-authorization");
|
|
7
|
+
const handle_management_user_authorization_1 = require("../handle-management-user-authorization");
|
|
8
|
+
const type_assertions_1 = require("../type-assertions");
|
|
9
|
+
/**
|
|
10
|
+
* Handles authorization for a given GraphQL mutation/query/subscription against a
|
|
11
|
+
* user token.
|
|
12
|
+
*
|
|
13
|
+
* @param subject Authenticated Subject
|
|
14
|
+
* @param authErrorInfo Authentication Error Info
|
|
15
|
+
* @param options AxGuardOptions
|
|
16
|
+
* @param resolveFunc Resolver function from guard-plugin or subscription-guard-plugin.
|
|
17
|
+
* @param parent
|
|
18
|
+
* @param args
|
|
19
|
+
* @param context
|
|
20
|
+
* @param info
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
const handleAuthorization = (subject, authErrorInfo, options, resolveFunc, parent, args, context, info) => {
|
|
24
|
+
// If the permissionDefinition is not undefined, then the subject is a AuthenticatedManagementSubject
|
|
25
|
+
if (options.authorizationOptions.permissionDefinition !== undefined) {
|
|
26
|
+
if (subject !== undefined && subject !== null) {
|
|
27
|
+
(0, type_assertions_1.assertGenericAuthenticatedSubject)(subject);
|
|
28
|
+
}
|
|
29
|
+
(0, handle_management_user_authorization_1.handleManagementUserAuthorization)(options.authorizationOptions, options.ensureOnlyAuthentication, subject, authErrorInfo);
|
|
30
|
+
return resolveFunc.call(this, parent, args, context, info);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
/**
|
|
34
|
+
* This block handles end-user operations.
|
|
35
|
+
* If the if condition (options.authorizationOptions.permissionDefinition !== undefined) falls through to this else branch,
|
|
36
|
+
* then the request is a end-user call.
|
|
37
|
+
*/
|
|
38
|
+
if (options.authorizationOptions.endUserAuthorizationConfig === undefined) {
|
|
39
|
+
throw new mosaic_service_common_1.MosaicError(__1.IdGuardErrors.AuthorizationOptionsMisconfigured);
|
|
40
|
+
}
|
|
41
|
+
if (subject !== undefined && subject !== null) {
|
|
42
|
+
(0, type_assertions_1.assertGenericAuthenticatedSubject)(subject);
|
|
43
|
+
}
|
|
44
|
+
(0, handle_end_user_authorization_1.handleEndUserAuthorization)(options.authorizationOptions, options.ensureOnlyAuthentication, subject, authErrorInfo);
|
|
45
|
+
return resolveFunc.call(this, parent, args, context, info);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.handleAuthorization = handleAuthorization;
|
|
49
|
+
//# sourceMappingURL=guard-authorization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard-authorization.js","sourceRoot":"","sources":["../../../src/common/helpers/guard-authorization.ts"],"names":[],"mappings":";;;AAAA,yEAA6E;AAE7E,0BAAmC;AAEnC,oFAA8E;AAC9E,kGAA4F;AAC5F,wDAAuE;AAGvE;;;;;;;;;;;;;GAaG;AACI,MAAM,mBAAmB,GAAG,CACjC,OAAgD,EAChD,aAA0C,EAC1C,OAAuB,EACvB,WAMC,EACD,MAAe,EACf,IAA6B,EAC7B,OAAgB,EAChB,IAAwB,EACf,EAAE;IACX,qGAAqG;IACrG,IAAI,OAAO,CAAC,oBAAoB,CAAC,oBAAoB,KAAK,SAAS,EAAE;QACnE,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE;YAC7C,IAAA,mDAAiC,EAAC,OAAO,CAAC,CAAC;SAC5C;QAED,IAAA,wEAAiC,EAC/B,OAAO,CAAC,oBAAoB,EAC5B,OAAO,CAAC,wBAAwB,EAChC,OAAO,EACP,aAAa,CACd,CAAC;QACF,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;KAC5D;SAAM;QACL;;;;WAIG;QAEH,IAAI,OAAO,CAAC,oBAAoB,CAAC,0BAA0B,KAAK,SAAS,EAAE;YACzE,MAAM,IAAI,mCAAW,CAAC,iBAAa,CAAC,iCAAiC,CAAC,CAAC;SACxE;QAED,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE;YAC7C,IAAA,mDAAiC,EAAC,OAAO,CAAC,CAAC;SAC5C;QAED,IAAA,0DAA0B,EACxB,OAAO,CAAC,oBAAoB,EAC5B,OAAO,CAAC,wBAAwB,EAChC,OAAO,EACP,aAAa,CACd,CAAC;QACF,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;KAC5D;AACH,CAAC,CAAC;AApDW,QAAA,mBAAmB,uBAoD9B"}
|
|
@@ -2,4 +2,5 @@ import { MosaicError, MosaicErrorInfo } from '@axinom/mosaic-service-common';
|
|
|
2
2
|
export declare class IdGuardError extends MosaicError {
|
|
3
3
|
constructor(info: MosaicErrorInfo);
|
|
4
4
|
}
|
|
5
|
+
export declare const assertIdGuardError: (error: unknown) => asserts error is IdGuardError;
|
|
5
6
|
//# sourceMappingURL=id-guard-error.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id-guard-error.d.ts","sourceRoot":"","sources":["../../src/common/id-guard-error.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,eAAe,
|
|
1
|
+
{"version":3,"file":"id-guard-error.d.ts","sourceRoot":"","sources":["../../src/common/id-guard-error.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,eAAe,EAGhB,MAAM,+BAA+B,CAAC;AAEvC,qBAAa,YAAa,SAAQ,WAAW;gBAC/B,IAAI,EAAE,eAAe;CAIlC;AAED,eAAO,MAAM,kBAAkB,EAAE,CAC/B,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,KAAK,IAAI,YAQrB,CAAC"}
|
|
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.IdGuardError = void 0;
|
|
14
|
+
exports.assertIdGuardError = exports.IdGuardError = void 0;
|
|
15
15
|
const mosaic_service_common_1 = require("@axinom/mosaic-service-common");
|
|
16
16
|
class IdGuardError extends mosaic_service_common_1.MosaicError {
|
|
17
17
|
constructor(info) {
|
|
@@ -20,4 +20,10 @@ class IdGuardError extends mosaic_service_common_1.MosaicError {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
exports.IdGuardError = IdGuardError;
|
|
23
|
+
const assertIdGuardError = (error) => {
|
|
24
|
+
if (!(error instanceof IdGuardError)) {
|
|
25
|
+
throw new mosaic_service_common_1.NonMosaicError(`A caught error is not an instance of an IdGuardError class.`);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.assertIdGuardError = assertIdGuardError;
|
|
23
29
|
//# sourceMappingURL=id-guard-error.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id-guard-error.js","sourceRoot":"","sources":["../../src/common/id-guard-error.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"id-guard-error.js","sourceRoot":"","sources":["../../src/common/id-guard-error.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,yEAKuC;AAEvC,MAAa,YAAa,SAAQ,mCAAW;IAC3C,YAAY,IAAqB;QAC/B,MAAM,EAAE,OAAO,KAAwB,IAAI,EAAvB,cAAc,UAAK,IAAI,EAArC,WAA8B,CAAO,CAAC;QAC5C,KAAK,iCAAM,cAAc,KAAE,OAAO,kCAAO,OAAO,KAAE,WAAW,EAAX,mCAAW,OAAK,CAAC;IACrE,CAAC;CACF;AALD,oCAKC;AAEM,MAAM,kBAAkB,GAEM,CACnC,KAAc,EACiB,EAAE;IACjC,IAAI,CAAC,CAAC,KAAK,YAAY,YAAY,CAAC,EAAE;QACpC,MAAM,IAAI,sCAAc,CACtB,6DAA6D,CAC9D,CAAC;KACH;AACH,CAAC,CAAC;AAVW,QAAA,kBAAkB,sBAU7B"}
|
|
@@ -83,5 +83,13 @@ export declare const IdGuardErrors: {
|
|
|
83
83
|
readonly message: "Authenticated End User not found.";
|
|
84
84
|
readonly code: "AUTHENTICATED_END_USER_NOT_FOUND";
|
|
85
85
|
};
|
|
86
|
+
readonly WebSocketNotFound: {
|
|
87
|
+
readonly message: "Websocket not found in ExtendedGraphQLContext. This is a development time issue. A reference to the websocket must be included in Postgraphile build options.";
|
|
88
|
+
readonly code: "WEBSOCKET_NOT_FOUND";
|
|
89
|
+
};
|
|
90
|
+
readonly AuthorizationOptionsMisconfigured: {
|
|
91
|
+
readonly message: "A Permission Definition or an EndUserAuthorizationConfig was not found to be passed into Postgraphile build options. This is a development time issue.";
|
|
92
|
+
readonly code: "AUTHORIZATION_OPTIONS_MISCONFIGURED";
|
|
93
|
+
};
|
|
86
94
|
};
|
|
87
95
|
//# sourceMappingURL=id-guard-errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id-guard-errors.d.ts","sourceRoot":"","sources":["../../src/common/id-guard-errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa
|
|
1
|
+
{"version":3,"file":"id-guard-errors.d.ts","sourceRoot":"","sources":["../../src/common/id-guard-errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmGhB,CAAC"}
|
|
@@ -86,5 +86,13 @@ exports.IdGuardErrors = {
|
|
|
86
86
|
message: 'Authenticated End User not found.',
|
|
87
87
|
code: 'AUTHENTICATED_END_USER_NOT_FOUND',
|
|
88
88
|
},
|
|
89
|
+
WebSocketNotFound: {
|
|
90
|
+
message: 'Websocket not found in ExtendedGraphQLContext. This is a development time issue. A reference to the websocket must be included in Postgraphile build options.',
|
|
91
|
+
code: 'WEBSOCKET_NOT_FOUND',
|
|
92
|
+
},
|
|
93
|
+
AuthorizationOptionsMisconfigured: {
|
|
94
|
+
message: 'A Permission Definition or an EndUserAuthorizationConfig was not found to be passed into Postgraphile build options. This is a development time issue.',
|
|
95
|
+
code: 'AUTHORIZATION_OPTIONS_MISCONFIGURED',
|
|
96
|
+
},
|
|
89
97
|
};
|
|
90
98
|
//# sourceMappingURL=id-guard-errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id-guard-errors.js","sourceRoot":"","sources":["../../src/common/id-guard-errors.ts"],"names":[],"mappings":";;;AAAa,QAAA,aAAa,GAAG;IAC3B,mBAAmB,EAAE;QACnB,OAAO,EAAE,8BAA8B;QACvC,IAAI,EAAE,uBAAuB;KAC9B;IACD,kBAAkB,EAAE;QAClB,OAAO,EAAE,yBAAyB;QAClC,IAAI,EAAE,sBAAsB;KAC7B;IACD,kBAAkB,EAAE;QAClB,OAAO,EAAE,2BAA2B;QACpC,IAAI,EAAE,sBAAsB;KAC7B;IACD,iBAAiB,EAAE;QACjB,OAAO,EAAE,iDAAiD;QAC1D,IAAI,EAAE,qBAAqB;KAC5B;IACD,kBAAkB,EAAE;QAClB,OAAO,EACL,oMAAoM;QACtM,IAAI,EAAE,uBAAuB;KAC9B;IACD,SAAS,EAAE;QACT,OAAO,EACL,kHAAkH;QACpH,IAAI,EAAE,YAAY;KACnB;IACD,6BAA6B,EAAE;QAC7B,OAAO,EAAE,kCAAkC;QAC3C,IAAI,EAAE,kCAAkC;KACzC;IACD,4BAA4B,EAAE;QAC5B,OAAO,EACL,wEAAwE;QAC1E,IAAI,EAAE,iCAAiC;KACxC;IACD,wBAAwB,EAAE;QACxB,OAAO,EACL,oEAAoE;QACtE,IAAI,EAAE,6BAA6B;KACpC;IACD,iBAAiB,EAAE;QACjB,OAAO,EAAE,yBAAyB;QAClC,IAAI,EAAE,qBAAqB;KAC5B;IACD,0BAA0B,EAAE;QAC1B,OAAO,EAAE,gEAAgE;QACzE,IAAI,EAAE,yBAAyB;KAChC;IACD,sCAAsC,EAAE;QACtC,OAAO,EAAE,6CAA6C;QACtD,IAAI,EAAE,4CAA4C;KACnD;IACD,uBAAuB,EAAE;QACvB,OAAO,EAAE,4CAA4C;QACrD,IAAI,EAAE,4BAA4B;KACnC;IACD,qBAAqB,EAAE;QACrB,OAAO,EAAE,0CAA0C;QACnD,IAAI,EAAE,0BAA0B;KACjC;IACD,8BAA8B,EAAE;QAC9B,OAAO,EAAE,iDAAiD;QAC1D,IAAI,EAAE,mCAAmC;KAC1C;IACD,iCAAiC,EAAE;QACjC,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,sCAAsC;KAC7C;IACD,uBAAuB,EAAE;QACvB,OAAO,EAAE,0CAA0C;QACnD,IAAI,EAAE,2BAA2B;KAClC;IACD,kCAAkC,EAAE;QAClC,OAAO,EAAE,qDAAqD;QAC9D,IAAI,EAAE,uCAAuC;KAC9C;IACD,+BAA+B,EAAE;QAC/B,OAAO,EAAE,mDAAmD;QAC5D,IAAI,EAAE,qCAAqC;KAC5C;IACD,cAAc,EAAE;QACd,OAAO,EAAE,iCAAiC;QAC1C,IAAI,EAAE,iBAAiB;KACxB;IACD,4BAA4B,EAAE;QAC5B,OAAO,EAAE,mCAAmC;QAC5C,IAAI,EAAE,kCAAkC;KACzC;CACO,CAAC"}
|
|
1
|
+
{"version":3,"file":"id-guard-errors.js","sourceRoot":"","sources":["../../src/common/id-guard-errors.ts"],"names":[],"mappings":";;;AAAa,QAAA,aAAa,GAAG;IAC3B,mBAAmB,EAAE;QACnB,OAAO,EAAE,8BAA8B;QACvC,IAAI,EAAE,uBAAuB;KAC9B;IACD,kBAAkB,EAAE;QAClB,OAAO,EAAE,yBAAyB;QAClC,IAAI,EAAE,sBAAsB;KAC7B;IACD,kBAAkB,EAAE;QAClB,OAAO,EAAE,2BAA2B;QACpC,IAAI,EAAE,sBAAsB;KAC7B;IACD,iBAAiB,EAAE;QACjB,OAAO,EAAE,iDAAiD;QAC1D,IAAI,EAAE,qBAAqB;KAC5B;IACD,kBAAkB,EAAE;QAClB,OAAO,EACL,oMAAoM;QACtM,IAAI,EAAE,uBAAuB;KAC9B;IACD,SAAS,EAAE;QACT,OAAO,EACL,kHAAkH;QACpH,IAAI,EAAE,YAAY;KACnB;IACD,6BAA6B,EAAE;QAC7B,OAAO,EAAE,kCAAkC;QAC3C,IAAI,EAAE,kCAAkC;KACzC;IACD,4BAA4B,EAAE;QAC5B,OAAO,EACL,wEAAwE;QAC1E,IAAI,EAAE,iCAAiC;KACxC;IACD,wBAAwB,EAAE;QACxB,OAAO,EACL,oEAAoE;QACtE,IAAI,EAAE,6BAA6B;KACpC;IACD,iBAAiB,EAAE;QACjB,OAAO,EAAE,yBAAyB;QAClC,IAAI,EAAE,qBAAqB;KAC5B;IACD,0BAA0B,EAAE;QAC1B,OAAO,EAAE,gEAAgE;QACzE,IAAI,EAAE,yBAAyB;KAChC;IACD,sCAAsC,EAAE;QACtC,OAAO,EAAE,6CAA6C;QACtD,IAAI,EAAE,4CAA4C;KACnD;IACD,uBAAuB,EAAE;QACvB,OAAO,EAAE,4CAA4C;QACrD,IAAI,EAAE,4BAA4B;KACnC;IACD,qBAAqB,EAAE;QACrB,OAAO,EAAE,0CAA0C;QACnD,IAAI,EAAE,0BAA0B;KACjC;IACD,8BAA8B,EAAE;QAC9B,OAAO,EAAE,iDAAiD;QAC1D,IAAI,EAAE,mCAAmC;KAC1C;IACD,iCAAiC,EAAE;QACjC,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,sCAAsC;KAC7C;IACD,uBAAuB,EAAE;QACvB,OAAO,EAAE,0CAA0C;QACnD,IAAI,EAAE,2BAA2B;KAClC;IACD,kCAAkC,EAAE;QAClC,OAAO,EAAE,qDAAqD;QAC9D,IAAI,EAAE,uCAAuC;KAC9C;IACD,+BAA+B,EAAE;QAC/B,OAAO,EAAE,mDAAmD;QAC5D,IAAI,EAAE,qCAAqC;KAC5C;IACD,cAAc,EAAE;QACd,OAAO,EAAE,iCAAiC;QAC1C,IAAI,EAAE,iBAAiB;KACxB;IACD,4BAA4B,EAAE;QAC5B,OAAO,EAAE,mCAAmC;QAC5C,IAAI,EAAE,kCAAkC;KACzC;IACD,iBAAiB,EAAE;QACjB,OAAO,EACL,+JAA+J;QACjK,IAAI,EAAE,qBAAqB;KAC5B;IACD,iCAAiC,EAAE;QACjC,OAAO,EACL,wJAAwJ;QAC1J,IAAI,EAAE,qCAAqC;KAC5C;CACO,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AxGuard plugin is created by combining two plugins - `QueryMutationGuardPlugin`
|
|
3
|
+
* and `SubscriptionGuardPlugin`.
|
|
4
|
+
*
|
|
5
|
+
* This plugin handles authorization for GraphQL resources exposed by the APIs.
|
|
6
|
+
* For Queries and Mutations an error is thrown if the authorization fails.
|
|
7
|
+
*
|
|
8
|
+
* For subscriptions, if the JWT token expires while subscription events are emitted,
|
|
9
|
+
* the websocket connection is closed with `4403` code, allowing the client to automatically
|
|
10
|
+
* re-establish the connection.
|
|
11
|
+
* For authorization errors, the websocket is closed with `4401` code.
|
|
12
|
+
*
|
|
13
|
+
* **!!!!!!!!!! IMPORTANT !!!!!!!!!!**
|
|
14
|
+
*
|
|
15
|
+
* When using this plugin with subscriptions, it's mandatory to send the reference to
|
|
16
|
+
* the websocket through Extended GraphQL Context with the key name `websocket`.
|
|
17
|
+
* `getWebsocketFromRequest` from `@axinom/mosaic-service-common` can be used to extract the
|
|
18
|
+
* websocket from request.
|
|
19
|
+
*
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
export declare const AxGuardPlugin: import("graphile-build").Plugin;
|
|
23
|
+
//# sourceMappingURL=ax-guard-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ax-guard-plugin.d.ts","sourceRoot":"","sources":["../../src/graphql/ax-guard-plugin.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,aAAa,iCAGzB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AxGuardPlugin = void 0;
|
|
4
|
+
const graphile_utils_1 = require("graphile-utils");
|
|
5
|
+
const query_mutation_guard_plugin_1 = require("./query-mutation-guard-plugin");
|
|
6
|
+
const subscription_guard_plugin_1 = require("./subscription-guard-plugin");
|
|
7
|
+
/**
|
|
8
|
+
* AxGuard plugin is created by combining two plugins - `QueryMutationGuardPlugin`
|
|
9
|
+
* and `SubscriptionGuardPlugin`.
|
|
10
|
+
*
|
|
11
|
+
* This plugin handles authorization for GraphQL resources exposed by the APIs.
|
|
12
|
+
* For Queries and Mutations an error is thrown if the authorization fails.
|
|
13
|
+
*
|
|
14
|
+
* For subscriptions, if the JWT token expires while subscription events are emitted,
|
|
15
|
+
* the websocket connection is closed with `4403` code, allowing the client to automatically
|
|
16
|
+
* re-establish the connection.
|
|
17
|
+
* For authorization errors, the websocket is closed with `4401` code.
|
|
18
|
+
*
|
|
19
|
+
* **!!!!!!!!!! IMPORTANT !!!!!!!!!!**
|
|
20
|
+
*
|
|
21
|
+
* When using this plugin with subscriptions, it's mandatory to send the reference to
|
|
22
|
+
* the websocket through Extended GraphQL Context with the key name `websocket`.
|
|
23
|
+
* `getWebsocketFromRequest` from `@axinom/mosaic-service-common` can be used to extract the
|
|
24
|
+
* websocket from request.
|
|
25
|
+
*
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
exports.AxGuardPlugin = (0, graphile_utils_1.makePluginByCombiningPlugins)(query_mutation_guard_plugin_1.QueryMutationGuardPlugin, subscription_guard_plugin_1.SubscriptionGuardPlugin);
|
|
29
|
+
//# sourceMappingURL=ax-guard-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ax-guard-plugin.js","sourceRoot":"","sources":["../../src/graphql/ax-guard-plugin.ts"],"names":[],"mappings":";;;AAAA,mDAA8D;AAC9D,+EAAyE;AACzE,2EAAsE;AAEtE;;;;;;;;;;;;;;;;;;;;GAoBG;AACU,QAAA,aAAa,GAAG,IAAA,6CAA4B,EACvD,sDAAwB,EACxB,mDAAuB,CACxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforce-strict-permissions.plugin.d.ts","sourceRoot":"","sources":["../../src/graphql/enforce-strict-permissions.plugin.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"enforce-strict-permissions.plugin.d.ts","sourceRoot":"","sources":["../../src/graphql/enforce-strict-permissions.plugin.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAQtC;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,EAAE,MA+I5C,CAAC"}
|
package/dist/graphql/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
export * from './ax-guard-plugin';
|
|
1
2
|
export * from './enforce-strict-permissions.plugin';
|
|
2
3
|
export * from './guard-context';
|
|
3
4
|
export { setupEndUserAuthentication, setupEndUserGQLSubscriptionAuthentication, setupManagementAuthentication, setupManagementGQLSubscriptionAuthentication, throwEndUserAuthError, throwManagementAuthError, } from './guard-middleware';
|
|
4
|
-
export * from './guard-plugin';
|
|
5
|
-
export * from './subscription-
|
|
5
|
+
export * from './query-mutation-guard-plugin';
|
|
6
|
+
export * from './subscription-guard-plugin';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graphql/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACL,0BAA0B,EAC1B,yCAAyC,EACzC,6BAA6B,EAC7B,4CAA4C,EAC5C,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graphql/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,qCAAqC,CAAC;AACpD,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACL,0BAA0B,EAC1B,yCAAyC,EACzC,6BAA6B,EAC7B,4CAA4C,EAC5C,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAC5B,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC"}
|
package/dist/graphql/index.js
CHANGED
|
@@ -11,6 +11,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.throwManagementAuthError = exports.throwEndUserAuthError = exports.setupManagementGQLSubscriptionAuthentication = exports.setupManagementAuthentication = exports.setupEndUserGQLSubscriptionAuthentication = exports.setupEndUserAuthentication = void 0;
|
|
14
|
+
__exportStar(require("./ax-guard-plugin"), exports);
|
|
14
15
|
__exportStar(require("./enforce-strict-permissions.plugin"), exports);
|
|
15
16
|
__exportStar(require("./guard-context"), exports);
|
|
16
17
|
var guard_middleware_1 = require("./guard-middleware");
|
|
@@ -20,6 +21,6 @@ Object.defineProperty(exports, "setupManagementAuthentication", { enumerable: tr
|
|
|
20
21
|
Object.defineProperty(exports, "setupManagementGQLSubscriptionAuthentication", { enumerable: true, get: function () { return guard_middleware_1.setupManagementGQLSubscriptionAuthentication; } });
|
|
21
22
|
Object.defineProperty(exports, "throwEndUserAuthError", { enumerable: true, get: function () { return guard_middleware_1.throwEndUserAuthError; } });
|
|
22
23
|
Object.defineProperty(exports, "throwManagementAuthError", { enumerable: true, get: function () { return guard_middleware_1.throwManagementAuthError; } });
|
|
23
|
-
__exportStar(require("./guard-plugin"), exports);
|
|
24
|
-
__exportStar(require("./subscription-
|
|
24
|
+
__exportStar(require("./query-mutation-guard-plugin"), exports);
|
|
25
|
+
__exportStar(require("./subscription-guard-plugin"), exports);
|
|
25
26
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graphql/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,sEAAoD;AACpD,kDAAgC;AAChC,uDAO4B;AAN1B,8HAAA,0BAA0B,OAAA;AAC1B,6IAAA,yCAAyC,OAAA;AACzC,iIAAA,6BAA6B,OAAA;AAC7B,gJAAA,4CAA4C,OAAA;AAC5C,yHAAA,qBAAqB,OAAA;AACrB,4HAAA,wBAAwB,OAAA;AAE1B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graphql/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,oDAAkC;AAClC,sEAAoD;AACpD,kDAAgC;AAChC,uDAO4B;AAN1B,8HAAA,0BAA0B,OAAA;AAC1B,6IAAA,yCAAyC,OAAA;AACzC,iIAAA,6BAA6B,OAAA;AAC7B,gJAAA,4CAA4C,OAAA;AAC5C,yHAAA,qBAAqB,OAAA;AACrB,4HAAA,wBAAwB,OAAA;AAE1B,gEAA8C;AAC9C,8DAA4C"}
|
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
* @param additionalGraphQLContextFromRequest should be of type `Record<string, any> & { subject: AuthenticatedSubject, authErrorInfo: AxGuardErrorInfo }`
|
|
8
8
|
* @param graphileBuildOptions should be of type `Partial<Options> & { permissionDefinition: PermissionDefinition, serviceId: string, ensureOnlyAuthentication: boolean }`
|
|
9
9
|
*/
|
|
10
|
-
export declare const
|
|
11
|
-
//# sourceMappingURL=guard-plugin.d.ts.map
|
|
10
|
+
export declare const QueryMutationGuardPlugin: import("graphile-build").Plugin;
|
|
11
|
+
//# sourceMappingURL=query-mutation-guard-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-mutation-guard-plugin.d.ts","sourceRoot":"","sources":["../../src/graphql/query-mutation-guard-plugin.ts"],"names":[],"mappings":"AAWA;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,iCAyDpC,CAAC"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.QueryMutationGuardPlugin = void 0;
|
|
4
4
|
const graphile_utils_1 = require("graphile-utils");
|
|
5
|
-
const common_1 = require("../common");
|
|
6
5
|
const guard_utils_1 = require("../common/guard-utils");
|
|
7
|
-
const
|
|
8
|
-
const handle_management_user_authorization_1 = require("../common/handle-management-user-authorization");
|
|
6
|
+
const guard_authorization_1 = require("../common/helpers/guard-authorization");
|
|
9
7
|
/**
|
|
10
8
|
* Postgraphile plugin that wraps resolver execution into an authentication check, making sure that that JwtToken subject is authorized to access a GraphQL resource.
|
|
11
9
|
* It extracts the `ensureOnlyAuthentication` property from Postgraphile Build Options to determine if only the authentication check must be performed or authorization checks
|
|
@@ -15,7 +13,7 @@ const handle_management_user_authorization_1 = require("../common/handle-managem
|
|
|
15
13
|
* @param additionalGraphQLContextFromRequest should be of type `Record<string, any> & { subject: AuthenticatedSubject, authErrorInfo: AxGuardErrorInfo }`
|
|
16
14
|
* @param graphileBuildOptions should be of type `Partial<Options> & { permissionDefinition: PermissionDefinition, serviceId: string, ensureOnlyAuthentication: boolean }`
|
|
17
15
|
*/
|
|
18
|
-
exports.
|
|
16
|
+
exports.QueryMutationGuardPlugin = (0, graphile_utils_1.makeWrapResolversPlugin)(({ scope }, _build, _config, { ensureOnlyAuthentication, serviceId, permissionDefinition, endUserAuthorizationConfig, }) => {
|
|
19
17
|
const operationCanBeProtected = scope.fieldName !== 'query' &&
|
|
20
18
|
(scope.isRootQuery ||
|
|
21
19
|
scope.isRootMutation ||
|
|
@@ -40,25 +38,6 @@ exports.AxGuardPlugin = (0, graphile_utils_1.makeWrapResolversPlugin)(({ scope }
|
|
|
40
38
|
options.authorizationOptions.operation = resolveInfo.fieldName;
|
|
41
39
|
// Validate if the Postgraphile build options related to authorization are correctly set.
|
|
42
40
|
(0, guard_utils_1.validatePostgraphileBuildOptions)(options);
|
|
43
|
-
|
|
44
|
-
if (options.authorizationOptions.permissionDefinition !== undefined) {
|
|
45
|
-
if (subject !== undefined && subject !== null) {
|
|
46
|
-
(0, common_1.assertGenericAuthenticatedSubject)(subject);
|
|
47
|
-
}
|
|
48
|
-
(0, handle_management_user_authorization_1.handleManagementUserAuthorization)(options.authorizationOptions, options.ensureOnlyAuthentication, subject, authErrorInfo);
|
|
49
|
-
return resolver(source, args, context, resolveInfo);
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
/**
|
|
53
|
-
* This block handles end-user operations.
|
|
54
|
-
* If the if condition (options.authorizationOptions.permissionDefinition !== undefined) falls through to this else branch,
|
|
55
|
-
* it is assumed that the request is a end-user call.
|
|
56
|
-
*/
|
|
57
|
-
if (subject !== undefined && subject !== null) {
|
|
58
|
-
(0, common_1.assertGenericAuthenticatedSubject)(subject);
|
|
59
|
-
}
|
|
60
|
-
(0, handle_end_user_authorization_1.handleEndUserAuthorization)(options.authorizationOptions, options.ensureOnlyAuthentication, subject, authErrorInfo);
|
|
61
|
-
return resolver(source, args, context, resolveInfo);
|
|
62
|
-
}
|
|
41
|
+
return (0, guard_authorization_1.handleAuthorization)(subject, authErrorInfo, options, resolver, source, args, context, resolveInfo);
|
|
63
42
|
});
|
|
64
|
-
//# sourceMappingURL=guard-plugin.js.map
|
|
43
|
+
//# sourceMappingURL=query-mutation-guard-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-mutation-guard-plugin.js","sourceRoot":"","sources":["../../src/graphql/query-mutation-guard-plugin.ts"],"names":[],"mappings":";;;AAAA,mDAAyD;AAKzD,uDAG+B;AAC/B,+EAA4E;AAE5E;;;;;;;;GAQG;AACU,QAAA,wBAAwB,GAAG,IAAA,wCAAuB,EAC7D,CACE,EAAE,KAAK,EAAE,EACT,MAAM,EACN,OAAO,EACP,EACE,wBAAwB,EACxB,SAAS,EACT,oBAAoB,EACpB,0BAA0B,GAC3B,EACD,EAAE;IACF,MAAM,uBAAuB,GAC3B,KAAK,CAAC,SAAS,KAAK,OAAO;QAC3B,CAAC,KAAK,CAAC,WAAW;YAChB,KAAK,CAAC,cAAc;YACpB,KAAK,CAAC,wBAAwB;YAC9B,KAAK,CAAC,yBAAyB;YAC/B,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAE9B,IAAI,uBAAuB,EAAE;QAC3B,OAAO;YACL,wBAAwB,EAAE,wBAAwB,aAAxB,wBAAwB,cAAxB,wBAAwB,GAAI,KAAK;YAC3D,oBAAoB,EAAE;gBACpB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,SAAS;gBACT,oBAAoB;gBACpB,0BAA0B;aAC3B;SACF,CAAC;KACH;IAED,OAAO,IAAI,CAAC;AACd,CAAC,EACD,CAAC,OAAuB,EAAE,EAAE,CAC1B,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE;IACrD,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,OAEH,CAAC,CAAC,mEAAmE;IAErG,sIAAsI;IACtI,OAAO,CAAC,oBAAoB,CAAC,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC;IAE/D,yFAAyF;IACzF,IAAA,8CAAgC,EAAC,OAAO,CAAC,CAAC;IAE1C,OAAO,IAAA,yCAAmB,EACxB,OAAO,EACP,aAAa,EACb,OAAO,EACP,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,OAAO,EACP,WAAW,CACZ,CAAC;AACJ,CAAC,CACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Plugin } from 'postgraphile';
|
|
2
|
+
/**
|
|
3
|
+
* This plugin wraps around the `subscribe` method for subscriptions
|
|
4
|
+
* and performs authorization, making sure that that JwtToken subject is authorized to access a GraphQL resource.
|
|
5
|
+
*
|
|
6
|
+
* The websocket is closed with error code 4403 if the access token has expired, allowing the client
|
|
7
|
+
* to re-establish the connection.
|
|
8
|
+
* If any other error is thrown, the websocket is closed with error code 4401.
|
|
9
|
+
*
|
|
10
|
+
* **!!!!!!!!!! IMPORTANT !!!!!!!!!!**
|
|
11
|
+
*
|
|
12
|
+
* When using this plugin, it's mandatory to send the reference to the websocket through
|
|
13
|
+
* Extended GraphQL Context with the key name `websocket`.
|
|
14
|
+
* `getWebsocketFromRequest` from `@axinom/mosaic-service-common` can be used to extract the
|
|
15
|
+
* websocket from request.
|
|
16
|
+
*
|
|
17
|
+
* @param builder
|
|
18
|
+
*/
|
|
19
|
+
export declare const SubscriptionGuardPlugin: Plugin;
|
|
20
|
+
//# sourceMappingURL=subscription-guard-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription-guard-plugin.d.ts","sourceRoot":"","sources":["../../src/graphql/subscription-guard-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAatC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,EAAE,MA+ErC,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SubscriptionGuardPlugin = void 0;
|
|
4
|
+
const mosaic_service_common_1 = require("@axinom/mosaic-service-common");
|
|
5
|
+
const graphql_ws_1 = require("graphql-ws");
|
|
6
|
+
const common_1 = require("../common");
|
|
7
|
+
const guard_utils_1 = require("../common/guard-utils");
|
|
8
|
+
const guard_authorization_1 = require("../common/helpers/guard-authorization");
|
|
9
|
+
/**
|
|
10
|
+
* This plugin wraps around the `subscribe` method for subscriptions
|
|
11
|
+
* and performs authorization, making sure that that JwtToken subject is authorized to access a GraphQL resource.
|
|
12
|
+
*
|
|
13
|
+
* The websocket is closed with error code 4403 if the access token has expired, allowing the client
|
|
14
|
+
* to re-establish the connection.
|
|
15
|
+
* If any other error is thrown, the websocket is closed with error code 4401.
|
|
16
|
+
*
|
|
17
|
+
* **!!!!!!!!!! IMPORTANT !!!!!!!!!!**
|
|
18
|
+
*
|
|
19
|
+
* When using this plugin, it's mandatory to send the reference to the websocket through
|
|
20
|
+
* Extended GraphQL Context with the key name `websocket`.
|
|
21
|
+
* `getWebsocketFromRequest` from `@axinom/mosaic-service-common` can be used to extract the
|
|
22
|
+
* websocket from request.
|
|
23
|
+
*
|
|
24
|
+
* @param builder
|
|
25
|
+
*/
|
|
26
|
+
const SubscriptionGuardPlugin = (builder) => {
|
|
27
|
+
builder.hook('GraphQLObjectType:fields:field', (field, build, _context) => {
|
|
28
|
+
if (field.subscribe) {
|
|
29
|
+
const oldSubscribe = field.subscribe;
|
|
30
|
+
field.subscribe = async function (parent, args,
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
+
context, info) {
|
|
33
|
+
var _a;
|
|
34
|
+
if (!context.websocket) {
|
|
35
|
+
throw new mosaic_service_common_1.MosaicError(common_1.IdGuardErrors.WebSocketNotFound);
|
|
36
|
+
}
|
|
37
|
+
const options = {
|
|
38
|
+
authorizationOptions: {
|
|
39
|
+
endUserAuthorizationConfig: build.options.endUserAuthorizationConfig,
|
|
40
|
+
operation: info.fieldName,
|
|
41
|
+
permissionDefinition: build.options.permissionDefinition,
|
|
42
|
+
serviceId: build.options.serviceId,
|
|
43
|
+
},
|
|
44
|
+
ensureOnlyAuthentication: (_a = build.options.ensureOnlyAuthentication) !== null && _a !== void 0 ? _a : false,
|
|
45
|
+
};
|
|
46
|
+
const { authErrorInfo, subject } = context; // The context could be either a Management or an End-User context.
|
|
47
|
+
try {
|
|
48
|
+
// Validate if the Postgraphile build options related to authorization are correctly set.
|
|
49
|
+
(0, guard_utils_1.validatePostgraphileBuildOptions)(options);
|
|
50
|
+
return (0, guard_authorization_1.handleAuthorization)(subject, authErrorInfo, options, oldSubscribe, parent, args, context, info);
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
(0, common_1.assertIdGuardError)(error);
|
|
54
|
+
/**
|
|
55
|
+
* If the token has expired, we close the connection with CloseCode.Forbidden, and allow the client to automatically re-establish
|
|
56
|
+
* the connection with a new token.
|
|
57
|
+
*/
|
|
58
|
+
if (error.code === common_1.IdGuardErrors.AccessTokenExpired.code) {
|
|
59
|
+
/**
|
|
60
|
+
* `CloseCode.Forbidden` is used so that the client will automatically start retry process with a newer token.
|
|
61
|
+
* Any other CloseCode will result in a client exception and the client will not automatically retry.
|
|
62
|
+
*/
|
|
63
|
+
context.websocket.close(graphql_ws_1.CloseCode.Forbidden, common_1.IdGuardErrors.AccessTokenExpired.code);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// Close the websocket connection.
|
|
67
|
+
context.websocket.close(graphql_ws_1.CloseCode.Unauthorized, error.message);
|
|
68
|
+
}
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return field;
|
|
74
|
+
}, [], [],
|
|
75
|
+
// Add the `subscribe` method to the graphql fields, wrapping around the GQL resolver.
|
|
76
|
+
// It looks for the `@pgSubscription` directive, and adds the `subscribe` method.
|
|
77
|
+
// https://github.com/graphile/graphile-engine/blob/1bc8cfefdab7a61fd7ad287bcdff66298352e308/packages/pg-pubsub/src/PgSubscriptionResolverPlugin.ts
|
|
78
|
+
['PgSubscriptionResolver']);
|
|
79
|
+
};
|
|
80
|
+
exports.SubscriptionGuardPlugin = SubscriptionGuardPlugin;
|
|
81
|
+
//# sourceMappingURL=subscription-guard-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription-guard-plugin.js","sourceRoot":"","sources":["../../src/graphql/subscription-guard-plugin.ts"],"names":[],"mappings":";;;AAAA,yEAA4D;AAC5D,2CAAuC;AAEvC,sCAKmB;AACnB,uDAG+B;AAC/B,+EAA4E;AAE5E;;;;;;;;;;;;;;;;GAgBG;AACI,MAAM,uBAAuB,GAAW,CAAC,OAAO,EAAE,EAAE;IACzD,OAAO,CAAC,IAAI,CACV,gCAAgC,EAChC,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QACzB,IAAI,KAAK,CAAC,SAAS,EAAE;YACnB,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC;YACrC,KAAK,CAAC,SAAS,GAAG,KAAK,WACrB,MAAe,EACf,IAAI;YACJ,8DAA8D;YAC9D,OAAY,EACZ,IAAI;;gBAEJ,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;oBACtB,MAAM,IAAI,mCAAW,CAAC,sBAAa,CAAC,iBAAiB,CAAC,CAAC;iBACxD;gBAED,MAAM,OAAO,GAAmB;oBAC9B,oBAAoB,EAAE;wBACpB,0BAA0B,EACxB,KAAK,CAAC,OAAO,CAAC,0BAA0B;wBAC1C,SAAS,EAAE,IAAI,CAAC,SAAS;wBACzB,oBAAoB,EAAE,KAAK,CAAC,OAAO,CAAC,oBAAoB;wBACxD,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS;qBACnC;oBACD,wBAAwB,EACtB,MAAA,KAAK,CAAC,OAAO,CAAC,wBAAwB,mCAAI,KAAK;iBAClD,CAAC;gBAEF,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,OAEH,CAAC,CAAC,mEAAmE;gBAErG,IAAI;oBACF,yFAAyF;oBACzF,IAAA,8CAAgC,EAAC,OAAO,CAAC,CAAC;oBAE1C,OAAO,IAAA,yCAAmB,EACxB,OAAO,EACP,aAAa,EACb,OAAO,EACP,YAAY,EACZ,MAAM,EACN,IAAI,EACJ,OAAO,EACP,IAAI,CACL,CAAC;iBACH;gBAAC,OAAO,KAAK,EAAE;oBACd,IAAA,2BAAkB,EAAC,KAAK,CAAC,CAAC;oBAC1B;;;uBAGG;oBACH,IAAI,KAAK,CAAC,IAAI,KAAK,sBAAa,CAAC,kBAAkB,CAAC,IAAI,EAAE;wBACxD;;;2BAGG;wBACH,OAAO,CAAC,SAAS,CAAC,KAAK,CACrB,sBAAS,CAAC,SAAS,EACnB,sBAAa,CAAC,kBAAkB,CAAC,IAAI,CACtC,CAAC;qBACH;yBAAM;wBACL,kCAAkC;wBAClC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,sBAAS,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;qBAChE;oBACD,MAAM,KAAK,CAAC;iBACb;YACH,CAAC,CAAC;SACH;QACD,OAAO,KAAK,CAAC;IACf,CAAC,EACD,EAAE,EACF,EAAE;IACF,sFAAsF;IACtF,iFAAiF;IACjF,mJAAmJ;IACnJ,CAAC,wBAAwB,CAAC,CAC3B,CAAC;AACJ,CAAC,CAAC;AA/EW,QAAA,uBAAuB,2BA+ElC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axinom/mosaic-id-guard",
|
|
3
|
-
"version": "0.18.0-rc.
|
|
3
|
+
"version": "0.18.0-rc.16",
|
|
4
4
|
"description": "Authentication and authorization helpers for Axinom Mosaic services",
|
|
5
5
|
"author": "Axinom",
|
|
6
6
|
"license": "PROPRIETARY",
|
|
@@ -28,22 +28,21 @@
|
|
|
28
28
|
"lint": "eslint . --ext .ts,.tsx,.js --color --cache"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@axinom/mosaic-id-utils": "^0.12.0-rc.
|
|
32
|
-
"@axinom/mosaic-message-bus": "^0.13.0-rc.
|
|
33
|
-
"@axinom/mosaic-service-common": "^0.28.0-rc.
|
|
31
|
+
"@axinom/mosaic-id-utils": "^0.12.0-rc.16",
|
|
32
|
+
"@axinom/mosaic-message-bus": "^0.13.0-rc.16",
|
|
33
|
+
"@axinom/mosaic-service-common": "^0.28.0-rc.16",
|
|
34
34
|
"amqplib": "^0.6.0",
|
|
35
35
|
"express": "^4.17.1",
|
|
36
36
|
"express-bearer-token": "^2.4.0",
|
|
37
|
-
"graphile-build": "^4.
|
|
38
|
-
"graphile-
|
|
39
|
-
"graphile-utils": "^4.12.1",
|
|
37
|
+
"graphile-build": "^4.13.0",
|
|
38
|
+
"graphile-utils": "^4.13.0",
|
|
40
39
|
"graphql": "^15.4.0",
|
|
41
40
|
"graphql-tag": "^2.11.0",
|
|
42
|
-
"graphql-ws": "^5.
|
|
41
|
+
"graphql-ws": "^5.11.2",
|
|
43
42
|
"jsonwebtoken": "^8.5.1",
|
|
44
43
|
"jwks-rsa": "^1.8.1",
|
|
45
44
|
"pg": "^8.5.1",
|
|
46
|
-
"postgraphile": "^4.
|
|
45
|
+
"postgraphile": "^4.13.0",
|
|
47
46
|
"rascal": "^14.0.1",
|
|
48
47
|
"subscriptions-transport-ws": "^0.9.19"
|
|
49
48
|
},
|
|
@@ -61,5 +60,5 @@
|
|
|
61
60
|
"publishConfig": {
|
|
62
61
|
"access": "public"
|
|
63
62
|
},
|
|
64
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "f80d456f741b896faf54b7181ca348ca2aba1cd2"
|
|
65
64
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { MosaicError, MosaicErrorInfo } from '@axinom/mosaic-service-common';
|
|
2
|
+
import { GraphQLFieldResolver, GraphQLResolveInfo } from 'graphql';
|
|
3
|
+
import { IdGuardErrors } from '..';
|
|
4
|
+
import { AxGuardOptions } from '../guard-utils';
|
|
5
|
+
import { handleEndUserAuthorization } from '../handle-end-user-authorization';
|
|
6
|
+
import { handleManagementUserAuthorization } from '../handle-management-user-authorization';
|
|
7
|
+
import { assertGenericAuthenticatedSubject } from '../type-assertions';
|
|
8
|
+
import { GenericAuthenticatedSubject } from '../types/authenticated-subject-models';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Handles authorization for a given GraphQL mutation/query/subscription against a
|
|
12
|
+
* user token.
|
|
13
|
+
*
|
|
14
|
+
* @param subject Authenticated Subject
|
|
15
|
+
* @param authErrorInfo Authentication Error Info
|
|
16
|
+
* @param options AxGuardOptions
|
|
17
|
+
* @param resolveFunc Resolver function from guard-plugin or subscription-guard-plugin.
|
|
18
|
+
* @param parent
|
|
19
|
+
* @param args
|
|
20
|
+
* @param context
|
|
21
|
+
* @param info
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
24
|
+
export const handleAuthorization = (
|
|
25
|
+
subject: GenericAuthenticatedSubject | undefined,
|
|
26
|
+
authErrorInfo: MosaicErrorInfo | undefined,
|
|
27
|
+
options: AxGuardOptions,
|
|
28
|
+
resolveFunc: GraphQLFieldResolver<
|
|
29
|
+
unknown,
|
|
30
|
+
unknown,
|
|
31
|
+
{
|
|
32
|
+
[argName: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
>,
|
|
35
|
+
parent: unknown,
|
|
36
|
+
args: Record<string, unknown>,
|
|
37
|
+
context: unknown,
|
|
38
|
+
info: GraphQLResolveInfo,
|
|
39
|
+
): unknown => {
|
|
40
|
+
// If the permissionDefinition is not undefined, then the subject is a AuthenticatedManagementSubject
|
|
41
|
+
if (options.authorizationOptions.permissionDefinition !== undefined) {
|
|
42
|
+
if (subject !== undefined && subject !== null) {
|
|
43
|
+
assertGenericAuthenticatedSubject(subject);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
handleManagementUserAuthorization(
|
|
47
|
+
options.authorizationOptions,
|
|
48
|
+
options.ensureOnlyAuthentication,
|
|
49
|
+
subject,
|
|
50
|
+
authErrorInfo,
|
|
51
|
+
);
|
|
52
|
+
return resolveFunc.call(this, parent, args, context, info);
|
|
53
|
+
} else {
|
|
54
|
+
/**
|
|
55
|
+
* This block handles end-user operations.
|
|
56
|
+
* If the if condition (options.authorizationOptions.permissionDefinition !== undefined) falls through to this else branch,
|
|
57
|
+
* then the request is a end-user call.
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
if (options.authorizationOptions.endUserAuthorizationConfig === undefined) {
|
|
61
|
+
throw new MosaicError(IdGuardErrors.AuthorizationOptionsMisconfigured);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (subject !== undefined && subject !== null) {
|
|
65
|
+
assertGenericAuthenticatedSubject(subject);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
handleEndUserAuthorization(
|
|
69
|
+
options.authorizationOptions,
|
|
70
|
+
options.ensureOnlyAuthentication,
|
|
71
|
+
subject,
|
|
72
|
+
authErrorInfo,
|
|
73
|
+
);
|
|
74
|
+
return resolveFunc.call(this, parent, args, context, info);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MosaicError,
|
|
3
3
|
MosaicErrorInfo,
|
|
4
|
+
NonMosaicError,
|
|
4
5
|
skipMaskTag,
|
|
5
6
|
} from '@axinom/mosaic-service-common';
|
|
6
7
|
|
|
@@ -10,3 +11,15 @@ export class IdGuardError extends MosaicError {
|
|
|
10
11
|
super({ ...everythingElse, details: { ...details, skipMaskTag } });
|
|
11
12
|
}
|
|
12
13
|
}
|
|
14
|
+
|
|
15
|
+
export const assertIdGuardError: (
|
|
16
|
+
error: unknown,
|
|
17
|
+
) => asserts error is IdGuardError = (
|
|
18
|
+
error: unknown,
|
|
19
|
+
): asserts error is IdGuardError => {
|
|
20
|
+
if (!(error instanceof IdGuardError)) {
|
|
21
|
+
throw new NonMosaicError(
|
|
22
|
+
`A caught error is not an instance of an IdGuardError class.`,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -87,4 +87,14 @@ export const IdGuardErrors = {
|
|
|
87
87
|
message: 'Authenticated End User not found.',
|
|
88
88
|
code: 'AUTHENTICATED_END_USER_NOT_FOUND',
|
|
89
89
|
},
|
|
90
|
+
WebSocketNotFound: {
|
|
91
|
+
message:
|
|
92
|
+
'Websocket not found in ExtendedGraphQLContext. This is a development time issue. A reference to the websocket must be included in Postgraphile build options.',
|
|
93
|
+
code: 'WEBSOCKET_NOT_FOUND',
|
|
94
|
+
},
|
|
95
|
+
AuthorizationOptionsMisconfigured: {
|
|
96
|
+
message:
|
|
97
|
+
'A Permission Definition or an EndUserAuthorizationConfig was not found to be passed into Postgraphile build options. This is a development time issue.',
|
|
98
|
+
code: 'AUTHORIZATION_OPTIONS_MISCONFIGURED',
|
|
99
|
+
},
|
|
90
100
|
} as const;
|