@grantjs/schema 1.22.1 → 1.23.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/package.json +1 -1
- package/src/events/event-catalog.ts +2 -0
- package/src/generated/graphql.ts +402 -0
- package/src/generated/resolvers.ts +43 -0
- package/src/generated/schema-types.ts +38 -2
- package/src/operations/api-keys/get-api-key-attachable-grants.graphql +23 -0
- package/src/operations/api-keys/get-api-key-role-permissions.graphql +28 -0
- package/src/operations/api-keys/get-api-keys.graphql +11 -0
- package/src/operations/api-keys/set-api-key-permissions.graphql +27 -0
- package/src/schema/api-keys/inputs/create-api-key.graphql +5 -1
- package/src/schema/api-keys/inputs/set-api-key-permissions.graphql +8 -0
- package/src/schema/api-keys/mutations/set-api-key-permissions.graphql +6 -0
- package/src/schema/api-keys/queries/get-api-key-attachable-grants.graphql +6 -0
- package/src/schema/api-keys/types/api-key-attachable-grants.graphql +4 -0
- package/src/schema/api-keys/types/api-key-attachable-permission.graphql +7 -0
- package/src/schema/api-keys/types/api-key.graphql +5 -1
- package/src/sdl-contract.test.ts +3 -1
package/package.json
CHANGED
|
@@ -154,6 +154,7 @@ export const EVENT_TYPES = [
|
|
|
154
154
|
'project.user_email_changed',
|
|
155
155
|
'project.user_password_set',
|
|
156
156
|
'api_key.deleted',
|
|
157
|
+
'api_key.updated',
|
|
157
158
|
'tag.created',
|
|
158
159
|
'tag.updated',
|
|
159
160
|
'tag.deleted',
|
|
@@ -232,6 +233,7 @@ export const EVENT_CATALOG: Readonly<Record<EventType, EventCatalogEntry>> = {
|
|
|
232
233
|
// Every project-credential write that changes the stored hash, any source. data.after = { projectId, userId, source }: never a hash or a password.
|
|
233
234
|
'project.user_password_set': webhookOnly('membership'),
|
|
234
235
|
'api_key.deleted': webhookOnly('security'),
|
|
236
|
+
'api_key.updated': webhookOnly('security'),
|
|
235
237
|
'tag.created': webhookOnly('iam'),
|
|
236
238
|
'tag.updated': webhookOnly('iam'),
|
|
237
239
|
'tag.deleted': webhookOnly('iam'),
|
package/src/generated/graphql.ts
CHANGED
|
@@ -50,6 +50,51 @@ export type ExchangeApiKeyMutationVariables = Exact<{
|
|
|
50
50
|
|
|
51
51
|
export type ExchangeApiKeyMutation = { exchangeApiKey: { accessToken: string; expiresIn: number } };
|
|
52
52
|
|
|
53
|
+
export type GetApiKeyAttachableGrantsQueryVariables = Exact<{
|
|
54
|
+
scope: Types.Scope;
|
|
55
|
+
}>;
|
|
56
|
+
|
|
57
|
+
export type GetApiKeyAttachableGrantsQuery = {
|
|
58
|
+
apiKeyAttachableGrants: {
|
|
59
|
+
permissions: Array<{
|
|
60
|
+
machineOnly: boolean;
|
|
61
|
+
permission: {
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
action: string;
|
|
65
|
+
description: string | null;
|
|
66
|
+
resource: { id: string; slug: string; name: string } | null;
|
|
67
|
+
};
|
|
68
|
+
}>;
|
|
69
|
+
roles: Array<{ id: string; name: string; description: string | null }>;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type GetApiKeyRolePermissionsQueryVariables = Exact<{
|
|
74
|
+
scope: Types.Scope;
|
|
75
|
+
ids?: Array<string | number> | string | number | null | undefined;
|
|
76
|
+
}>;
|
|
77
|
+
|
|
78
|
+
export type GetApiKeyRolePermissionsQuery = {
|
|
79
|
+
roles: {
|
|
80
|
+
roles: Array<{
|
|
81
|
+
id: string;
|
|
82
|
+
name: string;
|
|
83
|
+
groups: Array<{
|
|
84
|
+
id: string;
|
|
85
|
+
permissions: Array<{
|
|
86
|
+
id: string;
|
|
87
|
+
name: string;
|
|
88
|
+
action: string;
|
|
89
|
+
description: string | null;
|
|
90
|
+
resource: { id: string; slug: string; name: string } | null;
|
|
91
|
+
}> | null;
|
|
92
|
+
}> | null;
|
|
93
|
+
rolePermissions: Array<{ id: string; permissionId: string }> | null;
|
|
94
|
+
}>;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
53
98
|
export type GetApiKeysQueryVariables = Exact<{
|
|
54
99
|
scope: Types.Scope;
|
|
55
100
|
page?: number | null | undefined;
|
|
@@ -78,6 +123,13 @@ export type GetApiKeysQuery = {
|
|
|
78
123
|
updatedAt: Date;
|
|
79
124
|
deletedAt: Date | null;
|
|
80
125
|
role: { id: string; name: string } | null;
|
|
126
|
+
permissions: Array<{
|
|
127
|
+
id: string;
|
|
128
|
+
name: string;
|
|
129
|
+
action: string;
|
|
130
|
+
description: string | null;
|
|
131
|
+
resource: { id: string; slug: string; name: string } | null;
|
|
132
|
+
}> | null;
|
|
81
133
|
createdByUser: { id: string; name: string; pictureUrl: string | null } | null;
|
|
82
134
|
revokedByUser: { id: string; name: string; pictureUrl: string | null } | null;
|
|
83
135
|
}>;
|
|
@@ -122,6 +174,31 @@ export type RotateApiKeyMutation = {
|
|
|
122
174
|
};
|
|
123
175
|
};
|
|
124
176
|
|
|
177
|
+
export type SetApiKeyPermissionsMutationVariables = Exact<{
|
|
178
|
+
input: Types.SetApiKeyPermissionsInput;
|
|
179
|
+
}>;
|
|
180
|
+
|
|
181
|
+
export type SetApiKeyPermissionsMutation = {
|
|
182
|
+
setApiKeyPermissions: {
|
|
183
|
+
id: string;
|
|
184
|
+
clientId: string;
|
|
185
|
+
name: string | null;
|
|
186
|
+
description: string | null;
|
|
187
|
+
expiresAt: Date | null;
|
|
188
|
+
lastUsedAt: Date | null;
|
|
189
|
+
isRevoked: boolean;
|
|
190
|
+
updatedAt: Date;
|
|
191
|
+
role: { id: string; name: string } | null;
|
|
192
|
+
permissions: Array<{
|
|
193
|
+
id: string;
|
|
194
|
+
name: string;
|
|
195
|
+
action: string;
|
|
196
|
+
description: string | null;
|
|
197
|
+
resource: { id: string; slug: string; name: string } | null;
|
|
198
|
+
}> | null;
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
|
|
125
202
|
export type AuthSignupPolicyQueryVariables = Exact<{ [key: string]: never }>;
|
|
126
203
|
|
|
127
204
|
export type AuthSignupPolicyQuery = {
|
|
@@ -2530,6 +2607,221 @@ export const ExchangeApiKeyDocument = {
|
|
|
2530
2607
|
},
|
|
2531
2608
|
],
|
|
2532
2609
|
} as unknown as DocumentNode<ExchangeApiKeyMutation, ExchangeApiKeyMutationVariables>;
|
|
2610
|
+
export const GetApiKeyAttachableGrantsDocument = {
|
|
2611
|
+
kind: 'Document',
|
|
2612
|
+
definitions: [
|
|
2613
|
+
{
|
|
2614
|
+
kind: 'OperationDefinition',
|
|
2615
|
+
operation: 'query',
|
|
2616
|
+
name: { kind: 'Name', value: 'GetApiKeyAttachableGrants' },
|
|
2617
|
+
variableDefinitions: [
|
|
2618
|
+
{
|
|
2619
|
+
kind: 'VariableDefinition',
|
|
2620
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'scope' } },
|
|
2621
|
+
type: {
|
|
2622
|
+
kind: 'NonNullType',
|
|
2623
|
+
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Scope' } },
|
|
2624
|
+
},
|
|
2625
|
+
},
|
|
2626
|
+
],
|
|
2627
|
+
selectionSet: {
|
|
2628
|
+
kind: 'SelectionSet',
|
|
2629
|
+
selections: [
|
|
2630
|
+
{
|
|
2631
|
+
kind: 'Field',
|
|
2632
|
+
name: { kind: 'Name', value: 'apiKeyAttachableGrants' },
|
|
2633
|
+
arguments: [
|
|
2634
|
+
{
|
|
2635
|
+
kind: 'Argument',
|
|
2636
|
+
name: { kind: 'Name', value: 'scope' },
|
|
2637
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'scope' } },
|
|
2638
|
+
},
|
|
2639
|
+
],
|
|
2640
|
+
selectionSet: {
|
|
2641
|
+
kind: 'SelectionSet',
|
|
2642
|
+
selections: [
|
|
2643
|
+
{
|
|
2644
|
+
kind: 'Field',
|
|
2645
|
+
name: { kind: 'Name', value: 'permissions' },
|
|
2646
|
+
selectionSet: {
|
|
2647
|
+
kind: 'SelectionSet',
|
|
2648
|
+
selections: [
|
|
2649
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'machineOnly' } },
|
|
2650
|
+
{
|
|
2651
|
+
kind: 'Field',
|
|
2652
|
+
name: { kind: 'Name', value: 'permission' },
|
|
2653
|
+
selectionSet: {
|
|
2654
|
+
kind: 'SelectionSet',
|
|
2655
|
+
selections: [
|
|
2656
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2657
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
2658
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'action' } },
|
|
2659
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
|
|
2660
|
+
{
|
|
2661
|
+
kind: 'Field',
|
|
2662
|
+
name: { kind: 'Name', value: 'resource' },
|
|
2663
|
+
selectionSet: {
|
|
2664
|
+
kind: 'SelectionSet',
|
|
2665
|
+
selections: [
|
|
2666
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2667
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'slug' } },
|
|
2668
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
2669
|
+
],
|
|
2670
|
+
},
|
|
2671
|
+
},
|
|
2672
|
+
],
|
|
2673
|
+
},
|
|
2674
|
+
},
|
|
2675
|
+
],
|
|
2676
|
+
},
|
|
2677
|
+
},
|
|
2678
|
+
{
|
|
2679
|
+
kind: 'Field',
|
|
2680
|
+
name: { kind: 'Name', value: 'roles' },
|
|
2681
|
+
selectionSet: {
|
|
2682
|
+
kind: 'SelectionSet',
|
|
2683
|
+
selections: [
|
|
2684
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2685
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
2686
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
|
|
2687
|
+
],
|
|
2688
|
+
},
|
|
2689
|
+
},
|
|
2690
|
+
],
|
|
2691
|
+
},
|
|
2692
|
+
},
|
|
2693
|
+
],
|
|
2694
|
+
},
|
|
2695
|
+
},
|
|
2696
|
+
],
|
|
2697
|
+
} as unknown as DocumentNode<
|
|
2698
|
+
GetApiKeyAttachableGrantsQuery,
|
|
2699
|
+
GetApiKeyAttachableGrantsQueryVariables
|
|
2700
|
+
>;
|
|
2701
|
+
export const GetApiKeyRolePermissionsDocument = {
|
|
2702
|
+
kind: 'Document',
|
|
2703
|
+
definitions: [
|
|
2704
|
+
{
|
|
2705
|
+
kind: 'OperationDefinition',
|
|
2706
|
+
operation: 'query',
|
|
2707
|
+
name: { kind: 'Name', value: 'GetApiKeyRolePermissions' },
|
|
2708
|
+
variableDefinitions: [
|
|
2709
|
+
{
|
|
2710
|
+
kind: 'VariableDefinition',
|
|
2711
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'scope' } },
|
|
2712
|
+
type: {
|
|
2713
|
+
kind: 'NonNullType',
|
|
2714
|
+
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Scope' } },
|
|
2715
|
+
},
|
|
2716
|
+
},
|
|
2717
|
+
{
|
|
2718
|
+
kind: 'VariableDefinition',
|
|
2719
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'ids' } },
|
|
2720
|
+
type: {
|
|
2721
|
+
kind: 'ListType',
|
|
2722
|
+
type: {
|
|
2723
|
+
kind: 'NonNullType',
|
|
2724
|
+
type: { kind: 'NamedType', name: { kind: 'Name', value: 'ID' } },
|
|
2725
|
+
},
|
|
2726
|
+
},
|
|
2727
|
+
},
|
|
2728
|
+
],
|
|
2729
|
+
selectionSet: {
|
|
2730
|
+
kind: 'SelectionSet',
|
|
2731
|
+
selections: [
|
|
2732
|
+
{
|
|
2733
|
+
kind: 'Field',
|
|
2734
|
+
name: { kind: 'Name', value: 'roles' },
|
|
2735
|
+
arguments: [
|
|
2736
|
+
{
|
|
2737
|
+
kind: 'Argument',
|
|
2738
|
+
name: { kind: 'Name', value: 'scope' },
|
|
2739
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'scope' } },
|
|
2740
|
+
},
|
|
2741
|
+
{
|
|
2742
|
+
kind: 'Argument',
|
|
2743
|
+
name: { kind: 'Name', value: 'ids' },
|
|
2744
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'ids' } },
|
|
2745
|
+
},
|
|
2746
|
+
{
|
|
2747
|
+
kind: 'Argument',
|
|
2748
|
+
name: { kind: 'Name', value: 'limit' },
|
|
2749
|
+
value: { kind: 'IntValue', value: '1' },
|
|
2750
|
+
},
|
|
2751
|
+
{
|
|
2752
|
+
kind: 'Argument',
|
|
2753
|
+
name: { kind: 'Name', value: 'page' },
|
|
2754
|
+
value: { kind: 'IntValue', value: '1' },
|
|
2755
|
+
},
|
|
2756
|
+
],
|
|
2757
|
+
selectionSet: {
|
|
2758
|
+
kind: 'SelectionSet',
|
|
2759
|
+
selections: [
|
|
2760
|
+
{
|
|
2761
|
+
kind: 'Field',
|
|
2762
|
+
name: { kind: 'Name', value: 'roles' },
|
|
2763
|
+
selectionSet: {
|
|
2764
|
+
kind: 'SelectionSet',
|
|
2765
|
+
selections: [
|
|
2766
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2767
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
2768
|
+
{
|
|
2769
|
+
kind: 'Field',
|
|
2770
|
+
name: { kind: 'Name', value: 'groups' },
|
|
2771
|
+
selectionSet: {
|
|
2772
|
+
kind: 'SelectionSet',
|
|
2773
|
+
selections: [
|
|
2774
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2775
|
+
{
|
|
2776
|
+
kind: 'Field',
|
|
2777
|
+
name: { kind: 'Name', value: 'permissions' },
|
|
2778
|
+
selectionSet: {
|
|
2779
|
+
kind: 'SelectionSet',
|
|
2780
|
+
selections: [
|
|
2781
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2782
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
2783
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'action' } },
|
|
2784
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
|
|
2785
|
+
{
|
|
2786
|
+
kind: 'Field',
|
|
2787
|
+
name: { kind: 'Name', value: 'resource' },
|
|
2788
|
+
selectionSet: {
|
|
2789
|
+
kind: 'SelectionSet',
|
|
2790
|
+
selections: [
|
|
2791
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2792
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'slug' } },
|
|
2793
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
2794
|
+
],
|
|
2795
|
+
},
|
|
2796
|
+
},
|
|
2797
|
+
],
|
|
2798
|
+
},
|
|
2799
|
+
},
|
|
2800
|
+
],
|
|
2801
|
+
},
|
|
2802
|
+
},
|
|
2803
|
+
{
|
|
2804
|
+
kind: 'Field',
|
|
2805
|
+
name: { kind: 'Name', value: 'rolePermissions' },
|
|
2806
|
+
selectionSet: {
|
|
2807
|
+
kind: 'SelectionSet',
|
|
2808
|
+
selections: [
|
|
2809
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2810
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'permissionId' } },
|
|
2811
|
+
],
|
|
2812
|
+
},
|
|
2813
|
+
},
|
|
2814
|
+
],
|
|
2815
|
+
},
|
|
2816
|
+
},
|
|
2817
|
+
],
|
|
2818
|
+
},
|
|
2819
|
+
},
|
|
2820
|
+
],
|
|
2821
|
+
},
|
|
2822
|
+
},
|
|
2823
|
+
],
|
|
2824
|
+
} as unknown as DocumentNode<GetApiKeyRolePermissionsQuery, GetApiKeyRolePermissionsQueryVariables>;
|
|
2533
2825
|
export const GetApiKeysDocument = {
|
|
2534
2826
|
kind: 'Document',
|
|
2535
2827
|
definitions: [
|
|
@@ -2649,6 +2941,31 @@ export const GetApiKeysDocument = {
|
|
|
2649
2941
|
],
|
|
2650
2942
|
},
|
|
2651
2943
|
},
|
|
2944
|
+
{
|
|
2945
|
+
kind: 'Field',
|
|
2946
|
+
name: { kind: 'Name', value: 'permissions' },
|
|
2947
|
+
selectionSet: {
|
|
2948
|
+
kind: 'SelectionSet',
|
|
2949
|
+
selections: [
|
|
2950
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2951
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
2952
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'action' } },
|
|
2953
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
|
|
2954
|
+
{
|
|
2955
|
+
kind: 'Field',
|
|
2956
|
+
name: { kind: 'Name', value: 'resource' },
|
|
2957
|
+
selectionSet: {
|
|
2958
|
+
kind: 'SelectionSet',
|
|
2959
|
+
selections: [
|
|
2960
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
2961
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'slug' } },
|
|
2962
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
2963
|
+
],
|
|
2964
|
+
},
|
|
2965
|
+
},
|
|
2966
|
+
],
|
|
2967
|
+
},
|
|
2968
|
+
},
|
|
2652
2969
|
{
|
|
2653
2970
|
kind: 'Field',
|
|
2654
2971
|
name: { kind: 'Name', value: 'createdByUser' },
|
|
@@ -2788,6 +3105,91 @@ export const RotateApiKeyDocument = {
|
|
|
2788
3105
|
},
|
|
2789
3106
|
],
|
|
2790
3107
|
} as unknown as DocumentNode<RotateApiKeyMutation, RotateApiKeyMutationVariables>;
|
|
3108
|
+
export const SetApiKeyPermissionsDocument = {
|
|
3109
|
+
kind: 'Document',
|
|
3110
|
+
definitions: [
|
|
3111
|
+
{
|
|
3112
|
+
kind: 'OperationDefinition',
|
|
3113
|
+
operation: 'mutation',
|
|
3114
|
+
name: { kind: 'Name', value: 'SetApiKeyPermissions' },
|
|
3115
|
+
variableDefinitions: [
|
|
3116
|
+
{
|
|
3117
|
+
kind: 'VariableDefinition',
|
|
3118
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
3119
|
+
type: {
|
|
3120
|
+
kind: 'NonNullType',
|
|
3121
|
+
type: { kind: 'NamedType', name: { kind: 'Name', value: 'SetApiKeyPermissionsInput' } },
|
|
3122
|
+
},
|
|
3123
|
+
},
|
|
3124
|
+
],
|
|
3125
|
+
selectionSet: {
|
|
3126
|
+
kind: 'SelectionSet',
|
|
3127
|
+
selections: [
|
|
3128
|
+
{
|
|
3129
|
+
kind: 'Field',
|
|
3130
|
+
name: { kind: 'Name', value: 'setApiKeyPermissions' },
|
|
3131
|
+
arguments: [
|
|
3132
|
+
{
|
|
3133
|
+
kind: 'Argument',
|
|
3134
|
+
name: { kind: 'Name', value: 'input' },
|
|
3135
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
3136
|
+
},
|
|
3137
|
+
],
|
|
3138
|
+
selectionSet: {
|
|
3139
|
+
kind: 'SelectionSet',
|
|
3140
|
+
selections: [
|
|
3141
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
3142
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'clientId' } },
|
|
3143
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
3144
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
|
|
3145
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'expiresAt' } },
|
|
3146
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'lastUsedAt' } },
|
|
3147
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'isRevoked' } },
|
|
3148
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'updatedAt' } },
|
|
3149
|
+
{
|
|
3150
|
+
kind: 'Field',
|
|
3151
|
+
name: { kind: 'Name', value: 'role' },
|
|
3152
|
+
selectionSet: {
|
|
3153
|
+
kind: 'SelectionSet',
|
|
3154
|
+
selections: [
|
|
3155
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
3156
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
3157
|
+
],
|
|
3158
|
+
},
|
|
3159
|
+
},
|
|
3160
|
+
{
|
|
3161
|
+
kind: 'Field',
|
|
3162
|
+
name: { kind: 'Name', value: 'permissions' },
|
|
3163
|
+
selectionSet: {
|
|
3164
|
+
kind: 'SelectionSet',
|
|
3165
|
+
selections: [
|
|
3166
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
3167
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
3168
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'action' } },
|
|
3169
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'description' } },
|
|
3170
|
+
{
|
|
3171
|
+
kind: 'Field',
|
|
3172
|
+
name: { kind: 'Name', value: 'resource' },
|
|
3173
|
+
selectionSet: {
|
|
3174
|
+
kind: 'SelectionSet',
|
|
3175
|
+
selections: [
|
|
3176
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
3177
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'slug' } },
|
|
3178
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
3179
|
+
],
|
|
3180
|
+
},
|
|
3181
|
+
},
|
|
3182
|
+
],
|
|
3183
|
+
},
|
|
3184
|
+
},
|
|
3185
|
+
],
|
|
3186
|
+
},
|
|
3187
|
+
},
|
|
3188
|
+
],
|
|
3189
|
+
},
|
|
3190
|
+
},
|
|
3191
|
+
],
|
|
3192
|
+
} as unknown as DocumentNode<SetApiKeyPermissionsMutation, SetApiKeyPermissionsMutationVariables>;
|
|
2791
3193
|
export const AuthSignupPolicyDocument = {
|
|
2792
3194
|
kind: 'Document',
|
|
2793
3195
|
definitions: [
|
|
@@ -219,6 +219,8 @@ export type ResolversTypes = ResolversObject<{
|
|
|
219
219
|
AddUserRoleInput: Types.AddUserRoleInput;
|
|
220
220
|
AddUserTagInput: Types.AddUserTagInput;
|
|
221
221
|
ApiKey: ResolverTypeWrapper<Types.ApiKey>;
|
|
222
|
+
ApiKeyAttachableGrants: ResolverTypeWrapper<Types.ApiKeyAttachableGrants>;
|
|
223
|
+
ApiKeyAttachablePermission: ResolverTypeWrapper<Types.ApiKeyAttachablePermission>;
|
|
222
224
|
ApiKeyPage: ResolverTypeWrapper<Types.ApiKeyPage>;
|
|
223
225
|
ApiKeySearchableField: Types.ApiKeySearchableField;
|
|
224
226
|
ApiKeySortInput: Types.ApiKeySortInput;
|
|
@@ -507,6 +509,7 @@ export type ResolversTypes = ResolversObject<{
|
|
|
507
509
|
Scope: Types.Scope;
|
|
508
510
|
Searchable: ResolverTypeWrapper<ResolversInterfaceTypes<ResolversTypes>['Searchable']>;
|
|
509
511
|
SessionExportData: ResolverTypeWrapper<Types.SessionExportData>;
|
|
512
|
+
SetApiKeyPermissionsInput: Types.SetApiKeyPermissionsInput;
|
|
510
513
|
SetMyNotificationPreferenceInput: Types.SetMyNotificationPreferenceInput;
|
|
511
514
|
SetMyPrimaryMfaDeviceInput: Types.SetMyPrimaryMfaDeviceInput;
|
|
512
515
|
SetProjectExportableApiKeySecretsInput: Types.SetProjectExportableApiKeySecretsInput;
|
|
@@ -649,6 +652,8 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
649
652
|
AddUserRoleInput: Types.AddUserRoleInput;
|
|
650
653
|
AddUserTagInput: Types.AddUserTagInput;
|
|
651
654
|
ApiKey: Types.ApiKey;
|
|
655
|
+
ApiKeyAttachableGrants: Types.ApiKeyAttachableGrants;
|
|
656
|
+
ApiKeyAttachablePermission: Types.ApiKeyAttachablePermission;
|
|
652
657
|
ApiKeyPage: Types.ApiKeyPage;
|
|
653
658
|
ApiKeySortInput: Types.ApiKeySortInput;
|
|
654
659
|
AssignRolePermissionInput: Types.AssignRolePermissionInput;
|
|
@@ -899,6 +904,7 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
899
904
|
Scope: Types.Scope;
|
|
900
905
|
Searchable: ResolversInterfaceTypes<ResolversParentTypes>['Searchable'];
|
|
901
906
|
SessionExportData: Types.SessionExportData;
|
|
907
|
+
SetApiKeyPermissionsInput: Types.SetApiKeyPermissionsInput;
|
|
902
908
|
SetMyNotificationPreferenceInput: Types.SetMyNotificationPreferenceInput;
|
|
903
909
|
SetMyPrimaryMfaDeviceInput: Types.SetMyPrimaryMfaDeviceInput;
|
|
904
910
|
SetProjectExportableApiKeySecretsInput: Types.SetProjectExportableApiKeySecretsInput;
|
|
@@ -1136,6 +1142,7 @@ export type ApiKeyResolvers<
|
|
|
1136
1142
|
isRevoked?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
|
|
1137
1143
|
lastUsedAt?: Resolver<Types.Maybe<ResolversTypes['Date']>, ParentType, ContextType>;
|
|
1138
1144
|
name?: Resolver<Types.Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
1145
|
+
permissions?: Resolver<Types.Maybe<Array<ResolversTypes['Permission']>>, ParentType, ContextType>;
|
|
1139
1146
|
revokedAt?: Resolver<Types.Maybe<ResolversTypes['Date']>, ParentType, ContextType>;
|
|
1140
1147
|
revokedBy?: Resolver<Types.Maybe<ResolversTypes['ID']>, ParentType, ContextType>;
|
|
1141
1148
|
revokedByUser?: Resolver<Types.Maybe<ResolversTypes['User']>, ParentType, ContextType>;
|
|
@@ -1144,6 +1151,28 @@ export type ApiKeyResolvers<
|
|
|
1144
1151
|
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
1145
1152
|
}>;
|
|
1146
1153
|
|
|
1154
|
+
export type ApiKeyAttachableGrantsResolvers<
|
|
1155
|
+
ContextType = any,
|
|
1156
|
+
ParentType extends ResolversParentTypes['ApiKeyAttachableGrants'] =
|
|
1157
|
+
ResolversParentTypes['ApiKeyAttachableGrants'],
|
|
1158
|
+
> = ResolversObject<{
|
|
1159
|
+
permissions?: Resolver<
|
|
1160
|
+
Array<ResolversTypes['ApiKeyAttachablePermission']>,
|
|
1161
|
+
ParentType,
|
|
1162
|
+
ContextType
|
|
1163
|
+
>;
|
|
1164
|
+
roles?: Resolver<Array<ResolversTypes['Role']>, ParentType, ContextType>;
|
|
1165
|
+
}>;
|
|
1166
|
+
|
|
1167
|
+
export type ApiKeyAttachablePermissionResolvers<
|
|
1168
|
+
ContextType = any,
|
|
1169
|
+
ParentType extends ResolversParentTypes['ApiKeyAttachablePermission'] =
|
|
1170
|
+
ResolversParentTypes['ApiKeyAttachablePermission'],
|
|
1171
|
+
> = ResolversObject<{
|
|
1172
|
+
machineOnly?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
|
|
1173
|
+
permission?: Resolver<ResolversTypes['Permission'], ParentType, ContextType>;
|
|
1174
|
+
}>;
|
|
1175
|
+
|
|
1147
1176
|
export type ApiKeyPageResolvers<
|
|
1148
1177
|
ContextType = any,
|
|
1149
1178
|
ParentType extends ResolversParentTypes['ApiKeyPage'] = ResolversParentTypes['ApiKeyPage'],
|
|
@@ -2001,6 +2030,12 @@ export type MutationResolvers<
|
|
|
2001
2030
|
ContextType,
|
|
2002
2031
|
RequireFields<Types.MutationRotateWebhookSubscriptionSecretArgs, 'input'>
|
|
2003
2032
|
>;
|
|
2033
|
+
setApiKeyPermissions?: Resolver<
|
|
2034
|
+
ResolversTypes['ApiKey'],
|
|
2035
|
+
ParentType,
|
|
2036
|
+
ContextType,
|
|
2037
|
+
RequireFields<Types.MutationSetApiKeyPermissionsArgs, 'input'>
|
|
2038
|
+
>;
|
|
2004
2039
|
setMyNotificationPreference?: Resolver<
|
|
2005
2040
|
ResolversTypes['NotificationPreference'],
|
|
2006
2041
|
ParentType,
|
|
@@ -2981,6 +3016,12 @@ export type QueryResolvers<
|
|
|
2981
3016
|
ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query'],
|
|
2982
3017
|
> = ResolversObject<{
|
|
2983
3018
|
_empty?: Resolver<Types.Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
3019
|
+
apiKeyAttachableGrants?: Resolver<
|
|
3020
|
+
ResolversTypes['ApiKeyAttachableGrants'],
|
|
3021
|
+
ParentType,
|
|
3022
|
+
ContextType,
|
|
3023
|
+
RequireFields<Types.QueryApiKeyAttachableGrantsArgs, 'scope'>
|
|
3024
|
+
>;
|
|
2984
3025
|
apiKeys?: Resolver<
|
|
2985
3026
|
ResolversTypes['ApiKeyPage'],
|
|
2986
3027
|
ParentType,
|
|
@@ -3870,6 +3911,8 @@ export type Resolvers<ContextType = any> = ResolversObject<{
|
|
|
3870
3911
|
AccountRole?: AccountRoleResolvers<ContextType>;
|
|
3871
3912
|
AccountTag?: AccountTagResolvers<ContextType>;
|
|
3872
3913
|
ApiKey?: ApiKeyResolvers<ContextType>;
|
|
3914
|
+
ApiKeyAttachableGrants?: ApiKeyAttachableGrantsResolvers<ContextType>;
|
|
3915
|
+
ApiKeyAttachablePermission?: ApiKeyAttachablePermissionResolvers<ContextType>;
|
|
3873
3916
|
ApiKeyPage?: ApiKeyPageResolvers<ContextType>;
|
|
3874
3917
|
Auditable?: AuditableResolvers<ContextType>;
|
|
3875
3918
|
AuthSignupPolicy?: AuthSignupPolicyResolvers<ContextType>;
|
|
@@ -340,14 +340,29 @@ export type ApiKey = Auditable & {
|
|
|
340
340
|
isRevoked: Scalars['Boolean']['output'];
|
|
341
341
|
lastUsedAt?: Maybe<Scalars['Date']['output']>;
|
|
342
342
|
name?: Maybe<Scalars['String']['output']>;
|
|
343
|
+
/** Permissions this API key carries instead of a role (project-level keys only). Null for user-scoped keys and for role keys. */
|
|
344
|
+
permissions?: Maybe<Array<Permission>>;
|
|
343
345
|
revokedAt?: Maybe<Scalars['Date']['output']>;
|
|
344
346
|
revokedBy?: Maybe<Scalars['ID']['output']>;
|
|
345
347
|
revokedByUser?: Maybe<User>;
|
|
346
|
-
/**
|
|
348
|
+
/** Standard role bound to this API key (project-level keys only). Null for user-scoped keys and for keys that carry permissions. */
|
|
347
349
|
role?: Maybe<Role>;
|
|
348
350
|
updatedAt: Scalars['Date']['output'];
|
|
349
351
|
};
|
|
350
352
|
|
|
353
|
+
export type ApiKeyAttachableGrants = {
|
|
354
|
+
__typename?: 'ApiKeyAttachableGrants';
|
|
355
|
+
permissions: Array<ApiKeyAttachablePermission>;
|
|
356
|
+
roles: Array<Role>;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
export type ApiKeyAttachablePermission = {
|
|
360
|
+
__typename?: 'ApiKeyAttachablePermission';
|
|
361
|
+
/** True for a permission meant for credentials only (such as ProjectUser:ExportCredentials): it can be given to a key by a holder of its gate permission, without holding it. */
|
|
362
|
+
machineOnly: Scalars['Boolean']['output'];
|
|
363
|
+
permission: Permission;
|
|
364
|
+
};
|
|
365
|
+
|
|
351
366
|
export type ApiKeyPage = PaginatedResults & {
|
|
352
367
|
__typename?: 'ApiKeyPage';
|
|
353
368
|
apiKeys: Array<ApiKey>;
|
|
@@ -610,7 +625,9 @@ export type CreateApiKeyInput = {
|
|
|
610
625
|
description?: InputMaybe<Scalars['String']['input']>;
|
|
611
626
|
expiresAt?: InputMaybe<Scalars['Date']['input']>;
|
|
612
627
|
name?: InputMaybe<Scalars['String']['input']>;
|
|
613
|
-
/**
|
|
628
|
+
/** For a project key: the permissions the key carries instead of a role. Give exactly one of `roleId` or `permissionIds`. Each must be covered by what you can do in this scope, except machine-only permissions, which a holder of their gate permission may attach. Not allowed for other scopes. */
|
|
629
|
+
permissionIds?: InputMaybe<Array<Scalars['ID']['input']>>;
|
|
630
|
+
/** For a project key (scope.tenant is accountProject or organizationProject): the standard role the key carries. Give exactly one of `roleId` or `permissionIds`. An account project key with neither carries the creator's account role. The role's permissions must be covered by what you can do in this scope. */
|
|
614
631
|
roleId?: InputMaybe<Scalars['ID']['input']>;
|
|
615
632
|
scope: Scope;
|
|
616
633
|
};
|
|
@@ -1356,6 +1373,8 @@ export type Mutation = {
|
|
|
1356
1373
|
rotateSigningKey: SigningKey;
|
|
1357
1374
|
/** Rotate the signing secret. The new secret is returned once. */
|
|
1358
1375
|
rotateWebhookSubscriptionSecret: WebhookSubscriptionWithSecret;
|
|
1376
|
+
/** Replace the permissions a project API key carries. Applied to a role key it converts the key to permissions; the conversion is one way. The key keeps its id, clientId and secret, and the change applies to its next request. Refuses a revoked key. */
|
|
1377
|
+
setApiKeyPermissions: ApiKey;
|
|
1359
1378
|
setMyNotificationPreference: NotificationPreference;
|
|
1360
1379
|
setMyPrimaryAuthenticationMethod: UserAuthenticationMethod;
|
|
1361
1380
|
setMyPrimaryMfaDevice: MfaDevice;
|
|
@@ -1731,6 +1750,10 @@ export type MutationRotateWebhookSubscriptionSecretArgs = {
|
|
|
1731
1750
|
input: RotateWebhookSubscriptionSecretInput;
|
|
1732
1751
|
};
|
|
1733
1752
|
|
|
1753
|
+
export type MutationSetApiKeyPermissionsArgs = {
|
|
1754
|
+
input: SetApiKeyPermissionsInput;
|
|
1755
|
+
};
|
|
1756
|
+
|
|
1734
1757
|
export type MutationSetMyNotificationPreferenceArgs = {
|
|
1735
1758
|
input: SetMyNotificationPreferenceInput;
|
|
1736
1759
|
};
|
|
@@ -2706,6 +2729,8 @@ export type ProjectUserPermission = Auditable & {
|
|
|
2706
2729
|
export type Query = {
|
|
2707
2730
|
__typename?: 'Query';
|
|
2708
2731
|
_empty?: Maybe<Scalars['String']['output']>;
|
|
2732
|
+
/** What the caller may give a new project API key in this scope: the permissions (machine-only ones flagged) and the standard roles whose permissions the caller covers. Project scopes only. */
|
|
2733
|
+
apiKeyAttachableGrants: ApiKeyAttachableGrants;
|
|
2709
2734
|
apiKeys: ApiKeyPage;
|
|
2710
2735
|
/** Public signup policy. No authentication required. */
|
|
2711
2736
|
authSignupPolicy: AuthSignupPolicy;
|
|
@@ -2779,6 +2804,10 @@ export type Query = {
|
|
|
2779
2804
|
webhookSubscriptions: Array<WebhookSubscription>;
|
|
2780
2805
|
};
|
|
2781
2806
|
|
|
2807
|
+
export type QueryApiKeyAttachableGrantsArgs = {
|
|
2808
|
+
scope: Scope;
|
|
2809
|
+
};
|
|
2810
|
+
|
|
2782
2811
|
export type QueryApiKeysArgs = {
|
|
2783
2812
|
ids?: InputMaybe<Array<Scalars['ID']['input']>>;
|
|
2784
2813
|
limit?: InputMaybe<Scalars['Int']['input']>;
|
|
@@ -3704,6 +3733,13 @@ export type SessionExportData = {
|
|
|
3704
3733
|
userAgent?: Maybe<Scalars['String']['output']>;
|
|
3705
3734
|
};
|
|
3706
3735
|
|
|
3736
|
+
export type SetApiKeyPermissionsInput = {
|
|
3737
|
+
id: Scalars['ID']['input'];
|
|
3738
|
+
/** The complete set of permissions the key carries afterwards; it may not be empty. Permissions you add must be covered by what you can do in this scope (machine-only permissions: see `apiKeyAttachableGrants`); permissions you leave out are removed. */
|
|
3739
|
+
permissionIds: Array<Scalars['ID']['input']>;
|
|
3740
|
+
scope: Scope;
|
|
3741
|
+
};
|
|
3742
|
+
|
|
3707
3743
|
export type SetMyNotificationPreferenceInput = {
|
|
3708
3744
|
/** Notification preference category (security, iam, membership, integrations). */
|
|
3709
3745
|
category: Scalars['String']['input'];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
query GetApiKeyAttachableGrants($scope: Scope!) {
|
|
2
|
+
apiKeyAttachableGrants(scope: $scope) {
|
|
3
|
+
permissions {
|
|
4
|
+
machineOnly
|
|
5
|
+
permission {
|
|
6
|
+
id
|
|
7
|
+
name
|
|
8
|
+
action
|
|
9
|
+
description
|
|
10
|
+
resource {
|
|
11
|
+
id
|
|
12
|
+
slug
|
|
13
|
+
name
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
roles {
|
|
18
|
+
id
|
|
19
|
+
name
|
|
20
|
+
description
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
query GetApiKeyRolePermissions($scope: Scope!, $ids: [ID!]) {
|
|
2
|
+
roles(scope: $scope, ids: $ids, limit: 1, page: 1) {
|
|
3
|
+
roles {
|
|
4
|
+
id
|
|
5
|
+
name
|
|
6
|
+
# The permissions a role key resolves to come from the role's groups. `groups(scope)` does not
|
|
7
|
+
# list the standard groups, so they are read through the role.
|
|
8
|
+
groups {
|
|
9
|
+
id
|
|
10
|
+
permissions {
|
|
11
|
+
id
|
|
12
|
+
name
|
|
13
|
+
action
|
|
14
|
+
description
|
|
15
|
+
resource {
|
|
16
|
+
id
|
|
17
|
+
slug
|
|
18
|
+
name
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
rolePermissions {
|
|
23
|
+
id
|
|
24
|
+
permissionId
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
mutation SetApiKeyPermissions($input: SetApiKeyPermissionsInput!) {
|
|
2
|
+
setApiKeyPermissions(input: $input) {
|
|
3
|
+
id
|
|
4
|
+
clientId
|
|
5
|
+
name
|
|
6
|
+
description
|
|
7
|
+
expiresAt
|
|
8
|
+
lastUsedAt
|
|
9
|
+
isRevoked
|
|
10
|
+
updatedAt
|
|
11
|
+
role {
|
|
12
|
+
id
|
|
13
|
+
name
|
|
14
|
+
}
|
|
15
|
+
permissions {
|
|
16
|
+
id
|
|
17
|
+
name
|
|
18
|
+
action
|
|
19
|
+
description
|
|
20
|
+
resource {
|
|
21
|
+
id
|
|
22
|
+
slug
|
|
23
|
+
name
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -4,7 +4,11 @@ input CreateApiKeyInput {
|
|
|
4
4
|
expiresAt: Date
|
|
5
5
|
scope: Scope!
|
|
6
6
|
"""
|
|
7
|
-
|
|
7
|
+
For a project key (scope.tenant is accountProject or organizationProject): the standard role the key carries. Give exactly one of `roleId` or `permissionIds`. An account project key with neither carries the creator's account role. The role's permissions must be covered by what you can do in this scope.
|
|
8
8
|
"""
|
|
9
9
|
roleId: ID
|
|
10
|
+
"""
|
|
11
|
+
For a project key: the permissions the key carries instead of a role. Give exactly one of `roleId` or `permissionIds`. Each must be covered by what you can do in this scope, except machine-only permissions, which a holder of their gate permission may attach. Not allowed for other scopes.
|
|
12
|
+
"""
|
|
13
|
+
permissionIds: [ID!]
|
|
10
14
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
input SetApiKeyPermissionsInput {
|
|
2
|
+
scope: Scope!
|
|
3
|
+
id: ID!
|
|
4
|
+
"""
|
|
5
|
+
The complete set of permissions the key carries afterwards; it may not be empty. Permissions you add must be covered by what you can do in this scope (machine-only permissions: see `apiKeyAttachableGrants`); permissions you leave out are removed.
|
|
6
|
+
"""
|
|
7
|
+
permissionIds: [ID!]!
|
|
8
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
extend type Mutation {
|
|
2
|
+
"""
|
|
3
|
+
Replace the permissions a project API key carries. Applied to a role key it converts the key to permissions; the conversion is one way. The key keeps its id, clientId and secret, and the change applies to its next request. Refuses a revoked key.
|
|
4
|
+
"""
|
|
5
|
+
setApiKeyPermissions(input: SetApiKeyPermissionsInput!): ApiKey!
|
|
6
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
extend type Query {
|
|
2
|
+
"""
|
|
3
|
+
What the caller may give a new project API key in this scope: the permissions (machine-only ones flagged) and the standard roles whose permissions the caller covers. Project scopes only.
|
|
4
|
+
"""
|
|
5
|
+
apiKeyAttachableGrants(scope: Scope!): ApiKeyAttachableGrants!
|
|
6
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type ApiKeyAttachablePermission {
|
|
2
|
+
permission: Permission!
|
|
3
|
+
"""
|
|
4
|
+
True for a permission meant for credentials only (such as ProjectUser:ExportCredentials): it can be given to a key by a holder of its gate permission, without holding it.
|
|
5
|
+
"""
|
|
6
|
+
machineOnly: Boolean!
|
|
7
|
+
}
|
|
@@ -15,7 +15,11 @@ type ApiKey implements Auditable {
|
|
|
15
15
|
createdByUser: User
|
|
16
16
|
revokedByUser: User
|
|
17
17
|
"""
|
|
18
|
-
|
|
18
|
+
Standard role bound to this API key (project-level keys only). Null for user-scoped keys and for keys that carry permissions.
|
|
19
19
|
"""
|
|
20
20
|
role: Role
|
|
21
|
+
"""
|
|
22
|
+
Permissions this API key carries instead of a role (project-level keys only). Null for user-scoped keys and for role keys.
|
|
23
|
+
"""
|
|
24
|
+
permissions: [Permission!]
|
|
21
25
|
}
|
package/src/sdl-contract.test.ts
CHANGED
|
@@ -54,10 +54,12 @@ describe('operation documents', () => {
|
|
|
54
54
|
// 138 after operator-set-email: SetProjectUserEmailDocument.
|
|
55
55
|
// 140 after operator-set-password: SetProjectUserPasswordDocument, ExportProjectUserCredentialsDocument.
|
|
56
56
|
// 141 after exportable-api-key-secret opt-in: SetProjectExportableApiKeySecretsDocument.
|
|
57
|
+
// 144 after api-key scopes web: GetApiKeyAttachableGrantsDocument, SetApiKeyPermissionsDocument,
|
|
58
|
+
// GetApiKeyRolePermissionsDocument.
|
|
57
59
|
// Updating this number is the point of the pin, not a nuisance: every change
|
|
58
60
|
// to it should be a line in a commit message.
|
|
59
61
|
it('finds every document under src/operations', () => {
|
|
60
|
-
expect(files).toHaveLength(
|
|
62
|
+
expect(files).toHaveLength(144);
|
|
61
63
|
});
|
|
62
64
|
|
|
63
65
|
it.each(files.map((f) => [relative(process.cwd(), f), f]))('%s validates', (_label, file) => {
|