@grantjs/schema 1.9.1 → 1.10.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 +4 -4
- package/src/generated/graphql.ts +185 -0
- package/src/generated/resolvers.ts +44 -0
- package/src/generated/schema-types.ts +71 -0
- package/src/operations/project-oauth-connections/clear-project-oauth-connection.graphql +3 -0
- package/src/operations/project-oauth-connections/get-project-oauth-connections.graphql +11 -0
- package/src/operations/project-oauth-connections/upsert-project-oauth-connection.graphql +11 -0
- package/src/project-oauth-connection.sdl.test.ts +61 -0
- package/src/project-oauth.types.test.ts +21 -0
- package/src/project-oauth.types.ts +5 -0
- package/src/schema/project-oauth-connections/inputs/clear-project-oauth-connection.graphql +4 -0
- package/src/schema/project-oauth-connections/inputs/upsert-project-oauth-connection.graphql +12 -0
- package/src/schema/project-oauth-connections/mutations/clear-project-oauth-connection.graphql +8 -0
- package/src/schema/project-oauth-connections/mutations/upsert-project-oauth-connection.graphql +8 -0
- package/src/schema/project-oauth-connections/queries/get-project-oauth-connections.graphql +8 -0
- package/src/schema/project-oauth-connections/types/project-oauth-connection-provider.graphql +8 -0
- package/src/schema/project-oauth-connections/types/project-oauth-connection.graphql +20 -0
- package/src/sdl-contract.test.ts +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grantjs/schema",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,18 +23,18 @@
|
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@graphql-codegen/add": "^7.1.0",
|
|
26
|
-
"@graphql-codegen/cli": "^7.4.
|
|
26
|
+
"@graphql-codegen/cli": "^7.4.1",
|
|
27
27
|
"@graphql-codegen/typed-document-node": "^7.1.0",
|
|
28
28
|
"@graphql-codegen/typescript": "^6.1.0",
|
|
29
29
|
"@graphql-codegen/typescript-operations": "^6.1.6",
|
|
30
30
|
"@graphql-codegen/typescript-resolvers": "^6.1.0",
|
|
31
31
|
"@parcel/watcher": "^2.6.0",
|
|
32
|
-
"@types/node": "^26.
|
|
32
|
+
"@types/node": "^26.6.1",
|
|
33
33
|
"eslint": "^10.10.0",
|
|
34
34
|
"graphql": "^16.14.2",
|
|
35
35
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
36
36
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
37
|
-
"vitest": "^
|
|
37
|
+
"vitest": "^5.0.1"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"dev": "graphql-codegen --config codegen.ts generate --watch",
|
package/src/generated/graphql.ts
CHANGED
|
@@ -1257,6 +1257,44 @@ export type UploadProjectAppPictureMutation = {
|
|
|
1257
1257
|
uploadProjectAppPicture: { url: string; path: string };
|
|
1258
1258
|
};
|
|
1259
1259
|
|
|
1260
|
+
export type ClearProjectOAuthConnectionMutationVariables = Exact<{
|
|
1261
|
+
input: Types.ClearProjectOAuthConnectionInput;
|
|
1262
|
+
}>;
|
|
1263
|
+
|
|
1264
|
+
export type ClearProjectOAuthConnectionMutation = { clearProjectOAuthConnection: boolean };
|
|
1265
|
+
|
|
1266
|
+
export type GetProjectOAuthConnectionsQueryVariables = Exact<{
|
|
1267
|
+
scope: Types.Scope;
|
|
1268
|
+
}>;
|
|
1269
|
+
|
|
1270
|
+
export type GetProjectOAuthConnectionsQuery = {
|
|
1271
|
+
projectOAuthConnections: Array<{
|
|
1272
|
+
id: string;
|
|
1273
|
+
projectId: string;
|
|
1274
|
+
provider: Types.ProjectOAuthConnectionProvider;
|
|
1275
|
+
clientId: string;
|
|
1276
|
+
isConfigured: boolean;
|
|
1277
|
+
createdAt: Date;
|
|
1278
|
+
updatedAt: Date;
|
|
1279
|
+
}>;
|
|
1280
|
+
};
|
|
1281
|
+
|
|
1282
|
+
export type UpsertProjectOAuthConnectionMutationVariables = Exact<{
|
|
1283
|
+
input: Types.UpsertProjectOAuthConnectionInput;
|
|
1284
|
+
}>;
|
|
1285
|
+
|
|
1286
|
+
export type UpsertProjectOAuthConnectionMutation = {
|
|
1287
|
+
upsertProjectOAuthConnection: {
|
|
1288
|
+
id: string;
|
|
1289
|
+
projectId: string;
|
|
1290
|
+
provider: Types.ProjectOAuthConnectionProvider;
|
|
1291
|
+
clientId: string;
|
|
1292
|
+
isConfigured: boolean;
|
|
1293
|
+
createdAt: Date;
|
|
1294
|
+
updatedAt: Date;
|
|
1295
|
+
};
|
|
1296
|
+
};
|
|
1297
|
+
|
|
1260
1298
|
export type CancelProjectSyncMutationVariables = Exact<{
|
|
1261
1299
|
id: string | number;
|
|
1262
1300
|
scope: Types.Scope;
|
|
@@ -7188,6 +7226,153 @@ export const UploadProjectAppPictureDocument = {
|
|
|
7188
7226
|
UploadProjectAppPictureMutation,
|
|
7189
7227
|
UploadProjectAppPictureMutationVariables
|
|
7190
7228
|
>;
|
|
7229
|
+
export const ClearProjectOAuthConnectionDocument = {
|
|
7230
|
+
kind: 'Document',
|
|
7231
|
+
definitions: [
|
|
7232
|
+
{
|
|
7233
|
+
kind: 'OperationDefinition',
|
|
7234
|
+
operation: 'mutation',
|
|
7235
|
+
name: { kind: 'Name', value: 'ClearProjectOAuthConnection' },
|
|
7236
|
+
variableDefinitions: [
|
|
7237
|
+
{
|
|
7238
|
+
kind: 'VariableDefinition',
|
|
7239
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
7240
|
+
type: {
|
|
7241
|
+
kind: 'NonNullType',
|
|
7242
|
+
type: {
|
|
7243
|
+
kind: 'NamedType',
|
|
7244
|
+
name: { kind: 'Name', value: 'ClearProjectOAuthConnectionInput' },
|
|
7245
|
+
},
|
|
7246
|
+
},
|
|
7247
|
+
},
|
|
7248
|
+
],
|
|
7249
|
+
selectionSet: {
|
|
7250
|
+
kind: 'SelectionSet',
|
|
7251
|
+
selections: [
|
|
7252
|
+
{
|
|
7253
|
+
kind: 'Field',
|
|
7254
|
+
name: { kind: 'Name', value: 'clearProjectOAuthConnection' },
|
|
7255
|
+
arguments: [
|
|
7256
|
+
{
|
|
7257
|
+
kind: 'Argument',
|
|
7258
|
+
name: { kind: 'Name', value: 'input' },
|
|
7259
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
7260
|
+
},
|
|
7261
|
+
],
|
|
7262
|
+
},
|
|
7263
|
+
],
|
|
7264
|
+
},
|
|
7265
|
+
},
|
|
7266
|
+
],
|
|
7267
|
+
} as unknown as DocumentNode<
|
|
7268
|
+
ClearProjectOAuthConnectionMutation,
|
|
7269
|
+
ClearProjectOAuthConnectionMutationVariables
|
|
7270
|
+
>;
|
|
7271
|
+
export const GetProjectOAuthConnectionsDocument = {
|
|
7272
|
+
kind: 'Document',
|
|
7273
|
+
definitions: [
|
|
7274
|
+
{
|
|
7275
|
+
kind: 'OperationDefinition',
|
|
7276
|
+
operation: 'query',
|
|
7277
|
+
name: { kind: 'Name', value: 'GetProjectOAuthConnections' },
|
|
7278
|
+
variableDefinitions: [
|
|
7279
|
+
{
|
|
7280
|
+
kind: 'VariableDefinition',
|
|
7281
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'scope' } },
|
|
7282
|
+
type: {
|
|
7283
|
+
kind: 'NonNullType',
|
|
7284
|
+
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Scope' } },
|
|
7285
|
+
},
|
|
7286
|
+
},
|
|
7287
|
+
],
|
|
7288
|
+
selectionSet: {
|
|
7289
|
+
kind: 'SelectionSet',
|
|
7290
|
+
selections: [
|
|
7291
|
+
{
|
|
7292
|
+
kind: 'Field',
|
|
7293
|
+
name: { kind: 'Name', value: 'projectOAuthConnections' },
|
|
7294
|
+
arguments: [
|
|
7295
|
+
{
|
|
7296
|
+
kind: 'Argument',
|
|
7297
|
+
name: { kind: 'Name', value: 'scope' },
|
|
7298
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'scope' } },
|
|
7299
|
+
},
|
|
7300
|
+
],
|
|
7301
|
+
selectionSet: {
|
|
7302
|
+
kind: 'SelectionSet',
|
|
7303
|
+
selections: [
|
|
7304
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
7305
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'projectId' } },
|
|
7306
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'provider' } },
|
|
7307
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'clientId' } },
|
|
7308
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'isConfigured' } },
|
|
7309
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'createdAt' } },
|
|
7310
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'updatedAt' } },
|
|
7311
|
+
],
|
|
7312
|
+
},
|
|
7313
|
+
},
|
|
7314
|
+
],
|
|
7315
|
+
},
|
|
7316
|
+
},
|
|
7317
|
+
],
|
|
7318
|
+
} as unknown as DocumentNode<
|
|
7319
|
+
GetProjectOAuthConnectionsQuery,
|
|
7320
|
+
GetProjectOAuthConnectionsQueryVariables
|
|
7321
|
+
>;
|
|
7322
|
+
export const UpsertProjectOAuthConnectionDocument = {
|
|
7323
|
+
kind: 'Document',
|
|
7324
|
+
definitions: [
|
|
7325
|
+
{
|
|
7326
|
+
kind: 'OperationDefinition',
|
|
7327
|
+
operation: 'mutation',
|
|
7328
|
+
name: { kind: 'Name', value: 'UpsertProjectOAuthConnection' },
|
|
7329
|
+
variableDefinitions: [
|
|
7330
|
+
{
|
|
7331
|
+
kind: 'VariableDefinition',
|
|
7332
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
7333
|
+
type: {
|
|
7334
|
+
kind: 'NonNullType',
|
|
7335
|
+
type: {
|
|
7336
|
+
kind: 'NamedType',
|
|
7337
|
+
name: { kind: 'Name', value: 'UpsertProjectOAuthConnectionInput' },
|
|
7338
|
+
},
|
|
7339
|
+
},
|
|
7340
|
+
},
|
|
7341
|
+
],
|
|
7342
|
+
selectionSet: {
|
|
7343
|
+
kind: 'SelectionSet',
|
|
7344
|
+
selections: [
|
|
7345
|
+
{
|
|
7346
|
+
kind: 'Field',
|
|
7347
|
+
name: { kind: 'Name', value: 'upsertProjectOAuthConnection' },
|
|
7348
|
+
arguments: [
|
|
7349
|
+
{
|
|
7350
|
+
kind: 'Argument',
|
|
7351
|
+
name: { kind: 'Name', value: 'input' },
|
|
7352
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
7353
|
+
},
|
|
7354
|
+
],
|
|
7355
|
+
selectionSet: {
|
|
7356
|
+
kind: 'SelectionSet',
|
|
7357
|
+
selections: [
|
|
7358
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
7359
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'projectId' } },
|
|
7360
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'provider' } },
|
|
7361
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'clientId' } },
|
|
7362
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'isConfigured' } },
|
|
7363
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'createdAt' } },
|
|
7364
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'updatedAt' } },
|
|
7365
|
+
],
|
|
7366
|
+
},
|
|
7367
|
+
},
|
|
7368
|
+
],
|
|
7369
|
+
},
|
|
7370
|
+
},
|
|
7371
|
+
],
|
|
7372
|
+
} as unknown as DocumentNode<
|
|
7373
|
+
UpsertProjectOAuthConnectionMutation,
|
|
7374
|
+
UpsertProjectOAuthConnectionMutationVariables
|
|
7375
|
+
>;
|
|
7191
7376
|
export const CancelProjectSyncDocument = {
|
|
7192
7377
|
kind: 'Document',
|
|
7193
7378
|
definitions: [
|
|
@@ -128,6 +128,7 @@ export type ResolversInterfaceTypes<_RefType extends Record<string, unknown>> =
|
|
|
128
128
|
| Types.ProjectApp
|
|
129
129
|
| Types.ProjectAppTag
|
|
130
130
|
| Types.ProjectGroup
|
|
131
|
+
| Types.ProjectOAuthConnection
|
|
131
132
|
| Types.ProjectPermission
|
|
132
133
|
| Types.ProjectResource
|
|
133
134
|
| Types.ProjectRole
|
|
@@ -238,6 +239,7 @@ export type ResolversTypes = ResolversObject<{
|
|
|
238
239
|
ChangeMyPasswordInput: Types.ChangeMyPasswordInput;
|
|
239
240
|
ChangeMyPasswordResult: ResolverTypeWrapper<Types.ChangeMyPasswordResult>;
|
|
240
241
|
ClearProjectAppPictureInput: Types.ClearProjectAppPictureInput;
|
|
242
|
+
ClearProjectOAuthConnectionInput: Types.ClearProjectOAuthConnectionInput;
|
|
241
243
|
ClearProjectPictureInput: Types.ClearProjectPictureInput;
|
|
242
244
|
ConfirmMyProjectMembershipPictureUploadInput: Types.ConfirmMyProjectMembershipPictureUploadInput;
|
|
243
245
|
ConfirmMyUserPictureUploadInput: Types.ConfirmMyUserPictureUploadInput;
|
|
@@ -359,6 +361,8 @@ export type ResolversTypes = ResolversObject<{
|
|
|
359
361
|
ProjectAppTag: ResolverTypeWrapper<Types.ProjectAppTag>;
|
|
360
362
|
ProjectGroup: ResolverTypeWrapper<Types.ProjectGroup>;
|
|
361
363
|
ProjectMembershipExportData: ResolverTypeWrapper<Types.ProjectMembershipExportData>;
|
|
364
|
+
ProjectOAuthConnection: ResolverTypeWrapper<Types.ProjectOAuthConnection>;
|
|
365
|
+
ProjectOAuthConnectionProvider: Types.ProjectOAuthConnectionProvider;
|
|
362
366
|
ProjectPage: ResolverTypeWrapper<Types.ProjectPage>;
|
|
363
367
|
ProjectPermission: ResolverTypeWrapper<Types.ProjectPermission>;
|
|
364
368
|
ProjectResource: ResolverTypeWrapper<Types.ProjectResource>;
|
|
@@ -545,6 +549,7 @@ export type ResolversTypes = ResolversObject<{
|
|
|
545
549
|
UploadUrlHeader: ResolverTypeWrapper<Types.UploadUrlHeader>;
|
|
546
550
|
UploadUserPictureInput: Types.UploadUserPictureInput;
|
|
547
551
|
UploadUserPictureResult: ResolverTypeWrapper<Types.UploadUserPictureResult>;
|
|
552
|
+
UpsertProjectOAuthConnectionInput: Types.UpsertProjectOAuthConnectionInput;
|
|
548
553
|
User: ResolverTypeWrapper<Types.User>;
|
|
549
554
|
UserApiKeyCdmInput: Types.UserApiKeyCdmInput;
|
|
550
555
|
UserAuthenticationEmailProviderAction: Types.UserAuthenticationEmailProviderAction;
|
|
@@ -639,6 +644,7 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
639
644
|
ChangeMyPasswordInput: Types.ChangeMyPasswordInput;
|
|
640
645
|
ChangeMyPasswordResult: Types.ChangeMyPasswordResult;
|
|
641
646
|
ClearProjectAppPictureInput: Types.ClearProjectAppPictureInput;
|
|
647
|
+
ClearProjectOAuthConnectionInput: Types.ClearProjectOAuthConnectionInput;
|
|
642
648
|
ClearProjectPictureInput: Types.ClearProjectPictureInput;
|
|
643
649
|
ConfirmMyProjectMembershipPictureUploadInput: Types.ConfirmMyProjectMembershipPictureUploadInput;
|
|
644
650
|
ConfirmMyUserPictureUploadInput: Types.ConfirmMyUserPictureUploadInput;
|
|
@@ -741,6 +747,7 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
741
747
|
ProjectAppTag: Types.ProjectAppTag;
|
|
742
748
|
ProjectGroup: Types.ProjectGroup;
|
|
743
749
|
ProjectMembershipExportData: Types.ProjectMembershipExportData;
|
|
750
|
+
ProjectOAuthConnection: Types.ProjectOAuthConnection;
|
|
744
751
|
ProjectPage: Types.ProjectPage;
|
|
745
752
|
ProjectPermission: Types.ProjectPermission;
|
|
746
753
|
ProjectResource: Types.ProjectResource;
|
|
@@ -913,6 +920,7 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
913
920
|
UploadUrlHeader: Types.UploadUrlHeader;
|
|
914
921
|
UploadUserPictureInput: Types.UploadUserPictureInput;
|
|
915
922
|
UploadUserPictureResult: Types.UploadUserPictureResult;
|
|
923
|
+
UpsertProjectOAuthConnectionInput: Types.UpsertProjectOAuthConnectionInput;
|
|
916
924
|
User: Types.User;
|
|
917
925
|
UserApiKeyCdmInput: Types.UserApiKeyCdmInput;
|
|
918
926
|
UserAuthenticationMethod: Types.UserAuthenticationMethod;
|
|
@@ -1143,6 +1151,7 @@ export type AuditableResolvers<
|
|
|
1143
1151
|
| 'ProjectApp'
|
|
1144
1152
|
| 'ProjectAppTag'
|
|
1145
1153
|
| 'ProjectGroup'
|
|
1154
|
+
| 'ProjectOAuthConnection'
|
|
1146
1155
|
| 'ProjectPermission'
|
|
1147
1156
|
| 'ProjectResource'
|
|
1148
1157
|
| 'ProjectRole'
|
|
@@ -1512,6 +1521,12 @@ export type MutationResolvers<
|
|
|
1512
1521
|
ContextType,
|
|
1513
1522
|
RequireFields<Types.MutationClearProjectAppPictureArgs, 'input'>
|
|
1514
1523
|
>;
|
|
1524
|
+
clearProjectOAuthConnection?: Resolver<
|
|
1525
|
+
ResolversTypes['Boolean'],
|
|
1526
|
+
ParentType,
|
|
1527
|
+
ContextType,
|
|
1528
|
+
RequireFields<Types.MutationClearProjectOAuthConnectionArgs, 'input'>
|
|
1529
|
+
>;
|
|
1515
1530
|
clearProjectPicture?: Resolver<
|
|
1516
1531
|
ResolversTypes['Project'],
|
|
1517
1532
|
ParentType,
|
|
@@ -2030,6 +2045,12 @@ export type MutationResolvers<
|
|
|
2030
2045
|
ContextType,
|
|
2031
2046
|
RequireFields<Types.MutationUploadUserPictureArgs, 'input'>
|
|
2032
2047
|
>;
|
|
2048
|
+
upsertProjectOAuthConnection?: Resolver<
|
|
2049
|
+
ResolversTypes['ProjectOAuthConnection'],
|
|
2050
|
+
ParentType,
|
|
2051
|
+
ContextType,
|
|
2052
|
+
RequireFields<Types.MutationUpsertProjectOAuthConnectionArgs, 'input'>
|
|
2053
|
+
>;
|
|
2033
2054
|
verifyEmail?: Resolver<
|
|
2034
2055
|
ResolversTypes['VerifyEmailResponse'],
|
|
2035
2056
|
ParentType,
|
|
@@ -2568,6 +2589,22 @@ export type ProjectMembershipExportDataResolvers<
|
|
|
2568
2589
|
role?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
2569
2590
|
}>;
|
|
2570
2591
|
|
|
2592
|
+
export type ProjectOAuthConnectionResolvers<
|
|
2593
|
+
ContextType = any,
|
|
2594
|
+
ParentType extends ResolversParentTypes['ProjectOAuthConnection'] =
|
|
2595
|
+
ResolversParentTypes['ProjectOAuthConnection'],
|
|
2596
|
+
> = ResolversObject<{
|
|
2597
|
+
clientId?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
2598
|
+
createdAt?: Resolver<ResolversTypes['Date'], ParentType, ContextType>;
|
|
2599
|
+
deletedAt?: Resolver<Types.Maybe<ResolversTypes['Date']>, ParentType, ContextType>;
|
|
2600
|
+
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
|
|
2601
|
+
isConfigured?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
|
|
2602
|
+
projectId?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
|
|
2603
|
+
provider?: Resolver<ResolversTypes['ProjectOAuthConnectionProvider'], ParentType, ContextType>;
|
|
2604
|
+
updatedAt?: Resolver<ResolversTypes['Date'], ParentType, ContextType>;
|
|
2605
|
+
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
2606
|
+
}>;
|
|
2607
|
+
|
|
2571
2608
|
export type ProjectPageResolvers<
|
|
2572
2609
|
ContextType = any,
|
|
2573
2610
|
ParentType extends ResolversParentTypes['ProjectPage'] = ResolversParentTypes['ProjectPage'],
|
|
@@ -2883,6 +2920,12 @@ export type QueryResolvers<
|
|
|
2883
2920
|
ContextType,
|
|
2884
2921
|
RequireFields<Types.QueryProjectAppsArgs, 'scope'>
|
|
2885
2922
|
>;
|
|
2923
|
+
projectOAuthConnections?: Resolver<
|
|
2924
|
+
Array<ResolversTypes['ProjectOAuthConnection']>,
|
|
2925
|
+
ParentType,
|
|
2926
|
+
ContextType,
|
|
2927
|
+
RequireFields<Types.QueryProjectOAuthConnectionsArgs, 'scope'>
|
|
2928
|
+
>;
|
|
2886
2929
|
projectSyncJob?: Resolver<
|
|
2887
2930
|
ResolversTypes['ProjectSyncJob'],
|
|
2888
2931
|
ParentType,
|
|
@@ -3696,6 +3739,7 @@ export type Resolvers<ContextType = any> = ResolversObject<{
|
|
|
3696
3739
|
ProjectAppTag?: ProjectAppTagResolvers<ContextType>;
|
|
3697
3740
|
ProjectGroup?: ProjectGroupResolvers<ContextType>;
|
|
3698
3741
|
ProjectMembershipExportData?: ProjectMembershipExportDataResolvers<ContextType>;
|
|
3742
|
+
ProjectOAuthConnection?: ProjectOAuthConnectionResolvers<ContextType>;
|
|
3699
3743
|
ProjectPage?: ProjectPageResolvers<ContextType>;
|
|
3700
3744
|
ProjectPermission?: ProjectPermissionResolvers<ContextType>;
|
|
3701
3745
|
ProjectResource?: ProjectResourceResolvers<ContextType>;
|
|
@@ -488,6 +488,11 @@ export type ClearProjectAppPictureInput = {
|
|
|
488
488
|
scope: Scope;
|
|
489
489
|
};
|
|
490
490
|
|
|
491
|
+
export type ClearProjectOAuthConnectionInput = {
|
|
492
|
+
provider: ProjectOAuthConnectionProvider;
|
|
493
|
+
scope: Scope;
|
|
494
|
+
};
|
|
495
|
+
|
|
491
496
|
export type ClearProjectPictureInput = {
|
|
492
497
|
projectId: Scalars['ID']['input'];
|
|
493
498
|
scope: Scope;
|
|
@@ -1038,6 +1043,12 @@ export type Mutation = {
|
|
|
1038
1043
|
changeMyPassword: ChangeMyPasswordResult;
|
|
1039
1044
|
/** Clear the project-app logo. Does not delete the stored object. */
|
|
1040
1045
|
clearProjectAppPicture: ProjectApp;
|
|
1046
|
+
/**
|
|
1047
|
+
* Remove the project's GitHub or Google OAuth connection.
|
|
1048
|
+
* Ciphertext is wiped; the secret is never returned.
|
|
1049
|
+
* Requires Project Update on the scoped project.
|
|
1050
|
+
*/
|
|
1051
|
+
clearProjectOAuthConnection: Scalars['Boolean']['output'];
|
|
1041
1052
|
/** Clear the project logo. Does not delete the stored object. */
|
|
1042
1053
|
clearProjectPicture: Project;
|
|
1043
1054
|
/**
|
|
@@ -1254,6 +1265,12 @@ export type Mutation = {
|
|
|
1254
1265
|
/** Upload a project logo and persist its public URL. */
|
|
1255
1266
|
uploadProjectPicture: UploadProjectPictureResult;
|
|
1256
1267
|
uploadUserPicture: UploadUserPictureResult;
|
|
1268
|
+
/**
|
|
1269
|
+
* Create or replace the project's GitHub or Google OAuth connection.
|
|
1270
|
+
* The client secret is write-only and is never returned.
|
|
1271
|
+
* Requires Project Update on the scoped project.
|
|
1272
|
+
*/
|
|
1273
|
+
upsertProjectOAuthConnection: ProjectOAuthConnection;
|
|
1257
1274
|
verifyEmail: VerifyEmailResponse;
|
|
1258
1275
|
verifyMfa: MfaVerifyResponse;
|
|
1259
1276
|
verifyMfaRecoveryCode: MfaVerifyResponse;
|
|
@@ -1286,6 +1303,10 @@ export type MutationClearProjectAppPictureArgs = {
|
|
|
1286
1303
|
input: ClearProjectAppPictureInput;
|
|
1287
1304
|
};
|
|
1288
1305
|
|
|
1306
|
+
export type MutationClearProjectOAuthConnectionArgs = {
|
|
1307
|
+
input: ClearProjectOAuthConnectionInput;
|
|
1308
|
+
};
|
|
1309
|
+
|
|
1289
1310
|
export type MutationClearProjectPictureArgs = {
|
|
1290
1311
|
input: ClearProjectPictureInput;
|
|
1291
1312
|
};
|
|
@@ -1650,6 +1671,10 @@ export type MutationUploadUserPictureArgs = {
|
|
|
1650
1671
|
input: UploadUserPictureInput;
|
|
1651
1672
|
};
|
|
1652
1673
|
|
|
1674
|
+
export type MutationUpsertProjectOAuthConnectionArgs = {
|
|
1675
|
+
input: UpsertProjectOAuthConnectionInput;
|
|
1676
|
+
};
|
|
1677
|
+
|
|
1653
1678
|
export type MutationVerifyEmailArgs = {
|
|
1654
1679
|
input: VerifyEmailInput;
|
|
1655
1680
|
};
|
|
@@ -2180,6 +2205,33 @@ export type ProjectMembershipExportData = {
|
|
|
2180
2205
|
role: Scalars['String']['output'];
|
|
2181
2206
|
};
|
|
2182
2207
|
|
|
2208
|
+
/**
|
|
2209
|
+
* Per-project GitHub or Google OAuth app (Auth0-style connection).
|
|
2210
|
+
* The client secret is write-only and is never returned.
|
|
2211
|
+
*/
|
|
2212
|
+
export type ProjectOAuthConnection = Auditable & {
|
|
2213
|
+
__typename?: 'ProjectOAuthConnection';
|
|
2214
|
+
/** Public OAuth client id of the customer's GitHub or Google app. Not a secret. */
|
|
2215
|
+
clientId: Scalars['String']['output'];
|
|
2216
|
+
createdAt: Scalars['Date']['output'];
|
|
2217
|
+
deletedAt?: Maybe<Scalars['Date']['output']>;
|
|
2218
|
+
id: Scalars['ID']['output'];
|
|
2219
|
+
/** True when a BYO client secret is stored for this provider. The secret itself is never returned. */
|
|
2220
|
+
isConfigured: Scalars['Boolean']['output'];
|
|
2221
|
+
projectId: Scalars['ID']['output'];
|
|
2222
|
+
provider: ProjectOAuthConnectionProvider;
|
|
2223
|
+
updatedAt: Scalars['Date']['output'];
|
|
2224
|
+
};
|
|
2225
|
+
|
|
2226
|
+
/**
|
|
2227
|
+
* Social identity providers that can have a per-project OAuth connection.
|
|
2228
|
+
* Email magic-link is not a connection.
|
|
2229
|
+
*/
|
|
2230
|
+
export enum ProjectOAuthConnectionProvider {
|
|
2231
|
+
Github = 'github',
|
|
2232
|
+
Google = 'google',
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2183
2235
|
export type ProjectPage = PaginatedResults & {
|
|
2184
2236
|
__typename?: 'ProjectPage';
|
|
2185
2237
|
hasNextPage: Scalars['Boolean']['output'];
|
|
@@ -2420,6 +2472,12 @@ export type Query = {
|
|
|
2420
2472
|
permissions: PermissionPage;
|
|
2421
2473
|
/** List OAuth apps for the given project scope. Allowed scopes: accountProject, organizationProject. */
|
|
2422
2474
|
projectApps: ProjectAppPage;
|
|
2475
|
+
/**
|
|
2476
|
+
* List GitHub/Google OAuth connections for the project in `scope`.
|
|
2477
|
+
* Secrets and ciphertext are never returned.
|
|
2478
|
+
* Allowed scopes: accountProject, organizationProject.
|
|
2479
|
+
*/
|
|
2480
|
+
projectOAuthConnections: Array<ProjectOAuthConnection>;
|
|
2423
2481
|
/**
|
|
2424
2482
|
* Read the current state of a project CDM sync job. Use this to poll
|
|
2425
2483
|
* the lifecycle of a job started via `startProjectSync`.
|
|
@@ -2541,6 +2599,10 @@ export type QueryProjectAppsArgs = {
|
|
|
2541
2599
|
tagIds?: InputMaybe<Array<Scalars['ID']['input']>>;
|
|
2542
2600
|
};
|
|
2543
2601
|
|
|
2602
|
+
export type QueryProjectOAuthConnectionsArgs = {
|
|
2603
|
+
scope: Scope;
|
|
2604
|
+
};
|
|
2605
|
+
|
|
2544
2606
|
export type QueryProjectSyncJobArgs = {
|
|
2545
2607
|
id: Scalars['ID']['input'];
|
|
2546
2608
|
jobId: Scalars['ID']['input'];
|
|
@@ -3853,6 +3915,15 @@ export type UploadUserPictureResult = {
|
|
|
3853
3915
|
url: Scalars['String']['output'];
|
|
3854
3916
|
};
|
|
3855
3917
|
|
|
3918
|
+
export type UpsertProjectOAuthConnectionInput = {
|
|
3919
|
+
/** Public OAuth client id of the customer's GitHub or Google app. */
|
|
3920
|
+
clientId: Scalars['String']['input'];
|
|
3921
|
+
/** OAuth client secret. Write-only; never returned on the connection type or in logs. */
|
|
3922
|
+
clientSecret: Scalars['String']['input'];
|
|
3923
|
+
provider: ProjectOAuthConnectionProvider;
|
|
3924
|
+
scope: Scope;
|
|
3925
|
+
};
|
|
3926
|
+
|
|
3856
3927
|
export type User = Auditable & {
|
|
3857
3928
|
__typename?: 'User';
|
|
3858
3929
|
accounts?: Maybe<Array<Account>>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { parse, validate } from 'graphql';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { buildMergedSchema, operationFiles, readAll } from './test-support/sdl-fixture';
|
|
5
|
+
|
|
6
|
+
const SECRET_FIELD = /secret|encrypted|ciphertext|^iv$/i;
|
|
7
|
+
|
|
8
|
+
describe('ProjectOAuthConnection public types', () => {
|
|
9
|
+
const schema = buildMergedSchema();
|
|
10
|
+
|
|
11
|
+
it('does not expose secrets on the connection output type', () => {
|
|
12
|
+
const connection = schema.getType('ProjectOAuthConnection');
|
|
13
|
+
expect(connection).toBeDefined();
|
|
14
|
+
expect(connection?.astNode?.kind).toBe('ObjectTypeDefinition');
|
|
15
|
+
const fields =
|
|
16
|
+
connection && 'getFields' in connection ? Object.keys(connection.getFields()) : [];
|
|
17
|
+
|
|
18
|
+
expect(fields).toEqual(
|
|
19
|
+
expect.arrayContaining([
|
|
20
|
+
'id',
|
|
21
|
+
'projectId',
|
|
22
|
+
'provider',
|
|
23
|
+
'clientId',
|
|
24
|
+
'isConfigured',
|
|
25
|
+
'createdAt',
|
|
26
|
+
'updatedAt',
|
|
27
|
+
])
|
|
28
|
+
);
|
|
29
|
+
expect(fields.filter((name) => SECRET_FIELD.test(name))).toEqual([]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('accepts the client secret only as a write-only upsert input', () => {
|
|
33
|
+
const input = schema.getType('UpsertProjectOAuthConnectionInput');
|
|
34
|
+
expect(input).toBeDefined();
|
|
35
|
+
const fields = input && 'getFields' in input ? Object.keys(input.getFields()) : [];
|
|
36
|
+
|
|
37
|
+
expect(fields).toEqual(
|
|
38
|
+
expect.arrayContaining(['scope', 'provider', 'clientId', 'clientSecret'])
|
|
39
|
+
);
|
|
40
|
+
expect(schema.getType('ClearProjectOAuthConnectionInput')).toBeDefined();
|
|
41
|
+
expect(schema.getQueryType()?.getFields().projectOAuthConnections).toBeDefined();
|
|
42
|
+
expect(schema.getMutationType()?.getFields().upsertProjectOAuthConnection).toBeDefined();
|
|
43
|
+
expect(schema.getMutationType()?.getFields().clearProjectOAuthConnection).toBeDefined();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('keeps operation documents from selecting secret fields', () => {
|
|
47
|
+
const files = operationFiles().filter((file) => file.includes('project-oauth-connections'));
|
|
48
|
+
expect(files.length).toBe(3);
|
|
49
|
+
|
|
50
|
+
for (const file of files) {
|
|
51
|
+
const errors = validate(schema, parse(readAll([file])));
|
|
52
|
+
expect(errors.map((e) => e.message)).toEqual([]);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const documents = readAll(files);
|
|
56
|
+
expect(documents).not.toMatch(/\bclientSecret\b/);
|
|
57
|
+
expect(documents).not.toMatch(/\bencryptedSecret\b/);
|
|
58
|
+
expect(documents).not.toMatch(/\bsecretIv\b/);
|
|
59
|
+
expect(documents).not.toMatch(/\bsecretTag\b/);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
|
+
import type { ProjectAppPublicInfo } from './project-oauth.types';
|
|
3
4
|
import { isProjectOAuthThemeMode } from './project-oauth.types';
|
|
4
5
|
|
|
5
6
|
describe('isProjectOAuthThemeMode', () => {
|
|
@@ -16,3 +17,23 @@ describe('isProjectOAuthThemeMode', () => {
|
|
|
16
17
|
expect(isProjectOAuthThemeMode('DARK')).toBe(false);
|
|
17
18
|
});
|
|
18
19
|
});
|
|
20
|
+
|
|
21
|
+
const SECRET_FIELD = /secret|encrypted|ciphertext|^iv$/i;
|
|
22
|
+
|
|
23
|
+
describe('ProjectAppPublicInfo', () => {
|
|
24
|
+
it('does not declare secret or ciphertext fields', () => {
|
|
25
|
+
const sample: ProjectAppPublicInfo = {
|
|
26
|
+
name: null,
|
|
27
|
+
projectName: null,
|
|
28
|
+
pictureUrl: null,
|
|
29
|
+
primaryColor: null,
|
|
30
|
+
showHelpPanel: true,
|
|
31
|
+
themeMode: null,
|
|
32
|
+
enabledProviders: ['github'],
|
|
33
|
+
configuredProviders: ['github'],
|
|
34
|
+
scopes: [],
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
expect(Object.keys(sample).filter((key) => SECRET_FIELD.test(key))).toEqual([]);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -29,6 +29,11 @@ export interface ProjectAppPublicInfo {
|
|
|
29
29
|
showHelpPanel: boolean;
|
|
30
30
|
themeMode: ProjectOAuthThemeMode | null;
|
|
31
31
|
enabledProviders: string[] | null;
|
|
32
|
+
/**
|
|
33
|
+
* Social providers this project can offer (BYO connection and/or platform fallback).
|
|
34
|
+
* Hosted sign-in uses this instead of GET /api/auth/providers.
|
|
35
|
+
*/
|
|
36
|
+
configuredProviders?: string[];
|
|
32
37
|
scopes: ProjectAppScopeInfo[];
|
|
33
38
|
}
|
|
34
39
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
input UpsertProjectOAuthConnectionInput {
|
|
2
|
+
scope: Scope!
|
|
3
|
+
provider: ProjectOAuthConnectionProvider!
|
|
4
|
+
"""
|
|
5
|
+
Public OAuth client id of the customer's GitHub or Google app.
|
|
6
|
+
"""
|
|
7
|
+
clientId: String!
|
|
8
|
+
"""
|
|
9
|
+
OAuth client secret. Write-only; never returned on the connection type or in logs.
|
|
10
|
+
"""
|
|
11
|
+
clientSecret: String!
|
|
12
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
extend type Mutation {
|
|
2
|
+
"""
|
|
3
|
+
Remove the project's GitHub or Google OAuth connection.
|
|
4
|
+
Ciphertext is wiped; the secret is never returned.
|
|
5
|
+
Requires Project Update on the scoped project.
|
|
6
|
+
"""
|
|
7
|
+
clearProjectOAuthConnection(input: ClearProjectOAuthConnectionInput!): Boolean!
|
|
8
|
+
}
|
package/src/schema/project-oauth-connections/mutations/upsert-project-oauth-connection.graphql
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
extend type Mutation {
|
|
2
|
+
"""
|
|
3
|
+
Create or replace the project's GitHub or Google OAuth connection.
|
|
4
|
+
The client secret is write-only and is never returned.
|
|
5
|
+
Requires Project Update on the scoped project.
|
|
6
|
+
"""
|
|
7
|
+
upsertProjectOAuthConnection(input: UpsertProjectOAuthConnectionInput!): ProjectOAuthConnection!
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
extend type Query {
|
|
2
|
+
"""
|
|
3
|
+
List GitHub/Google OAuth connections for the project in `scope`.
|
|
4
|
+
Secrets and ciphertext are never returned.
|
|
5
|
+
Allowed scopes: accountProject, organizationProject.
|
|
6
|
+
"""
|
|
7
|
+
projectOAuthConnections(scope: Scope!): [ProjectOAuthConnection!]!
|
|
8
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Per-project GitHub or Google OAuth app (Auth0-style connection).
|
|
3
|
+
The client secret is write-only and is never returned.
|
|
4
|
+
"""
|
|
5
|
+
type ProjectOAuthConnection implements Auditable {
|
|
6
|
+
id: ID!
|
|
7
|
+
projectId: ID!
|
|
8
|
+
provider: ProjectOAuthConnectionProvider!
|
|
9
|
+
"""
|
|
10
|
+
Public OAuth client id of the customer's GitHub or Google app. Not a secret.
|
|
11
|
+
"""
|
|
12
|
+
clientId: String!
|
|
13
|
+
"""
|
|
14
|
+
True when a BYO client secret is stored for this provider. The secret itself is never returned.
|
|
15
|
+
"""
|
|
16
|
+
isConfigured: Boolean!
|
|
17
|
+
createdAt: Date!
|
|
18
|
+
updatedAt: Date!
|
|
19
|
+
deletedAt: Date
|
|
20
|
+
}
|
package/src/sdl-contract.test.ts
CHANGED
|
@@ -48,10 +48,11 @@ describe('operation documents', () => {
|
|
|
48
48
|
// 124 after slice 17b: organization request/confirm (the last upload target).
|
|
49
49
|
// 132 after project branding: request/confirm/upload/clear for project and
|
|
50
50
|
// project-app pictures (eight operation documents).
|
|
51
|
+
// 135 after project OAuth connections: get/upsert/clear (three operation documents).
|
|
51
52
|
// Updating this number is the point of the pin, not a nuisance: every change
|
|
52
53
|
// to it should be a line in a commit message.
|
|
53
54
|
it('finds every document under src/operations', () => {
|
|
54
|
-
expect(files).toHaveLength(
|
|
55
|
+
expect(files).toHaveLength(135);
|
|
55
56
|
});
|
|
56
57
|
|
|
57
58
|
it.each(files.map((f) => [relative(process.cwd(), f), f]))('%s validates', (_label, file) => {
|