@nxgt/shared-graphql 1.2.3 → 1.4.0
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/README.md +76 -0
- package/dist/directives/check.d.ts +40 -0
- package/dist/directives/check.d.ts.map +1 -0
- package/dist/directives/index.d.ts +1 -0
- package/dist/directives/index.d.ts.map +1 -1
- package/dist/index.js +127 -5
- package/dist/index.js.map +5 -3
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/keto-checks.d.ts +48 -0
- package/dist/plugins/keto-checks.d.ts.map +1 -0
- package/graphql/directives/check.graphqls +86 -0
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -33,6 +33,82 @@ schema: ['./src/**/*.graphqls', SHARED_SCHEMA_PATH],
|
|
|
33
33
|
A relative path into this package's `src/` will not work from an install — it
|
|
34
34
|
is not published, and it was not there in the first place.
|
|
35
35
|
|
|
36
|
+
## `@check` — the permission a field requires
|
|
37
|
+
|
|
38
|
+
`@authenticated` asks whether anyone is calling. `@policy` asks whether they
|
|
39
|
+
*carry* an authority. Neither can ask what an Ory-native API needs to know:
|
|
40
|
+
**may this caller `view` `Note:n1`** — a question about one object, answered by
|
|
41
|
+
Keto.
|
|
42
|
+
|
|
43
|
+
`@check` asks it. The declaration ships in `graphql/directives/check.graphqls`,
|
|
44
|
+
so any schema built from `SHARED_SCHEMA_PATH` already has it; `useKetoChecks(ory)`
|
|
45
|
+
is what answers it.
|
|
46
|
+
|
|
47
|
+
```graphql
|
|
48
|
+
note(id: ID!): Note!
|
|
49
|
+
@check(permissions: [[{ namespace: "Note", permit: "view" }]])
|
|
50
|
+
|
|
51
|
+
updateNote(id: ID!, input: UpdateNoteInput!): Note!
|
|
52
|
+
@check(permissions: [[{ namespace: "Note", permit: "view" }]])
|
|
53
|
+
@check(permissions: [[{ namespace: "Note", permit: "edit" }]], onDeny: FORBIDDEN)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
plugins: [useOryAuth(ory), useKetoChecks(ory), useGenericAuth({ … })]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`permissions` is disjunctive normal form — **outer list OR, inner list AND**,
|
|
61
|
+
the same shape `@policy(policies: [["ADMIN"]])` uses. `[[A, B], [C]]` reads
|
|
62
|
+
"(A and B) or C", and evaluation is short-circuit in both directions, so the
|
|
63
|
+
order written is the order Keto is billed for.
|
|
64
|
+
|
|
65
|
+
`id` defaults to `args.id` and may be any `args.<path>` or `source.<path>`. A
|
|
66
|
+
value that turns out to be a **list** requires the permit on every element —
|
|
67
|
+
that is what `deleteNotes(ids: [ID!]!)` means.
|
|
68
|
+
|
|
69
|
+
**The directive is repeatable, and that is how 404 and 403 stay distinct.**
|
|
70
|
+
Checks run in declaration order with their own `onDeny`: a stranger fails the
|
|
71
|
+
`view` check and gets `NOT_FOUND`, so an id cannot be probed; a viewer passes
|
|
72
|
+
it, fails `edit`, and gets `FORBIDDEN`, which is honest because they already
|
|
73
|
+
know the object exists.
|
|
74
|
+
|
|
75
|
+
**Word the refusal like the layer beneath it.** `message:` sets the i18n key a
|
|
76
|
+
denial carries; without it the shared `errors.not-found` /
|
|
77
|
+
`errors.insufficient-permissions` are used. It matters because these fields are
|
|
78
|
+
guarded twice — by the directive, and by the `require<M>Access` their service
|
|
79
|
+
calls — and if the two word one 404 differently, the wording alone tells the
|
|
80
|
+
caller which refused: a generic message means "you may not", a domain one means
|
|
81
|
+
"it is gone". That is the distinction `NOT_FOUND` exists to hide.
|
|
82
|
+
|
|
83
|
+
```graphql
|
|
84
|
+
note(id: ID!): Note!
|
|
85
|
+
@check(
|
|
86
|
+
permissions: [[{ namespace: "Note", permit: "view" }]]
|
|
87
|
+
message: "notes.errors.not-found"
|
|
88
|
+
)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### What it does not cover, on purpose
|
|
92
|
+
|
|
93
|
+
A field that answers a **list** the caller is entitled to. "Which notes may I
|
|
94
|
+
see" is not a check — it is a Keto query (`heldBy(subject)`) folded into the
|
|
95
|
+
database filter before the read. A directive there would have to fetch
|
|
96
|
+
everything and filter after, which makes `totalCount` and the cursors lie.
|
|
97
|
+
Those fields keep their access layer.
|
|
98
|
+
|
|
99
|
+
That access layer stays anyway, and costs nothing: `useKetoChecks` puts a
|
|
100
|
+
per-request loader on the context that **batches** distinct questions into one
|
|
101
|
+
`POST /relation-tuples/batch/check` and **memoises** identical ones. A field
|
|
102
|
+
guarded by `@check(view)` and a service that then asks the same question pay
|
|
103
|
+
for one round trip between them.
|
|
104
|
+
|
|
105
|
+
Two mistakes are refused when the schema is built, not when a request arrives:
|
|
106
|
+
an `id` naming neither root, and `permissions: [[]]` — a conjunction over no
|
|
107
|
+
terms is vacuously true, so it would admit everyone while looking guarded.
|
|
108
|
+
|
|
109
|
+
A Keto outage is never a denial: `OryUnavailable` travels up to
|
|
110
|
+
`createMaskError`, which answers 503.
|
|
111
|
+
|
|
36
112
|
## The context is a `TokenPrincipal`
|
|
37
113
|
|
|
38
114
|
`GraphQLBaseContext.user` is `TokenPrincipal` — the caller as the access token
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getDirective } from '@graphql-tools/utils';
|
|
2
|
+
import type { GraphQLSchema } from 'graphql';
|
|
3
|
+
import { type PermissionRequirement, type PermissionTerm } from 'stx-sdk/ory';
|
|
4
|
+
/**
|
|
5
|
+
* `@check` — the Ory-native counterpart to `@policy`.
|
|
6
|
+
*
|
|
7
|
+
* The declaration itself is SDL, in `graphql/directives/check.graphqls`, so it
|
|
8
|
+
* reaches every consumer of `SHARED_SCHEMA_PATH`. This module only reads it.
|
|
9
|
+
* Keeping the two in one place would mean two copies of the same grammar, and
|
|
10
|
+
* the copy nobody edits is the one that goes wrong.
|
|
11
|
+
*/
|
|
12
|
+
export declare const CHECK_DIRECTIVE_NAME = "check";
|
|
13
|
+
export type CheckDenial = 'NOT_FOUND' | 'FORBIDDEN';
|
|
14
|
+
export type CheckArgs = {
|
|
15
|
+
permissions: PermissionRequirement;
|
|
16
|
+
onDeny: CheckDenial;
|
|
17
|
+
/** i18n key; the shared `errors.*` one when the field does not say. */
|
|
18
|
+
message?: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Every `@check` on a field, in declaration order.
|
|
22
|
+
*
|
|
23
|
+
* `@check` is repeatable, so this is a list and the order is load-bearing:
|
|
24
|
+
* `view` then `edit` is what turns a denial into 404 for a stranger and 403
|
|
25
|
+
* for a viewer. `getDirective` reads the arguments against the schema's own
|
|
26
|
+
* definition, which is what applies the `id` and `onDeny` defaults — the AST
|
|
27
|
+
* node carries only what was written.
|
|
28
|
+
*/
|
|
29
|
+
export declare function readChecks(schema: GraphQLSchema, node: Parameters<typeof getDirective>[1], where: string): CheckArgs[];
|
|
30
|
+
/**
|
|
31
|
+
* Validated here, when the schema is transformed, and not when a request
|
|
32
|
+
* arrives: a path naming neither root is a wiring mistake, and it should stop
|
|
33
|
+
* the server from booting rather than 500 on the one query nobody tried.
|
|
34
|
+
*/
|
|
35
|
+
export declare function assertReadablePath(term: PermissionTerm, where: string): void;
|
|
36
|
+
/** Reads `args.x` / `source.x.y` off a resolver's inputs. */
|
|
37
|
+
export declare function readPath(path: string, source: unknown, args: Record<string, unknown>): unknown;
|
|
38
|
+
/** The ids one term has to clear: one value, or every element of a list. */
|
|
39
|
+
export declare function objectIds(value: unknown): string[];
|
|
40
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/directives/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAEN,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,MAAM,aAAa,CAAC;AAErB;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAEpD,MAAM,MAAM,SAAS,GAAG;IACvB,WAAW,EAAE,qBAAqB,CAAC;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACzB,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,EACxC,KAAK,EAAE,MAAM,GACX,SAAS,EAAE,CAeb;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,QAMrE;AAED,6DAA6D;AAC7D,wBAAgB,QAAQ,CACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,OAAO,CAOT;AAED,4EAA4E;AAC5E,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAKlD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/directives/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/directives/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,47 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import
|
|
2
|
+
import DataLoader3 from "dataloader";
|
|
3
3
|
|
|
4
4
|
export * from "graphql-subscriptions";
|
|
5
5
|
|
|
6
|
+
// src/directives/check.ts
|
|
7
|
+
import { getDirective } from "@graphql-tools/utils";
|
|
8
|
+
import {
|
|
9
|
+
assertRequirement
|
|
10
|
+
} from "stx-sdk/ory";
|
|
11
|
+
var CHECK_DIRECTIVE_NAME = "check";
|
|
12
|
+
function readChecks(schema, node, where) {
|
|
13
|
+
const found = getDirective(schema, node, CHECK_DIRECTIVE_NAME) ?? [];
|
|
14
|
+
return found.map((raw) => {
|
|
15
|
+
const permissions = raw.permissions ?? [];
|
|
16
|
+
assertRequirement(permissions, `@check on ${where}`);
|
|
17
|
+
for (const group of permissions) {
|
|
18
|
+
for (const term of group)
|
|
19
|
+
assertReadablePath(term, where);
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
permissions,
|
|
23
|
+
onDeny: raw.onDeny ?? "NOT_FOUND",
|
|
24
|
+
message: raw.message
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function assertReadablePath(term, where) {
|
|
29
|
+
if (!/^(args|source)(\.[A-Za-z0-9_]+)+$/.test(term.id)) {
|
|
30
|
+
throw new Error(`@check on ${where}: \`id\` must be "args.<path>" or "source.<path>", got ${JSON.stringify(term.id)}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function readPath(path, source, args) {
|
|
34
|
+
const [root, ...rest] = path.split(".");
|
|
35
|
+
let value = root === "args" ? args : source;
|
|
36
|
+
for (const key of rest) {
|
|
37
|
+
value = value?.[key];
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
function objectIds(value) {
|
|
42
|
+
const values = Array.isArray(value) ? value : [value];
|
|
43
|
+
return values.filter((item) => typeof item === "string" && item.length > 0);
|
|
44
|
+
}
|
|
6
45
|
// src/directives/federation.ts
|
|
7
46
|
var FEDERATION_DIRECTIVES = `
|
|
8
47
|
directive @external on FIELD_DEFINITION | OBJECT
|
|
@@ -488,6 +527,81 @@ var extractJwtPlugin = {
|
|
|
488
527
|
};
|
|
489
528
|
}
|
|
490
529
|
};
|
|
530
|
+
// src/plugins/keto-checks.ts
|
|
531
|
+
import { MapperKind, mapSchema } from "@graphql-tools/utils";
|
|
532
|
+
import { CustomException as CustomException2 } from "@nxgt/shared-exceptions";
|
|
533
|
+
import DataLoader2 from "dataloader";
|
|
534
|
+
import { defaultFieldResolver } from "graphql";
|
|
535
|
+
import {
|
|
536
|
+
evaluateRequirement,
|
|
537
|
+
tuple
|
|
538
|
+
} from "stx-sdk/ory";
|
|
539
|
+
function createKetoChecks(ory) {
|
|
540
|
+
const loader = new DataLoader2((questions) => ory.checkMany([...questions]), {
|
|
541
|
+
cacheKeyFn: ({ permission, subject }) => tuple(permission, subject)
|
|
542
|
+
});
|
|
543
|
+
return (permission, subject) => loader.load({ permission, subject });
|
|
544
|
+
}
|
|
545
|
+
function applyKetoChecks(schema) {
|
|
546
|
+
return mapSchema(schema, {
|
|
547
|
+
[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => {
|
|
548
|
+
const where = `${typeName}.${fieldName}`;
|
|
549
|
+
const checks = readChecks(schema, fieldConfig, where);
|
|
550
|
+
if (checks.length === 0)
|
|
551
|
+
return fieldConfig;
|
|
552
|
+
const resolve = fieldConfig.resolve ?? defaultFieldResolver;
|
|
553
|
+
return {
|
|
554
|
+
...fieldConfig,
|
|
555
|
+
resolve: async (source, args, context, info) => {
|
|
556
|
+
const ctx = context;
|
|
557
|
+
const subject = ctx.ory?.subject;
|
|
558
|
+
if (!subject) {
|
|
559
|
+
throw CustomException2.unauthenticated({
|
|
560
|
+
message: "errors.unauthenticated"
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
const check = ctx.ketoChecks;
|
|
564
|
+
if (!check) {
|
|
565
|
+
throw new Error(`@check on ${where}: no checker on the context — useKetoChecks(ory) is not registered`);
|
|
566
|
+
}
|
|
567
|
+
for (const { permissions, onDeny, message } of checks) {
|
|
568
|
+
const allowed = await evaluateRequirement(permissions, (term) => objectsOf(term, source, args, where), check, subject);
|
|
569
|
+
if (!allowed)
|
|
570
|
+
throw denial(onDeny, message);
|
|
571
|
+
}
|
|
572
|
+
return resolve(source, args, context, info);
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
function objectsOf(term, source, args, where) {
|
|
579
|
+
const ids = objectIds(readPath(term.id, source, args));
|
|
580
|
+
if (ids.length === 0) {
|
|
581
|
+
throw new Error(`@check on ${where}: "${term.id}" resolved no object id`);
|
|
582
|
+
}
|
|
583
|
+
return ids;
|
|
584
|
+
}
|
|
585
|
+
function denial(onDeny, message) {
|
|
586
|
+
return onDeny === "FORBIDDEN" ? CustomException2.forbidden({
|
|
587
|
+
message: message ?? "errors.insufficient-permissions"
|
|
588
|
+
}) : CustomException2.notFound({ message: message ?? "errors.not-found" });
|
|
589
|
+
}
|
|
590
|
+
function useKetoChecks(ory) {
|
|
591
|
+
const transformed = new WeakSet;
|
|
592
|
+
return {
|
|
593
|
+
onSchemaChange: ({ schema, replaceSchema }) => {
|
|
594
|
+
if (transformed.has(schema))
|
|
595
|
+
return;
|
|
596
|
+
const next = applyKetoChecks(schema);
|
|
597
|
+
transformed.add(next);
|
|
598
|
+
replaceSchema(next);
|
|
599
|
+
},
|
|
600
|
+
onContextBuilding: ({ extendContext }) => {
|
|
601
|
+
extendContext({ ketoChecks: createKetoChecks(ory) });
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
}
|
|
491
605
|
// src/plugins/ory-auth.ts
|
|
492
606
|
import { GraphQLError as GraphQLError2 } from "graphql";
|
|
493
607
|
import {
|
|
@@ -631,7 +745,7 @@ import {
|
|
|
631
745
|
} from "graphql-scalars";
|
|
632
746
|
|
|
633
747
|
// src/scalars/custom/utils.ts
|
|
634
|
-
import { CustomException as
|
|
748
|
+
import { CustomException as CustomException3 } from "@nxgt/shared-exceptions";
|
|
635
749
|
import { logger as logger2 } from "@nxgt/shared-logging";
|
|
636
750
|
import { GraphQLScalarType as GraphQLScalarType2 } from "graphql";
|
|
637
751
|
function createScalarFrom(scalar, {
|
|
@@ -639,7 +753,7 @@ function createScalarFrom(scalar, {
|
|
|
639
753
|
description,
|
|
640
754
|
errorMessage
|
|
641
755
|
}) {
|
|
642
|
-
const exception =
|
|
756
|
+
const exception = CustomException3.badRequest({
|
|
643
757
|
message: errorMessage
|
|
644
758
|
});
|
|
645
759
|
return new GraphQLScalarType2({
|
|
@@ -878,12 +992,15 @@ directive @link(url: String!, import: [String!]) on SCHEMA
|
|
|
878
992
|
// src/upload.ts
|
|
879
993
|
import graphqlUploadExpress from "graphql-upload/graphqlUploadExpress.mjs";
|
|
880
994
|
export {
|
|
881
|
-
|
|
995
|
+
CHECK_DIRECTIVE_NAME,
|
|
996
|
+
DataLoader3 as DataLoader,
|
|
882
997
|
FEDERATION_DIRECTIVES,
|
|
883
998
|
SCALARS_MAPPING,
|
|
884
999
|
SCALAR_RESOLVERS,
|
|
885
1000
|
SHARED_SCHEMA_PATH,
|
|
886
1001
|
SHARED_TYPE_DEFS,
|
|
1002
|
+
applyKetoChecks,
|
|
1003
|
+
assertReadablePath,
|
|
887
1004
|
buildSubgraphSchema,
|
|
888
1005
|
createChangeResolvers,
|
|
889
1006
|
createChildrenConnectionDataLoader,
|
|
@@ -893,6 +1010,7 @@ export {
|
|
|
893
1010
|
createEntitiesReferenceLoader,
|
|
894
1011
|
createFormatError,
|
|
895
1012
|
createGraphQLError,
|
|
1013
|
+
createKetoChecks,
|
|
896
1014
|
createMaskError,
|
|
897
1015
|
createSimpleListDataLoader,
|
|
898
1016
|
createSingleChildDataLoader,
|
|
@@ -903,7 +1021,10 @@ export {
|
|
|
903
1021
|
graphqlUploadExpress,
|
|
904
1022
|
honoYoga,
|
|
905
1023
|
loadTypeDefs,
|
|
1024
|
+
objectIds,
|
|
906
1025
|
oryUnavailableError,
|
|
1026
|
+
readChecks,
|
|
1027
|
+
readPath,
|
|
907
1028
|
renderSandbox,
|
|
908
1029
|
resolveOryPrincipal,
|
|
909
1030
|
resolveWsUser,
|
|
@@ -911,8 +1032,9 @@ export {
|
|
|
911
1032
|
setupYogaWebSocketServer,
|
|
912
1033
|
toPrincipal,
|
|
913
1034
|
useAuth,
|
|
1035
|
+
useKetoChecks,
|
|
914
1036
|
useOryAuth
|
|
915
1037
|
};
|
|
916
1038
|
|
|
917
|
-
//# debugId=
|
|
1039
|
+
//# debugId=B268AC8FCE1D143C64756E2164756E21
|
|
918
1040
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/directives/federation.ts", "../src/integrations/hono.ts", "../src/utils/change-resolvers.utils.ts", "../src/utils/codegen.utils.ts", "../src/utils/data-loader.utils.ts", "../src/utils/errors.utils.ts", "../src/utils/publish.ts", "../src/utils/sandbox.ts", "../src/utils/schema.utils.ts", "../src/utils/websocket.ts", "../src/utils/ws-context.ts", "../src/plugins/auth.ts", "../src/plugins/extract-jwt.ts", "../src/plugins/ory-auth.ts", "../src/scalars/any/any.scalars.ts", "../src/scalars/custom/custom.scalars.ts", "../src/scalars/custom/utils.ts", "../src/scalars/upload/upload.scalar.ts", "../src/scalars/index.ts", "../src/shared.ts", "../src/upload.ts"],
|
|
3
|
+
"sources": ["../src/index.ts", "../src/directives/check.ts", "../src/directives/federation.ts", "../src/integrations/hono.ts", "../src/utils/change-resolvers.utils.ts", "../src/utils/codegen.utils.ts", "../src/utils/data-loader.utils.ts", "../src/utils/errors.utils.ts", "../src/utils/publish.ts", "../src/utils/sandbox.ts", "../src/utils/schema.utils.ts", "../src/utils/websocket.ts", "../src/utils/ws-context.ts", "../src/plugins/auth.ts", "../src/plugins/extract-jwt.ts", "../src/plugins/keto-checks.ts", "../src/plugins/ory-auth.ts", "../src/scalars/any/any.scalars.ts", "../src/scalars/custom/custom.scalars.ts", "../src/scalars/custom/utils.ts", "../src/scalars/upload/upload.scalar.ts", "../src/scalars/index.ts", "../src/shared.ts", "../src/upload.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import DataLoader from 'dataloader';\n\nexport * from 'graphql-subscriptions';\nexport * from './directives';\nexport * from './integrations';\nexport * from './plugins';\nexport * from './scalars';\nexport * from './shared';\nexport * from './types';\nexport * from './upload';\nexport * from './utils';\n\nexport { DataLoader };\n",
|
|
6
|
+
"import { getDirective } from '@graphql-tools/utils';\nimport type { GraphQLSchema } from 'graphql';\nimport {\n\tassertRequirement,\n\ttype PermissionRequirement,\n\ttype PermissionTerm,\n} from 'stx-sdk/ory';\n\n/**\n * `@check` — the Ory-native counterpart to `@policy`.\n *\n * The declaration itself is SDL, in `graphql/directives/check.graphqls`, so it\n * reaches every consumer of `SHARED_SCHEMA_PATH`. This module only reads it.\n * Keeping the two in one place would mean two copies of the same grammar, and\n * the copy nobody edits is the one that goes wrong.\n */\nexport const CHECK_DIRECTIVE_NAME = 'check';\n\nexport type CheckDenial = 'NOT_FOUND' | 'FORBIDDEN';\n\nexport type CheckArgs = {\n\tpermissions: PermissionRequirement;\n\tonDeny: CheckDenial;\n\t/** i18n key; the shared `errors.*` one when the field does not say. */\n\tmessage?: string;\n};\n\n/**\n * Every `@check` on a field, in declaration order.\n *\n * `@check` is repeatable, so this is a list and the order is load-bearing:\n * `view` then `edit` is what turns a denial into 404 for a stranger and 403\n * for a viewer. `getDirective` reads the arguments against the schema's own\n * definition, which is what applies the `id` and `onDeny` defaults — the AST\n * node carries only what was written.\n */\nexport function readChecks(\n\tschema: GraphQLSchema,\n\tnode: Parameters<typeof getDirective>[1],\n\twhere: string,\n): CheckArgs[] {\n\tconst found = getDirective(schema, node, CHECK_DIRECTIVE_NAME) ?? [];\n\n\treturn found.map((raw) => {\n\t\tconst permissions = (raw.permissions ?? []) as PermissionRequirement;\n\t\tassertRequirement(permissions, `@check on ${where}`);\n\t\tfor (const group of permissions) {\n\t\t\tfor (const term of group) assertReadablePath(term, where);\n\t\t}\n\t\treturn {\n\t\t\tpermissions,\n\t\t\tonDeny: (raw.onDeny ?? 'NOT_FOUND') as CheckDenial,\n\t\t\tmessage: raw.message as string | undefined,\n\t\t};\n\t});\n}\n\n/**\n * Validated here, when the schema is transformed, and not when a request\n * arrives: a path naming neither root is a wiring mistake, and it should stop\n * the server from booting rather than 500 on the one query nobody tried.\n */\nexport function assertReadablePath(term: PermissionTerm, where: string) {\n\tif (!/^(args|source)(\\.[A-Za-z0-9_]+)+$/.test(term.id)) {\n\t\tthrow new Error(\n\t\t\t`@check on ${where}: \\`id\\` must be \"args.<path>\" or \"source.<path>\", got ${JSON.stringify(term.id)}`,\n\t\t);\n\t}\n}\n\n/** Reads `args.x` / `source.x.y` off a resolver's inputs. */\nexport function readPath(\n\tpath: string,\n\tsource: unknown,\n\targs: Record<string, unknown>,\n): unknown {\n\tconst [root, ...rest] = path.split('.');\n\tlet value: unknown = root === 'args' ? args : source;\n\tfor (const key of rest) {\n\t\tvalue = (value as Record<string, unknown> | null | undefined)?.[key];\n\t}\n\treturn value;\n}\n\n/** The ids one term has to clear: one value, or every element of a list. */\nexport function objectIds(value: unknown): string[] {\n\tconst values = Array.isArray(value) ? value : [value];\n\treturn values.filter(\n\t\t(item): item is string => typeof item === 'string' && item.length > 0,\n\t);\n}\n",
|
|
6
7
|
"export const FEDERATION_DIRECTIVES = `\ndirective @external on FIELD_DEFINITION | OBJECT\ndirective @requires(fields: FieldSet!) on FIELD_DEFINITION\ndirective @provides(fields: FieldSet!) on FIELD_DEFINITION\ndirective @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE\ndirective @shareable repeatable on OBJECT | FIELD_DEFINITION\ndirective @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION\ndirective @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION\ndirective @override(from: String!) on FIELD_DEFINITION\ndirective @composeDirective(name: String!) repeatable on SCHEMA\ndirective @interfaceObject on OBJECT\ndirective @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM\n`;\n",
|
|
7
8
|
"import type { YogaInitialContext, YogaServerInstance } from 'graphql-yoga';\nimport { Hono } from 'hono';\nimport { contextStorage } from 'hono/context-storage';\nimport { createMiddleware } from 'hono/factory';\nimport { languageDetector } from 'hono/language';\nimport { type RenderSandboxOptions, renderSandbox } from '../utils';\n\nexport function sandboxExpolorer(options: RenderSandboxOptions) {\n\treturn createMiddleware(async (ctx) => {\n\t\treturn ctx.html(renderSandbox(options));\n\t});\n}\n\ntype HonoYogaOptions = {\n\tsandbox?: RenderSandboxOptions & { endpoint?: string };\n};\n\nexport function honoYoga<\n\tServerContext extends Partial<YogaInitialContext>,\n\tUserContext extends {},\n>(yoga: YogaServerInstance<ServerContext, UserContext>) {\n\treturn createMiddleware(async (ctx) => {\n\t\tconst response = await yoga.fetch(ctx.req.raw);\n\n\t\treturn response;\n\t});\n}\n\nexport function createYogaHono<\n\tServerContext extends Partial<YogaInitialContext>,\n\tUserContext extends {},\n>(\n\tyoga: YogaServerInstance<ServerContext, UserContext>,\n\toptions?: HonoYogaOptions,\n) {\n\tconst app = new Hono();\n\n\tapp.use(contextStorage());\n\tapp.use(\n\t\tlanguageDetector({\n\t\t\torder: ['header'],\n\t\t\tsupportedLanguages: ['en', 'fr'],\n\t\t\tfallbackLanguage: 'en',\n\t\t\tcaches: [],\n\t\t}),\n\t);\n\n\tapp.get('/health', (ctx) => {\n\t\treturn ctx.json({ status: 'ok' }, 200);\n\t});\n\n\tapp.get(\n\t\toptions?.sandbox?.endpoint || 'sandbox',\n\t\tsandboxExpolorer(options?.sandbox || {}),\n\t);\n\n\tapp.use(yoga.graphqlEndpoint, honoYoga(yoga));\n\n\treturn app;\n}\n",
|
|
8
9
|
"import {\n\tAUDIT_EVENT,\n\ttype Audit,\n\ttype AuditService,\n\tCommitType,\n} from '@nxgt/shared-mongo';\nimport { withFilter } from 'graphql-subscriptions';\n\n/**\n * Minimal structural shape of the app's pubsub instance. Kept structural so\n * this factory does not couple to a specific `graphql-yoga` `PubSub<...>`\n * instantiation.\n */\nexport type ChangeResolversPubSub = {\n\tsubscribe: (event: string) => any;\n};\n\n/**\n * Minimal structural shape of the context every subgraph builds: an\n * `AuditService` under `services.audit`, plus the module's own CRUD service\n * exposing `findById`.\n */\nexport type ChangeResolversContext = {\n\tservices: {\n\t\taudit: AuditService;\n\t\t[key: string]: any;\n\t};\n};\n\nexport type CreateChangeResolversConfig = {\n\t/**\n\t * Singular camelCase entity name used to build the resolver field names:\n\t * `bed` -> `bedChanges`, `bedChangesById`, `bedChanged`.\n\t */\n\tentity: string;\n\t/**\n\t * Mongo collection name, i.e. `BedModel.collection.collectionName`.\n\t */\n\tcollection: string;\n\t/**\n\t * Key of the module's CRUD service on `context.services`, i.e. `beds`.\n\t */\n\tservice: string;\n\t/**\n\t * The app's pubsub instance, or a getter returning it. Prefer the getter\n\t * form (`() => pubsub`) when the app can re-create its pubsub at runtime,\n\t * so the subscription always resolves against the current instance.\n\t */\n\tpubsub: ChangeResolversPubSub | (() => ChangeResolversPubSub);\n};\n\nexport type ChangeResolvers = {\n\tQuery: Record<string, any>;\n\tSubscription: Record<string, any>;\n};\n\n/**\n * Builds the audit change-stream resolver block that is otherwise repeated\n * verbatim in every module's `*.resolver.ts`: the two paginated `Changes`\n * queries and the `Changed` subscription.\n *\n * ```ts\n * const changes = createChangeResolvers({\n * entity: 'bed',\n * collection: BedModel.collection.collectionName,\n * service: 'beds',\n * pubsub: () => pubsub,\n * });\n *\n * export const beds: Resolvers = {\n * Query: { bed: ..., beds: ..., ...changes.Query },\n * Subscription: { ...changes.Subscription },\n * };\n * ```\n */\nexport function createChangeResolvers(\n\tconfig: CreateChangeResolversConfig,\n): ChangeResolvers {\n\tconst { entity, collection, service, pubsub } = config;\n\n\tconst resolvePubSub = () =>\n\t\ttypeof pubsub === 'function' ? pubsub() : pubsub;\n\n\treturn {\n\t\tQuery: {\n\t\t\t[`${entity}Changes`]: async (\n\t\t\t\t_parent: unknown,\n\t\t\t\targs: any,\n\t\t\t\tcontext: ChangeResolversContext,\n\t\t\t) =>\n\t\t\t\tcontext.services.audit.findChangesPaginatedByCollection(\n\t\t\t\t\tcollection,\n\t\t\t\t\targs,\n\t\t\t\t),\n\t\t\t[`${entity}ChangesById`]: async (\n\t\t\t\t_parent: unknown,\n\t\t\t\targs: any,\n\t\t\t\tcontext: ChangeResolversContext,\n\t\t\t) =>\n\t\t\t\tcontext.services.audit.findChangesPaginatedByCollectionAndOid(\n\t\t\t\t\targs.id,\n\t\t\t\t\tcollection,\n\t\t\t\t\targs,\n\t\t\t\t),\n\t\t},\n\t\tSubscription: {\n\t\t\t[`${entity}Changed`]: {\n\t\t\t\tresolve: async (\n\t\t\t\t\tpayload: Audit,\n\t\t\t\t\t_args: any,\n\t\t\t\t\tcontext: ChangeResolversContext,\n\t\t\t\t) => ({\n\t\t\t\t\tid: context.services.audit.extractId(payload),\n\t\t\t\t\tdata:\n\t\t\t\t\t\tpayload.type !== CommitType.TERMINAL\n\t\t\t\t\t\t\t? await context.services[service].findById(payload.state._id)\n\t\t\t\t\t\t\t: null,\n\t\t\t\t\ttype: payload.type,\n\t\t\t\t}),\n\t\t\t\tsubscribe: withFilter(\n\t\t\t\t\t() => resolvePubSub().subscribe(AUDIT_EVENT),\n\t\t\t\t\t(payload: any, _variables: any, context?: ChangeResolversContext) =>\n\t\t\t\t\t\tcontext\n\t\t\t\t\t\t\t? context.services.audit.matches(payload, { collection })\n\t\t\t\t\t\t\t: false,\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t};\n}\n",
|
|
@@ -16,6 +17,7 @@
|
|
|
16
17
|
"import type { TokenPrincipal } from '@nxgt/shared';\nimport type { Context } from 'graphql-ws';\nimport type { createAuthClient } from 'stx-sdk/auth';\n\ntype AuthClient = ReturnType<typeof createAuthClient>;\n\nexport interface ResolvedWsUser {\n\tuser: TokenPrincipal | undefined;\n\ttoken: string | undefined;\n}\n\n/**\n * Resolves the authenticated TokenPrincipal for a `graphql-ws` connection - the\n * WS-transport equivalent of the HTTP-path `useAuth()`/`useGenericAuth()`\n * plugins. There is no gateway hop for WS connections, so each app performs\n * the OAuth introspection call itself using its own `auth` client.\n *\n * Reads the bearer token off `connectionParams.authorization` /\n * `connectionParams.Authorization` (both casings are used by existing\n * clients), strips the `Bearer ` prefix, and introspects it. Returns\n * `user: undefined` for a missing, invalid, or inactive token - callers\n * pass `user ?? null` into their own `services()` factory, exactly as the\n * HTTP-path plugins already do.\n */\nexport async function resolveWsUser(\n\tconnectionParams: Context['connectionParams'],\n\tauthClient: AuthClient,\n): Promise<ResolvedWsUser> {\n\tconst rawToken =\n\t\t(connectionParams?.authorization as string | undefined) ??\n\t\t(connectionParams?.Authorization as string | undefined);\n\tconst token = rawToken?.replace('Bearer ', '');\n\n\tconst { data } = token\n\t\t? await authClient.POST('/oauth/introspect', { body: { token } })\n\t\t: { data: null };\n\n\tconst user = data?.active\n\t\t? ({ ...(data as any), name: (data as any).sub } as TokenPrincipal)\n\t\t: undefined;\n\n\treturn { user, token };\n}\n",
|
|
17
18
|
"import type { Plugin } from 'graphql-yoga';\nimport type { GraphQLBaseContext } from '../types';\n\nexport function useAuth(): Plugin<GraphQLBaseContext> {\n\treturn {\n\t\tonContextBuilding: async ({ context, extendContext }) => {\n\t\t\textendContext({\n\t\t\t\tuser: context.params.extensions?.user,\n\t\t\t\ttoken: context.params.extensions?.token,\n\t\t\t});\n\t\t},\n\t};\n}\n",
|
|
18
19
|
"import type { ApolloServerPlugin } from '@apollo/server';\nimport type { TokenPrincipal } from '@nxgt/shared';\nimport { logger } from '@nxgt/shared-logging';\n\nexport const extractJwtPlugin = {\n\tasync requestDidStart({ request, contextValue }) {\n\t\tlogger.info(\n\t\t\t`[${request.extensions?.subgraphName}] Extracting JWT from request extensions: ${request.extensions?.payload?.sub}`,\n\t\t\trequest.extensions,\n\t\t);\n\t\tcontextValue.jwt = {\n\t\t\tpayload: request.extensions?.payload,\n\t\t};\n\t},\n} satisfies ApolloServerPlugin<{\n\tjwt?: { payload: TokenPrincipal };\n}>;\n",
|
|
20
|
+
"import { MapperKind, mapSchema } from '@graphql-tools/utils';\nimport { CustomException } from '@nxgt/shared-exceptions';\nimport DataLoader from 'dataloader';\nimport { defaultFieldResolver, type GraphQLSchema } from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\nimport {\n\tevaluateRequirement,\n\ttype Ory,\n\ttype Permission,\n\ttype PermissionTerm,\n\ttype Subject,\n\ttuple,\n} from 'stx-sdk/ory';\nimport {\n\ttype CheckArgs,\n\tobjectIds,\n\treadChecks,\n\treadPath,\n} from '../directives/check';\nimport type { GraphQLBaseContext } from '../types';\nimport type { OryContext } from './ory-auth';\n\n/**\n * The per-request answer cache, and the reason `@check` costs nothing on top\n * of the access layer that already asks Keto.\n *\n * `DataLoader` here does two things: it **batches** distinct questions into\n * one `POST /relation-tuples/batch/check`, and it **memoises** identical ones\n * for the life of the request. So a field guarded by `@check(view)` and a\n * service that then calls `require<M>Access` — which asks the same question —\n * pay for one round trip between them.\n *\n * The key is Keto's own notation, `Note:n1#view@idn-7`, so a cache hit is\n * legible in a log line.\n */\nexport type KetoChecker = (\n\tpermission: Permission,\n\tsubject: Subject,\n) => Promise<boolean>;\n\nexport type KetoChecksContext = {\n\tketoChecks?: KetoChecker;\n};\n\nexport function createKetoChecks(ory: Ory): KetoChecker {\n\tconst loader = new DataLoader<\n\t\t{ permission: Permission; subject: Subject },\n\t\tboolean,\n\t\tstring\n\t>((questions) => ory.checkMany([...questions]), {\n\t\tcacheKeyFn: ({ permission, subject }) => tuple(permission, subject),\n\t});\n\n\treturn (permission, subject) => loader.load({ permission, subject });\n}\n\n/**\n * Wraps every field carrying `@check` so the permission is answered before its\n * resolver runs.\n *\n * Modelled on `applyGraphqlPolicy` in `@nxgt/security` — same `mapSchema` over\n * `MapperKind.OBJECT_FIELD`, same `fieldConfig.resolve ?? defaultFieldResolver`.\n * Exported on its own because a schema transform is far easier to test than a\n * plugin, and `useKetoChecks` is a three-line wrapper over it.\n */\nexport function applyKetoChecks(schema: GraphQLSchema): GraphQLSchema {\n\treturn mapSchema(schema, {\n\t\t[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => {\n\t\t\tconst where = `${typeName}.${fieldName}`;\n\t\t\tconst checks = readChecks(schema, fieldConfig, where);\n\t\t\tif (checks.length === 0) return fieldConfig;\n\n\t\t\tconst resolve = fieldConfig.resolve ?? defaultFieldResolver;\n\n\t\t\treturn {\n\t\t\t\t...fieldConfig,\n\t\t\t\tresolve: async (source, args, context, info) => {\n\t\t\t\t\tconst ctx = context as KetoChecksContext & OryContext;\n\t\t\t\t\tconst subject = ctx.ory?.subject;\n\t\t\t\t\tif (!subject) {\n\t\t\t\t\t\tthrow CustomException.unauthenticated({\n\t\t\t\t\t\t\tmessage: 'errors.unauthenticated',\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst check = ctx.ketoChecks;\n\t\t\t\t\tif (!check) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`@check on ${where}: no checker on the context — useKetoChecks(ory) is not registered`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// In declaration order, each with its own denial: `view` first\n\t\t\t\t\t// answers 404 for a stranger, `edit` next answers 403 for a viewer.\n\t\t\t\t\tfor (const { permissions, onDeny, message } of checks) {\n\t\t\t\t\t\tconst allowed = await evaluateRequirement(\n\t\t\t\t\t\t\tpermissions,\n\t\t\t\t\t\t\t(term) => objectsOf(term, source, args, where),\n\t\t\t\t\t\t\tcheck,\n\t\t\t\t\t\t\tsubject,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (!allowed) throw denial(onDeny, message);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn resolve(source, args, context, info);\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t});\n}\n\n/**\n * A term that resolves no object is a wiring mistake — a nullable argument\n * nobody passed, a `source` field that is not selected — and it must not read\n * as \"allowed\". `evaluateRequirement` throws on an empty list; this only makes\n * the message name the field.\n */\nfunction objectsOf(\n\tterm: PermissionTerm,\n\tsource: unknown,\n\targs: Record<string, unknown>,\n\twhere: string,\n): string[] {\n\tconst ids = objectIds(readPath(term.id, source, args));\n\tif (ids.length === 0) {\n\t\tthrow new Error(`@check on ${where}: \"${term.id}\" resolved no object id`);\n\t}\n\treturn ids;\n}\n\n/**\n * `message` is the field's own i18n key when it gave one. It exists so the\n * directive and the service layer can answer a refusal with the SAME words:\n * two different messages behind one 404 tell the caller which layer spoke, and\n * that is the difference NOT_FOUND is there to hide.\n */\nfunction denial(onDeny: CheckArgs['onDeny'], message?: string) {\n\treturn onDeny === 'FORBIDDEN'\n\t\t? CustomException.forbidden({\n\t\t\t\tmessage: message ?? 'errors.insufficient-permissions',\n\t\t\t})\n\t\t: CustomException.notFound({ message: message ?? 'errors.not-found' });\n}\n\n/**\n * Registers the whole thing: the schema transform, and the per-request checker\n * the transform — and the app's own access layer — read off the context.\n *\n * Goes after `useOryAuth(ory)`, which is what puts `ory.subject` there.\n *\n * `replaceSchema` inside `onSchemaChange` re-enters this hook with the new\n * schema, so transformed schemas are remembered and passed through. Without\n * the guard this loops until the stack gives out.\n *\n * `OryUnavailable` is deliberately not caught anywhere here: a Keto outage is\n * a 503 through `createMaskError`, never a denial.\n */\nexport function useKetoChecks(\n\tory: Ory,\n): Plugin<GraphQLBaseContext & OryContext & KetoChecksContext> {\n\tconst transformed = new WeakSet<GraphQLSchema>();\n\n\treturn {\n\t\tonSchemaChange: ({ schema, replaceSchema }) => {\n\t\t\tif (transformed.has(schema)) return;\n\t\t\tconst next = applyKetoChecks(schema);\n\t\t\ttransformed.add(next);\n\t\t\treplaceSchema(next);\n\t\t},\n\t\tonContextBuilding: ({ extendContext }) => {\n\t\t\textendContext({ ketoChecks: createKetoChecks(ory) });\n\t\t},\n\t};\n}\n",
|
|
19
21
|
"import type { TokenPrincipal } from '@nxgt/shared';\nimport { GraphQLError } from 'graphql';\nimport type { Plugin } from 'graphql-yoga';\nimport {\n\tbearerOf,\n\ttype Ory,\n\ttype OryPrincipal,\n\tOryUnavailable,\n} from 'stx-sdk/ory';\nimport type { GraphQLBaseContext } from '../types';\n\n/**\n * What `useOryAuth()` adds to the context, next to `user` and `token`: the\n * Ory principal itself, or `null` when the request carried no honoured\n * credential. `user.sub === ory.subject` by construction; read `ory` when the\n * value is going to Keto, so the code says what it is.\n */\nexport type OryContext = {\n\tory?: OryPrincipal | null;\n};\n\n/**\n * The repo-wide TokenPrincipal an Ory principal becomes.\n *\n * `sub` and `uid` are both the Ory subject — a Kratos identity id for a\n * session or a person's token, the client id for a `client_credentials`\n * token — so every service that reads `this.principal?.sub` (or `.uid`) keeps\n * working unchanged. `authorities` is EMPTY on purpose: Keto answers per\n * object, and an empty list is what keeps `@policy` / `useGenericAuth`'s\n * policy extraction from granting anything by accident.\n */\nexport function toPrincipal(ory: OryPrincipal): TokenPrincipal {\n\tconst email = ory.identity?.email;\n\treturn {\n\t\tsub: ory.subject,\n\t\tuid: ory.subject,\n\t\tname: email ?? ory.clientId ?? ory.subject,\n\t\tusername: email,\n\t\tclientId: ory.clientId,\n\t\tscope: ory.scopes.join(' ') || undefined,\n\t\ttokenType: ory.kind,\n\t\texp: ory.expiresAt ? Math.floor(ory.expiresAt.getTime() / 1000) : undefined,\n\t\tauthorities: [],\n\t\troles: [],\n\t};\n}\n\n/**\n * A 503 the client can read as one — a real `GraphQLError` so Yoga's masking\n * leaves it alone, `extensions.http.status` so the transport says 503 too.\n * Never a denial: `stx-sdk/ory` throws `OryUnavailable` only when Kratos,\n * Hydra or Keto could not answer, and that must not read as \"not signed in\".\n */\nexport function oryUnavailableError(error: OryUnavailable): GraphQLError {\n\treturn new GraphQLError(`ory: ${error.service} is unavailable`, {\n\t\textensions: {\n\t\t\tcode: 'SERVICE_UNAVAILABLE',\n\t\t\thttp: { status: 503 },\n\t\t\tdebugMessage: error.message,\n\t\t},\n\t});\n}\n\n/**\n * The one introspection code path — `Bearer` first, then `X-Session-Token`,\n * then the Kratos cookie; the first credential present decides. Exported so\n * a REST route mounted beside the GraphQL endpoint (content-hub-api's\n * webhook shape) authenticates through the same function instead of a\n * second call.\n */\nexport async function resolveOryPrincipal(\n\tory: Ory,\n\theaders: Headers,\n): Promise<OryContext & { user?: TokenPrincipal; token?: string }> {\n\tlet principal: OryPrincipal | null;\n\ttry {\n\t\tprincipal = await ory.resolve(headers);\n\t} catch (error) {\n\t\tif (error instanceof OryUnavailable) throw oryUnavailableError(error);\n\t\tthrow error;\n\t}\n\n\treturn {\n\t\tory: principal,\n\t\tuser: principal ? toPrincipal(principal) : undefined,\n\t\ttoken: bearerOf(headers) ?? undefined,\n\t};\n}\n\n/**\n * `useAuth()` for an Ory-native API: resolves the caller through Kratos\n * (session cookie, session token) or Hydra (Bearer, introspected) and puts\n * `user`, `token` and `ory` on the context. Wire it exactly where the\n * standalone APIs wire `useAuth()`, ahead of `useGenericAuth` — which then\n * enforces `@authenticated` from `context.user` unchanged.\n *\n * The `Ory` instance comes from the app's `createOry()` — one per process —\n * and is the same one the services use for `isAllowed`.\n */\nexport function useOryAuth(ory: Ory): Plugin<GraphQLBaseContext & OryContext> {\n\treturn {\n\t\tonContextBuilding: async ({ context, extendContext }) => {\n\t\t\textendContext(await resolveOryPrincipal(ory, context.request.headers));\n\t\t},\n\t};\n}\n",
|
|
20
22
|
"import { GraphQLScalarType, Kind } from 'graphql';\n\nexport const ANY_SCALAR = {\n\tAny: new GraphQLScalarType<any, any>({\n\t\tname: 'Any',\n\t\tdescription: 'Generic scalar to represent any type',\n\t\tserialize(value) {\n\t\t\treturn value;\n\t\t},\n\t\tparseValue(value: any) {\n\t\t\treturn value;\n\t\t},\n\t\tparseLiteral(ast, variables) {\n\t\t\tswitch (ast.kind) {\n\t\t\t\tcase Kind.STRING:\n\t\t\t\tcase Kind.BOOLEAN:\n\t\t\t\t\treturn ast.value;\n\t\t\t\tcase Kind.INT:\n\t\t\t\tcase Kind.FLOAT:\n\t\t\t\t\treturn parseFloat(ast.value);\n\t\t\t\tcase Kind.OBJECT:\n\t\t\t\t\treturn Object.fromEntries(\n\t\t\t\t\t\tast.fields.map((field) => [field.name, field.value]),\n\t\t\t\t\t);\n\t\t\t\tcase Kind.LIST:\n\t\t\t\t\treturn ast.values.map((n) => this?.parseLiteral?.(n, variables));\n\t\t\t\tcase Kind.NULL:\n\t\t\t\t\treturn null;\n\t\t\t\tcase Kind.VARIABLE: {\n\t\t\t\t\tconst name = ast.name.value;\n\t\t\t\t\treturn variables ? variables[name] : undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}),\n};\n",
|
|
21
23
|
"import type { GraphQLScalarType } from 'graphql';\nimport {\n\tAccountNumberResolver,\n\tBigIntResolver,\n\tCountryCodeResolver,\n\tCountryNameResolver,\n\tCuidResolver,\n\tCurrencyResolver,\n\tDateResolver,\n\tDateTimeISOResolver,\n\tDurationResolver,\n\tEmailAddressResolver,\n\tGeoJSONResolver,\n\tGUIDResolver,\n\tHexadecimalResolver,\n\tHexColorCodeResolver,\n\tHSLAResolver,\n\tHSLResolver,\n\tIBANResolver,\n\tIPResolver,\n\tIPv4Resolver,\n\tIPv6Resolver,\n\tISBNResolver,\n\tJSONObjectResolver,\n\tJSONResolver,\n\tJWTResolver,\n\tLatitudeResolver,\n\tLocaleResolver,\n\tLongitudeResolver,\n\tLongResolver,\n\tMACResolver,\n\tNegativeFloatResolver,\n\tNegativeIntResolver,\n\tNonEmptyStringResolver,\n\tNonNegativeFloatResolver,\n\tNonNegativeIntResolver,\n\tNonPositiveFloatResolver,\n\tNonPositiveIntResolver,\n\tObjectIDResolver,\n\tPhoneNumberResolver,\n\tPortResolver,\n\tPositiveFloatResolver,\n\tPositiveIntResolver,\n\tPostalCodeResolver,\n\tRGBAResolver,\n\tRGBResolver,\n\tSESSNResolver,\n\tTimeResolver,\n\tTimestampResolver,\n\tURLResolver,\n\tUSCurrencyResolver,\n\tUtcOffsetResolver,\n\tUUIDResolver,\n\tVoidResolver,\n} from 'graphql-scalars';\nimport { createScalarFrom } from './utils';\n\nexport const CUSTOM_SCALARS: Record<string, GraphQLScalarType> = {\n\tAccountNumber: createScalarFrom(AccountNumberResolver, {\n\t\terrorMessage: 'validation.errors.invalid-account-number',\n\t}),\n\tBigInt: createScalarFrom(BigIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-big-int',\n\t}),\n\tCountryCode: createScalarFrom(CountryCodeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-country-code',\n\t}),\n\tCountryName: createScalarFrom(CountryNameResolver, {\n\t\terrorMessage: 'validation.errors.invalid-country-name',\n\t}),\n\tCuid: createScalarFrom(CuidResolver, {\n\t\terrorMessage: 'validation.errors.invalid-cuid',\n\t}),\n\tCurrencyCode: createScalarFrom(CurrencyResolver, {\n\t\tname: 'CurrencyCode',\n\t\terrorMessage: 'validation.errors.invalid-currency',\n\t}),\n\tDate: createScalarFrom(DateResolver, {\n\t\terrorMessage: 'validation.errors.invalid-date',\n\t}),\n\tDateTime: createScalarFrom(DateTimeISOResolver, {\n\t\tname: 'DateTime',\n\t\terrorMessage: 'validation.errors.invalid-date-time',\n\t}),\n\tDuration: createScalarFrom(DurationResolver, {\n\t\terrorMessage: 'validation.errors.invalid-duration',\n\t}),\n\tEmailAddress: createScalarFrom(EmailAddressResolver, {\n\t\terrorMessage: 'validation.errors.invalid-email-address',\n\t}),\n\tGeoJSON: createScalarFrom(GeoJSONResolver, {\n\t\terrorMessage: 'validation.errors.invalid-geo-json',\n\t}),\n\tGUID: createScalarFrom(GUIDResolver, {\n\t\terrorMessage: 'validation.errors.invalid-guid',\n\t}),\n\tHexColorCode: createScalarFrom(HexColorCodeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-hex-color-code',\n\t}),\n\tHexadecimal: createScalarFrom(HexadecimalResolver, {\n\t\terrorMessage: 'validation.errors.invalid-hexadecimal',\n\t}),\n\tHSL: createScalarFrom(HSLResolver, {\n\t\terrorMessage: 'validation.errors.invalid-hsl',\n\t}),\n\tHSLA: createScalarFrom(HSLAResolver, {\n\t\terrorMessage: 'validation.errors.invalid-hsla',\n\t}),\n\tIBAN: createScalarFrom(IBANResolver, {\n\t\terrorMessage: 'validation.errors.invalid-iban',\n\t}),\n\tIP: createScalarFrom(IPResolver, {\n\t\terrorMessage: 'validation.errors.invalid-ip',\n\t}),\n\tIPv4: createScalarFrom(IPv4Resolver, {\n\t\terrorMessage: 'validation.errors.invalid-ipv4',\n\t}),\n\tIPv6: createScalarFrom(IPv6Resolver, {\n\t\terrorMessage: 'validation.errors.invalid-ipv6',\n\t}),\n\tISBN: createScalarFrom(ISBNResolver, {\n\t\terrorMessage: 'validation.errors.invalid-isbn',\n\t}),\n\tJSON: createScalarFrom(JSONResolver, {\n\t\terrorMessage: 'validation.errors.invalid-json',\n\t}),\n\tJSONObject: createScalarFrom(JSONObjectResolver, {\n\t\terrorMessage: 'validation.errors.invalid-json-object',\n\t}),\n\tJWT: createScalarFrom(JWTResolver, {\n\t\terrorMessage: 'validation.errors.invalid-jwt',\n\t}),\n\tLatitude: createScalarFrom(LatitudeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-latitude',\n\t}),\n\tLocale: createScalarFrom(LocaleResolver, {\n\t\terrorMessage: 'validation.errors.invalid-locale',\n\t}),\n\tLongitude: createScalarFrom(LongitudeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-longitude',\n\t}),\n\tLong: createScalarFrom(LongResolver, {\n\t\terrorMessage: 'validation.errors.invalid-long',\n\t}),\n\tMAC: createScalarFrom(MACResolver, {\n\t\terrorMessage: 'validation.errors.invalid-mac',\n\t}),\n\tNegativeFloat: createScalarFrom(NegativeFloatResolver, {\n\t\terrorMessage: 'validation.errors.invalid-negative-float',\n\t}),\n\tNegativeInt: createScalarFrom(NegativeIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-negative-int',\n\t}),\n\tNonEmptyString: createScalarFrom(NonEmptyStringResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-empty-string',\n\t}),\n\tNonNegativeFloat: createScalarFrom(NonNegativeFloatResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-negative-float',\n\t}),\n\tNonNegativeInt: createScalarFrom(NonNegativeIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-negative-int',\n\t}),\n\tNonPositiveFloat: createScalarFrom(NonPositiveFloatResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-positive-float',\n\t}),\n\tNonPositiveInt: createScalarFrom(NonPositiveIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-non-positive-int',\n\t}),\n\tObjectID: createScalarFrom(ObjectIDResolver, {\n\t\terrorMessage: 'validation.errors.invalid-object-id',\n\t}),\n\tPhoneNumber: createScalarFrom(PhoneNumberResolver, {\n\t\terrorMessage: 'validation.errors.invalid-phone-number',\n\t}),\n\tPort: createScalarFrom(PortResolver, {\n\t\terrorMessage: 'validation.errors.invalid-port',\n\t}),\n\tPositiveFloat: createScalarFrom(PositiveFloatResolver, {\n\t\terrorMessage: 'validation.errors.invalid-positive-float',\n\t}),\n\tPositiveInt: createScalarFrom(PositiveIntResolver, {\n\t\terrorMessage: 'validation.errors.invalid-positive-int',\n\t}),\n\tPostalCode: createScalarFrom(PostalCodeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-postal-code',\n\t}),\n\tRGB: createScalarFrom(RGBResolver, {\n\t\terrorMessage: 'validation.errors.invalid-rgb',\n\t}),\n\tRGBA: createScalarFrom(RGBAResolver, {\n\t\terrorMessage: 'validation.errors.invalid-rgba',\n\t}),\n\tSESSN: createScalarFrom(SESSNResolver, {\n\t\terrorMessage: 'validation.errors.invalid-sessn',\n\t}),\n\tTime: createScalarFrom(TimeResolver, {\n\t\terrorMessage: 'validation.errors.invalid-time',\n\t}),\n\tTimestamp: createScalarFrom(TimestampResolver, {\n\t\terrorMessage: 'validation.errors.invalid-timestamp',\n\t}),\n\tURL: createScalarFrom(URLResolver, {\n\t\terrorMessage: 'validation.errors.invalid-url',\n\t}),\n\tUSCurrency: createScalarFrom(USCurrencyResolver, {\n\t\terrorMessage: 'validation.errors.invalid-us-currency',\n\t}),\n\tUTCOffset: createScalarFrom(UtcOffsetResolver, {\n\t\terrorMessage: 'validation.errors.invalid-utc-offset',\n\t}),\n\tUUID: createScalarFrom(UUIDResolver, {\n\t\terrorMessage: 'validation.errors.invalid-uuid',\n\t}),\n\tVoid: createScalarFrom(VoidResolver, {\n\t\terrorMessage: 'validation.errors.invalid-void',\n\t}),\n};\n",
|
|
@@ -25,7 +27,7 @@
|
|
|
25
27
|
"export const SHARED_TYPE_DEFS = `\ntype Query {\n\t_empty: String\n}\ntype Mutation {\n\t_empty: String\n}\ntype Subscription {\n\t_empty: String\n}\n\ndirective @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM\n\ndirective @policy(policies: [[String!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM\n\ndirective @shareable on OBJECT | FIELD_DEFINITION\n\ndirective @link(url: String!, import: [String!]) on SCHEMA\n\n`;\n",
|
|
26
28
|
"import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';\n\nexport { graphqlUploadExpress };\n"
|
|
27
29
|
],
|
|
28
|
-
"mappings": "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",
|
|
29
|
-
"debugId": "
|
|
30
|
+
"mappings": "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",
|
|
31
|
+
"debugId": "B268AC8FCE1D143C64756E2164756E21",
|
|
30
32
|
"names": []
|
|
31
33
|
}
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type GraphQLSchema } from 'graphql';
|
|
2
|
+
import type { Plugin } from 'graphql-yoga';
|
|
3
|
+
import { type Ory, type Permission, type Subject } from 'stx-sdk/ory';
|
|
4
|
+
import type { GraphQLBaseContext } from '../types';
|
|
5
|
+
import type { OryContext } from './ory-auth';
|
|
6
|
+
/**
|
|
7
|
+
* The per-request answer cache, and the reason `@check` costs nothing on top
|
|
8
|
+
* of the access layer that already asks Keto.
|
|
9
|
+
*
|
|
10
|
+
* `DataLoader` here does two things: it **batches** distinct questions into
|
|
11
|
+
* one `POST /relation-tuples/batch/check`, and it **memoises** identical ones
|
|
12
|
+
* for the life of the request. So a field guarded by `@check(view)` and a
|
|
13
|
+
* service that then calls `require<M>Access` — which asks the same question —
|
|
14
|
+
* pay for one round trip between them.
|
|
15
|
+
*
|
|
16
|
+
* The key is Keto's own notation, `Note:n1#view@idn-7`, so a cache hit is
|
|
17
|
+
* legible in a log line.
|
|
18
|
+
*/
|
|
19
|
+
export type KetoChecker = (permission: Permission, subject: Subject) => Promise<boolean>;
|
|
20
|
+
export type KetoChecksContext = {
|
|
21
|
+
ketoChecks?: KetoChecker;
|
|
22
|
+
};
|
|
23
|
+
export declare function createKetoChecks(ory: Ory): KetoChecker;
|
|
24
|
+
/**
|
|
25
|
+
* Wraps every field carrying `@check` so the permission is answered before its
|
|
26
|
+
* resolver runs.
|
|
27
|
+
*
|
|
28
|
+
* Modelled on `applyGraphqlPolicy` in `@nxgt/security` — same `mapSchema` over
|
|
29
|
+
* `MapperKind.OBJECT_FIELD`, same `fieldConfig.resolve ?? defaultFieldResolver`.
|
|
30
|
+
* Exported on its own because a schema transform is far easier to test than a
|
|
31
|
+
* plugin, and `useKetoChecks` is a three-line wrapper over it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function applyKetoChecks(schema: GraphQLSchema): GraphQLSchema;
|
|
34
|
+
/**
|
|
35
|
+
* Registers the whole thing: the schema transform, and the per-request checker
|
|
36
|
+
* the transform — and the app's own access layer — read off the context.
|
|
37
|
+
*
|
|
38
|
+
* Goes after `useOryAuth(ory)`, which is what puts `ory.subject` there.
|
|
39
|
+
*
|
|
40
|
+
* `replaceSchema` inside `onSchemaChange` re-enters this hook with the new
|
|
41
|
+
* schema, so transformed schemas are remembered and passed through. Without
|
|
42
|
+
* the guard this loops until the stack gives out.
|
|
43
|
+
*
|
|
44
|
+
* `OryUnavailable` is deliberately not caught anywhere here: a Keto outage is
|
|
45
|
+
* a 503 through `createMaskError`, never a denial.
|
|
46
|
+
*/
|
|
47
|
+
export declare function useKetoChecks(ory: Ory): Plugin<GraphQLBaseContext & OryContext & KetoChecksContext>;
|
|
48
|
+
//# sourceMappingURL=keto-checks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keto-checks.d.ts","sourceRoot":"","sources":["../../src/plugins/keto-checks.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAEN,KAAK,GAAG,EACR,KAAK,UAAU,EAEf,KAAK,OAAO,EAEZ,MAAM,aAAa,CAAC;AAOrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,GAAG,CACzB,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,OAAO,KACZ,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,MAAM,iBAAiB,GAAG;IAC/B,UAAU,CAAC,EAAE,WAAW,CAAC;CACzB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,CAUtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CA4CpE;AAmCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC5B,GAAG,EAAE,GAAG,GACN,MAAM,CAAC,kBAAkB,GAAG,UAAU,GAAG,iBAAiB,CAAC,CAc7D"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# The Ory-native counterpart to @policy.
|
|
2
|
+
#
|
|
3
|
+
# @policy asks whether the caller CARRIES an authority. An Ory principal
|
|
4
|
+
# carries none — `toPrincipal` sets `authorities: []` on purpose — because
|
|
5
|
+
# Keto answers per OBJECT: "may this subject `view` `Note:<id>`". @check is how
|
|
6
|
+
# a schema asks that, and `useKetoChecks(ory)` is what answers it.
|
|
7
|
+
#
|
|
8
|
+
# It lives here, in the shipped SDL, rather than in SHARED_TYPE_DEFS, so that
|
|
9
|
+
# every consumer of SHARED_SCHEMA_PATH sees it — the subgraphs built with
|
|
10
|
+
# `buildSubgraphSchema` included, which never load SHARED_TYPE_DEFS.
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
One question, with the object left as a path instead of a value.
|
|
14
|
+
"""
|
|
15
|
+
input CheckPermission {
|
|
16
|
+
"""
|
|
17
|
+
The Keto namespace, e.g. "Note" — from the stack's OPL document.
|
|
18
|
+
"""
|
|
19
|
+
namespace: String!
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
The permit asked of it, e.g. "view". A plain relation works too; Keto
|
|
23
|
+
answers `false`, not an error, for a name it does not know.
|
|
24
|
+
"""
|
|
25
|
+
permit: String!
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
Where the object id is read: `args.<path>` or `source.<path>`, dotted paths
|
|
29
|
+
allowed. A value that turns out to be a LIST requires the permit on every
|
|
30
|
+
element — that is what a mutation taking `ids: [ID!]!` means.
|
|
31
|
+
"""
|
|
32
|
+
id: String = "args.id"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
What a denial looks like from outside.
|
|
37
|
+
"""
|
|
38
|
+
enum CheckDenial {
|
|
39
|
+
"""
|
|
40
|
+
The same answer as for an id that never existed, so ids cannot be probed.
|
|
41
|
+
The default, and the one to keep unless the caller already knows the object
|
|
42
|
+
is there.
|
|
43
|
+
"""
|
|
44
|
+
NOT_FOUND
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
For a second check on an object the caller can already see: a viewer asked
|
|
48
|
+
to edit already knows it exists, and "you may not change it" is honest.
|
|
49
|
+
"""
|
|
50
|
+
FORBIDDEN
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
"""
|
|
54
|
+
The permission a field requires, in disjunctive normal form: the OUTER list is
|
|
55
|
+
OR, the INNER list is AND. `[[A, B], [C]]` reads "(A and B) or C" — the same
|
|
56
|
+
shape `@policy(policies: [["ADMIN"]])` uses.
|
|
57
|
+
|
|
58
|
+
Repeatable, and evaluated in declaration order, each with its own `onDeny`.
|
|
59
|
+
That is how the 404-then-403 ladder is written:
|
|
60
|
+
|
|
61
|
+
updateNote(id: ID!, input: UpdateNoteInput!): Note!
|
|
62
|
+
@check(permissions: [[{ namespace: "Note", permit: "view" }]])
|
|
63
|
+
@check(permissions: [[{ namespace: "Note", permit: "edit" }]], onDeny: FORBIDDEN)
|
|
64
|
+
|
|
65
|
+
NOT for a field that answers a LIST the caller is entitled to. "Which notes may
|
|
66
|
+
I see" is not a check, it is a Keto query folded into the database filter
|
|
67
|
+
before the read. A directive there would have to fetch everything and filter
|
|
68
|
+
after, which makes `totalCount` and the cursors lie.
|
|
69
|
+
"""
|
|
70
|
+
directive @check(
|
|
71
|
+
permissions: [[CheckPermission!]!]!
|
|
72
|
+
onDeny: CheckDenial! = NOT_FOUND
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
The i18n key the denial carries, e.g. "notes.errors.not-found". Defaults to
|
|
76
|
+
`errors.not-found` / `errors.insufficient-permissions`, the shared keys.
|
|
77
|
+
|
|
78
|
+
Set it whenever the API's own service layer answers the same refusal with a
|
|
79
|
+
domain message. Two layers guard these fields — the directive, and the
|
|
80
|
+
`require<M>Access` the service calls — and if they word the same 404
|
|
81
|
+
differently, the wording tells a caller WHICH one refused: a generic message
|
|
82
|
+
means "you may not", a domain one means "it is gone". That is precisely the
|
|
83
|
+
distinction NOT_FOUND exists to hide.
|
|
84
|
+
"""
|
|
85
|
+
message: String
|
|
86
|
+
) repeatable on FIELD_DEFINITION
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/shared-graphql",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,12 +55,12 @@
|
|
|
55
55
|
"@graphql-tools/utils": "^12.0.0",
|
|
56
56
|
"@graphql-yoga/redis-event-target": "^3.0.3",
|
|
57
57
|
"@hono/zod-validator": "^0.9.0",
|
|
58
|
-
"@nxgt/i18n": "^1.0.
|
|
59
|
-
"@nxgt/security": "^1.0.
|
|
60
|
-
"@nxgt/shared": "^1.0.
|
|
61
|
-
"@nxgt/shared-exceptions": "^1.0.
|
|
62
|
-
"@nxgt/shared-logging": "^1.0.
|
|
63
|
-
"@nxgt/shared-mongo": "^1.1.
|
|
58
|
+
"@nxgt/i18n": "^1.0.2",
|
|
59
|
+
"@nxgt/security": "^1.0.2",
|
|
60
|
+
"@nxgt/shared": "^1.0.2",
|
|
61
|
+
"@nxgt/shared-exceptions": "^1.0.2",
|
|
62
|
+
"@nxgt/shared-logging": "^1.0.2",
|
|
63
|
+
"@nxgt/shared-mongo": "^1.1.2",
|
|
64
64
|
"dataloader": "^2.2.3",
|
|
65
65
|
"graphql": "^16.4.2",
|
|
66
66
|
"graphql-scalars": "^1.26.0",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"@types/ws": "^8.18.1"
|
|
82
82
|
},
|
|
83
83
|
"peerDependencies": {
|
|
84
|
-
"stx-sdk": ">=1.
|
|
84
|
+
"stx-sdk": ">=1.1.0",
|
|
85
85
|
"typescript": "^6.0.3"
|
|
86
86
|
}
|
|
87
87
|
}
|