@grantjs/schema 1.18.11 → 1.20.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 +5 -0
- package/src/generated/graphql.ts +204 -0
- package/src/generated/resolvers.ts +82 -0
- package/src/generated/schema-types.ts +119 -0
- package/src/operations/project-users/exportProjectUserCredentials.graphql +11 -0
- package/src/operations/users/setProjectUserEmail.graphql +9 -0
- package/src/operations/users/setProjectUserPassword.graphql +9 -0
- package/src/schema/project-users/inputs/export-project-user-credentials.graphql +8 -0
- package/src/schema/project-users/queries/export-project-user-credentials.graphql +12 -0
- package/src/schema/project-users/types/credential-kind.graphql +8 -0
- package/src/schema/project-users/types/project-user-credential-export.graphql +22 -0
- package/src/schema/project-users/types/project-user-password-credential.graphql +14 -0
- package/src/schema/users/inputs/create-user.graphql +5 -0
- package/src/schema/users/inputs/set-project-user-email.graphql +9 -0
- package/src/schema/users/inputs/set-project-user-password.graphql +9 -0
- package/src/schema/users/mutations/set-project-user-email.graphql +7 -0
- package/src/schema/users/mutations/set-project-user-password.graphql +10 -0
- package/src/schema/users/types/user.graphql +7 -0
- package/src/sdl-contract.test.ts +10 -2
package/package.json
CHANGED
|
@@ -151,6 +151,8 @@ export const EVENT_TYPES = [
|
|
|
151
151
|
'user.updated',
|
|
152
152
|
'user.deleted',
|
|
153
153
|
'project.user_updated',
|
|
154
|
+
'project.user_email_changed',
|
|
155
|
+
'project.user_password_set',
|
|
154
156
|
'api_key.deleted',
|
|
155
157
|
'tag.created',
|
|
156
158
|
'tag.updated',
|
|
@@ -226,6 +228,9 @@ export const EVENT_CATALOG: Readonly<Record<EventType, EventCatalogEntry>> = {
|
|
|
226
228
|
'user.updated': webhookOnly('membership'),
|
|
227
229
|
'user.deleted': webhookOnly('membership'),
|
|
228
230
|
'project.user_updated': webhookOnly('membership'),
|
|
231
|
+
'project.user_email_changed': webhookOnly('membership'),
|
|
232
|
+
// Every project-credential write that changes the stored hash, any source. data.after = { projectId, userId, source }: never a hash or a password.
|
|
233
|
+
'project.user_password_set': webhookOnly('membership'),
|
|
229
234
|
'api_key.deleted': webhookOnly('security'),
|
|
230
235
|
'tag.created': webhookOnly('iam'),
|
|
231
236
|
'tag.updated': webhookOnly('iam'),
|
package/src/generated/graphql.ts
CHANGED
|
@@ -1310,6 +1310,16 @@ export type UpsertProjectOAuthConnectionMutation = {
|
|
|
1310
1310
|
};
|
|
1311
1311
|
};
|
|
1312
1312
|
|
|
1313
|
+
export type ExportProjectUserCredentialsQueryVariables = Exact<{
|
|
1314
|
+
input: Types.ExportProjectUserCredentialsInput;
|
|
1315
|
+
}>;
|
|
1316
|
+
|
|
1317
|
+
export type ExportProjectUserCredentialsQuery = {
|
|
1318
|
+
exportProjectUserCredentials: {
|
|
1319
|
+
users: Array<{ userId: string; password: { algorithm: string; hash: string } | null }>;
|
|
1320
|
+
};
|
|
1321
|
+
};
|
|
1322
|
+
|
|
1313
1323
|
export type CancelProjectSyncMutationVariables = Exact<{
|
|
1314
1324
|
id: string | number;
|
|
1315
1325
|
scope: Types.Scope;
|
|
@@ -2174,6 +2184,34 @@ export type GetUsersListQuery = {
|
|
|
2174
2184
|
};
|
|
2175
2185
|
};
|
|
2176
2186
|
|
|
2187
|
+
export type SetProjectUserEmailMutationVariables = Exact<{
|
|
2188
|
+
input: Types.SetProjectUserEmailInput;
|
|
2189
|
+
}>;
|
|
2190
|
+
|
|
2191
|
+
export type SetProjectUserEmailMutation = {
|
|
2192
|
+
setProjectUserEmail: {
|
|
2193
|
+
id: string;
|
|
2194
|
+
name: string;
|
|
2195
|
+
metadata: Record<string, unknown>;
|
|
2196
|
+
createdAt: Date;
|
|
2197
|
+
updatedAt: Date;
|
|
2198
|
+
};
|
|
2199
|
+
};
|
|
2200
|
+
|
|
2201
|
+
export type SetProjectUserPasswordMutationVariables = Exact<{
|
|
2202
|
+
input: Types.SetProjectUserPasswordInput;
|
|
2203
|
+
}>;
|
|
2204
|
+
|
|
2205
|
+
export type SetProjectUserPasswordMutation = {
|
|
2206
|
+
setProjectUserPassword: {
|
|
2207
|
+
id: string;
|
|
2208
|
+
name: string;
|
|
2209
|
+
metadata: Record<string, unknown>;
|
|
2210
|
+
createdAt: Date;
|
|
2211
|
+
updatedAt: Date;
|
|
2212
|
+
};
|
|
2213
|
+
};
|
|
2214
|
+
|
|
2177
2215
|
export type UpdateUserMutationVariables = Exact<{
|
|
2178
2216
|
id: string | number;
|
|
2179
2217
|
input: Types.UpdateUserInput;
|
|
@@ -7453,6 +7491,74 @@ export const UpsertProjectOAuthConnectionDocument = {
|
|
|
7453
7491
|
UpsertProjectOAuthConnectionMutation,
|
|
7454
7492
|
UpsertProjectOAuthConnectionMutationVariables
|
|
7455
7493
|
>;
|
|
7494
|
+
export const ExportProjectUserCredentialsDocument = {
|
|
7495
|
+
kind: 'Document',
|
|
7496
|
+
definitions: [
|
|
7497
|
+
{
|
|
7498
|
+
kind: 'OperationDefinition',
|
|
7499
|
+
operation: 'query',
|
|
7500
|
+
name: { kind: 'Name', value: 'ExportProjectUserCredentials' },
|
|
7501
|
+
variableDefinitions: [
|
|
7502
|
+
{
|
|
7503
|
+
kind: 'VariableDefinition',
|
|
7504
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
7505
|
+
type: {
|
|
7506
|
+
kind: 'NonNullType',
|
|
7507
|
+
type: {
|
|
7508
|
+
kind: 'NamedType',
|
|
7509
|
+
name: { kind: 'Name', value: 'ExportProjectUserCredentialsInput' },
|
|
7510
|
+
},
|
|
7511
|
+
},
|
|
7512
|
+
},
|
|
7513
|
+
],
|
|
7514
|
+
selectionSet: {
|
|
7515
|
+
kind: 'SelectionSet',
|
|
7516
|
+
selections: [
|
|
7517
|
+
{
|
|
7518
|
+
kind: 'Field',
|
|
7519
|
+
name: { kind: 'Name', value: 'exportProjectUserCredentials' },
|
|
7520
|
+
arguments: [
|
|
7521
|
+
{
|
|
7522
|
+
kind: 'Argument',
|
|
7523
|
+
name: { kind: 'Name', value: 'input' },
|
|
7524
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
7525
|
+
},
|
|
7526
|
+
],
|
|
7527
|
+
selectionSet: {
|
|
7528
|
+
kind: 'SelectionSet',
|
|
7529
|
+
selections: [
|
|
7530
|
+
{
|
|
7531
|
+
kind: 'Field',
|
|
7532
|
+
name: { kind: 'Name', value: 'users' },
|
|
7533
|
+
selectionSet: {
|
|
7534
|
+
kind: 'SelectionSet',
|
|
7535
|
+
selections: [
|
|
7536
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'userId' } },
|
|
7537
|
+
{
|
|
7538
|
+
kind: 'Field',
|
|
7539
|
+
name: { kind: 'Name', value: 'password' },
|
|
7540
|
+
selectionSet: {
|
|
7541
|
+
kind: 'SelectionSet',
|
|
7542
|
+
selections: [
|
|
7543
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'algorithm' } },
|
|
7544
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'hash' } },
|
|
7545
|
+
],
|
|
7546
|
+
},
|
|
7547
|
+
},
|
|
7548
|
+
],
|
|
7549
|
+
},
|
|
7550
|
+
},
|
|
7551
|
+
],
|
|
7552
|
+
},
|
|
7553
|
+
},
|
|
7554
|
+
],
|
|
7555
|
+
},
|
|
7556
|
+
},
|
|
7557
|
+
],
|
|
7558
|
+
} as unknown as DocumentNode<
|
|
7559
|
+
ExportProjectUserCredentialsQuery,
|
|
7560
|
+
ExportProjectUserCredentialsQueryVariables
|
|
7561
|
+
>;
|
|
7456
7562
|
export const CancelProjectSyncDocument = {
|
|
7457
7563
|
kind: 'Document',
|
|
7458
7564
|
definitions: [
|
|
@@ -11155,6 +11261,104 @@ export const GetUsersListDocument = {
|
|
|
11155
11261
|
},
|
|
11156
11262
|
],
|
|
11157
11263
|
} as unknown as DocumentNode<GetUsersListQuery, GetUsersListQueryVariables>;
|
|
11264
|
+
export const SetProjectUserEmailDocument = {
|
|
11265
|
+
kind: 'Document',
|
|
11266
|
+
definitions: [
|
|
11267
|
+
{
|
|
11268
|
+
kind: 'OperationDefinition',
|
|
11269
|
+
operation: 'mutation',
|
|
11270
|
+
name: { kind: 'Name', value: 'SetProjectUserEmail' },
|
|
11271
|
+
variableDefinitions: [
|
|
11272
|
+
{
|
|
11273
|
+
kind: 'VariableDefinition',
|
|
11274
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
11275
|
+
type: {
|
|
11276
|
+
kind: 'NonNullType',
|
|
11277
|
+
type: { kind: 'NamedType', name: { kind: 'Name', value: 'SetProjectUserEmailInput' } },
|
|
11278
|
+
},
|
|
11279
|
+
},
|
|
11280
|
+
],
|
|
11281
|
+
selectionSet: {
|
|
11282
|
+
kind: 'SelectionSet',
|
|
11283
|
+
selections: [
|
|
11284
|
+
{
|
|
11285
|
+
kind: 'Field',
|
|
11286
|
+
name: { kind: 'Name', value: 'setProjectUserEmail' },
|
|
11287
|
+
arguments: [
|
|
11288
|
+
{
|
|
11289
|
+
kind: 'Argument',
|
|
11290
|
+
name: { kind: 'Name', value: 'input' },
|
|
11291
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
11292
|
+
},
|
|
11293
|
+
],
|
|
11294
|
+
selectionSet: {
|
|
11295
|
+
kind: 'SelectionSet',
|
|
11296
|
+
selections: [
|
|
11297
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
11298
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
11299
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'metadata' } },
|
|
11300
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'createdAt' } },
|
|
11301
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'updatedAt' } },
|
|
11302
|
+
],
|
|
11303
|
+
},
|
|
11304
|
+
},
|
|
11305
|
+
],
|
|
11306
|
+
},
|
|
11307
|
+
},
|
|
11308
|
+
],
|
|
11309
|
+
} as unknown as DocumentNode<SetProjectUserEmailMutation, SetProjectUserEmailMutationVariables>;
|
|
11310
|
+
export const SetProjectUserPasswordDocument = {
|
|
11311
|
+
kind: 'Document',
|
|
11312
|
+
definitions: [
|
|
11313
|
+
{
|
|
11314
|
+
kind: 'OperationDefinition',
|
|
11315
|
+
operation: 'mutation',
|
|
11316
|
+
name: { kind: 'Name', value: 'SetProjectUserPassword' },
|
|
11317
|
+
variableDefinitions: [
|
|
11318
|
+
{
|
|
11319
|
+
kind: 'VariableDefinition',
|
|
11320
|
+
variable: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
11321
|
+
type: {
|
|
11322
|
+
kind: 'NonNullType',
|
|
11323
|
+
type: {
|
|
11324
|
+
kind: 'NamedType',
|
|
11325
|
+
name: { kind: 'Name', value: 'SetProjectUserPasswordInput' },
|
|
11326
|
+
},
|
|
11327
|
+
},
|
|
11328
|
+
},
|
|
11329
|
+
],
|
|
11330
|
+
selectionSet: {
|
|
11331
|
+
kind: 'SelectionSet',
|
|
11332
|
+
selections: [
|
|
11333
|
+
{
|
|
11334
|
+
kind: 'Field',
|
|
11335
|
+
name: { kind: 'Name', value: 'setProjectUserPassword' },
|
|
11336
|
+
arguments: [
|
|
11337
|
+
{
|
|
11338
|
+
kind: 'Argument',
|
|
11339
|
+
name: { kind: 'Name', value: 'input' },
|
|
11340
|
+
value: { kind: 'Variable', name: { kind: 'Name', value: 'input' } },
|
|
11341
|
+
},
|
|
11342
|
+
],
|
|
11343
|
+
selectionSet: {
|
|
11344
|
+
kind: 'SelectionSet',
|
|
11345
|
+
selections: [
|
|
11346
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
|
|
11347
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'name' } },
|
|
11348
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'metadata' } },
|
|
11349
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'createdAt' } },
|
|
11350
|
+
{ kind: 'Field', name: { kind: 'Name', value: 'updatedAt' } },
|
|
11351
|
+
],
|
|
11352
|
+
},
|
|
11353
|
+
},
|
|
11354
|
+
],
|
|
11355
|
+
},
|
|
11356
|
+
},
|
|
11357
|
+
],
|
|
11358
|
+
} as unknown as DocumentNode<
|
|
11359
|
+
SetProjectUserPasswordMutation,
|
|
11360
|
+
SetProjectUserPasswordMutationVariables
|
|
11361
|
+
>;
|
|
11158
11362
|
export const UpdateUserDocument = {
|
|
11159
11363
|
kind: 'Document',
|
|
11160
11364
|
definitions: [
|
|
@@ -271,6 +271,7 @@ export type ResolversTypes = ResolversObject<{
|
|
|
271
271
|
CreateUserSessionInput: Types.CreateUserSessionInput;
|
|
272
272
|
CreateWebhookSubscriptionMutationInput: Types.CreateWebhookSubscriptionMutationInput;
|
|
273
273
|
CredentialExportData: ResolverTypeWrapper<Types.CredentialExportData>;
|
|
274
|
+
CredentialKind: Types.CredentialKind;
|
|
274
275
|
Date: ResolverTypeWrapper<Types.Scalars['Date']['output']>;
|
|
275
276
|
DeleteApiKeyInput: Types.DeleteApiKeyInput;
|
|
276
277
|
DeleteMyAccountsInput: Types.DeleteMyAccountsInput;
|
|
@@ -281,6 +282,9 @@ export type ResolversTypes = ResolversObject<{
|
|
|
281
282
|
EmailVerificationProofType: Types.EmailVerificationProofType;
|
|
282
283
|
ExchangeApiKeyInput: Types.ExchangeApiKeyInput;
|
|
283
284
|
ExchangeApiKeyResult: ResolverTypeWrapper<Types.ExchangeApiKeyResult>;
|
|
285
|
+
ExportProjectUserCredentialsInput: Types.ExportProjectUserCredentialsInput;
|
|
286
|
+
ExportedPasswordCredential: ResolverTypeWrapper<Types.ExportedPasswordCredential>;
|
|
287
|
+
ExportedProjectUserCredential: ResolverTypeWrapper<Types.ExportedProjectUserCredential>;
|
|
284
288
|
GenerateMyMfaRecoveryCodesInput: Types.GenerateMyMfaRecoveryCodesInput;
|
|
285
289
|
GetUserAuthenticationMethodsInput: Types.GetUserAuthenticationMethodsInput;
|
|
286
290
|
GetUserSessionsInput: Types.GetUserSessionsInput;
|
|
@@ -385,7 +389,9 @@ export type ResolversTypes = ResolversObject<{
|
|
|
385
389
|
ProjectTag: ResolverTypeWrapper<Types.ProjectTag>;
|
|
386
390
|
ProjectUser: ResolverTypeWrapper<Types.ProjectUser>;
|
|
387
391
|
ProjectUserApiKey: ResolverTypeWrapper<Types.ProjectUserApiKey>;
|
|
392
|
+
ProjectUserCredentialExport: ResolverTypeWrapper<Types.ProjectUserCredentialExport>;
|
|
388
393
|
ProjectUserGroup: ResolverTypeWrapper<Types.ProjectUserGroup>;
|
|
394
|
+
ProjectUserPasswordCredential: ResolverTypeWrapper<Types.ProjectUserPasswordCredential>;
|
|
389
395
|
ProjectUserPermission: ResolverTypeWrapper<Types.ProjectUserPermission>;
|
|
390
396
|
Query: ResolverTypeWrapper<Record<PropertyKey, never>>;
|
|
391
397
|
QueryAccountProjectApiKeysInput: Types.QueryAccountProjectApiKeysInput;
|
|
@@ -501,6 +507,8 @@ export type ResolversTypes = ResolversObject<{
|
|
|
501
507
|
SessionExportData: ResolverTypeWrapper<Types.SessionExportData>;
|
|
502
508
|
SetMyNotificationPreferenceInput: Types.SetMyNotificationPreferenceInput;
|
|
503
509
|
SetMyPrimaryMfaDeviceInput: Types.SetMyPrimaryMfaDeviceInput;
|
|
510
|
+
SetProjectUserEmailInput: Types.SetProjectUserEmailInput;
|
|
511
|
+
SetProjectUserPasswordInput: Types.SetProjectUserPasswordInput;
|
|
504
512
|
SigningKey: ResolverTypeWrapper<Types.SigningKey>;
|
|
505
513
|
SortOrder: Types.SortOrder;
|
|
506
514
|
StartProjectExportInput: Types.StartProjectExportInput;
|
|
@@ -691,6 +699,9 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
691
699
|
EmailVerificationProofInput: Types.EmailVerificationProofInput;
|
|
692
700
|
ExchangeApiKeyInput: Types.ExchangeApiKeyInput;
|
|
693
701
|
ExchangeApiKeyResult: Types.ExchangeApiKeyResult;
|
|
702
|
+
ExportProjectUserCredentialsInput: Types.ExportProjectUserCredentialsInput;
|
|
703
|
+
ExportedPasswordCredential: Types.ExportedPasswordCredential;
|
|
704
|
+
ExportedProjectUserCredential: Types.ExportedProjectUserCredential;
|
|
694
705
|
GenerateMyMfaRecoveryCodesInput: Types.GenerateMyMfaRecoveryCodesInput;
|
|
695
706
|
GetUserAuthenticationMethodsInput: Types.GetUserAuthenticationMethodsInput;
|
|
696
707
|
GetUserSessionsInput: Types.GetUserSessionsInput;
|
|
@@ -771,7 +782,9 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
771
782
|
ProjectTag: Types.ProjectTag;
|
|
772
783
|
ProjectUser: Types.ProjectUser;
|
|
773
784
|
ProjectUserApiKey: Types.ProjectUserApiKey;
|
|
785
|
+
ProjectUserCredentialExport: Types.ProjectUserCredentialExport;
|
|
774
786
|
ProjectUserGroup: Types.ProjectUserGroup;
|
|
787
|
+
ProjectUserPasswordCredential: Types.ProjectUserPasswordCredential;
|
|
775
788
|
ProjectUserPermission: Types.ProjectUserPermission;
|
|
776
789
|
Query: Record<PropertyKey, never>;
|
|
777
790
|
QueryAccountProjectApiKeysInput: Types.QueryAccountProjectApiKeysInput;
|
|
@@ -883,6 +896,8 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
883
896
|
SessionExportData: Types.SessionExportData;
|
|
884
897
|
SetMyNotificationPreferenceInput: Types.SetMyNotificationPreferenceInput;
|
|
885
898
|
SetMyPrimaryMfaDeviceInput: Types.SetMyPrimaryMfaDeviceInput;
|
|
899
|
+
SetProjectUserEmailInput: Types.SetProjectUserEmailInput;
|
|
900
|
+
SetProjectUserPasswordInput: Types.SetProjectUserPasswordInput;
|
|
886
901
|
SigningKey: Types.SigningKey;
|
|
887
902
|
StartProjectExportInput: Types.StartProjectExportInput;
|
|
888
903
|
String: Types.Scalars['String']['output'];
|
|
@@ -1323,6 +1338,28 @@ export type ExchangeApiKeyResultResolvers<
|
|
|
1323
1338
|
expiresIn?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
|
1324
1339
|
}>;
|
|
1325
1340
|
|
|
1341
|
+
export type ExportedPasswordCredentialResolvers<
|
|
1342
|
+
ContextType = any,
|
|
1343
|
+
ParentType extends ResolversParentTypes['ExportedPasswordCredential'] =
|
|
1344
|
+
ResolversParentTypes['ExportedPasswordCredential'],
|
|
1345
|
+
> = ResolversObject<{
|
|
1346
|
+
algorithm?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
1347
|
+
hash?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
1348
|
+
}>;
|
|
1349
|
+
|
|
1350
|
+
export type ExportedProjectUserCredentialResolvers<
|
|
1351
|
+
ContextType = any,
|
|
1352
|
+
ParentType extends ResolversParentTypes['ExportedProjectUserCredential'] =
|
|
1353
|
+
ResolversParentTypes['ExportedProjectUserCredential'],
|
|
1354
|
+
> = ResolversObject<{
|
|
1355
|
+
password?: Resolver<
|
|
1356
|
+
Types.Maybe<ResolversTypes['ExportedPasswordCredential']>,
|
|
1357
|
+
ParentType,
|
|
1358
|
+
ContextType
|
|
1359
|
+
>;
|
|
1360
|
+
userId?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
|
|
1361
|
+
}>;
|
|
1362
|
+
|
|
1326
1363
|
export type GroupResolvers<
|
|
1327
1364
|
ContextType = any,
|
|
1328
1365
|
ParentType extends ResolversParentTypes['Group'] = ResolversParentTypes['Group'],
|
|
@@ -1960,6 +1997,18 @@ export type MutationResolvers<
|
|
|
1960
1997
|
ContextType,
|
|
1961
1998
|
RequireFields<Types.MutationSetMyPrimaryMfaDeviceArgs, 'input'>
|
|
1962
1999
|
>;
|
|
2000
|
+
setProjectUserEmail?: Resolver<
|
|
2001
|
+
ResolversTypes['User'],
|
|
2002
|
+
ParentType,
|
|
2003
|
+
ContextType,
|
|
2004
|
+
RequireFields<Types.MutationSetProjectUserEmailArgs, 'input'>
|
|
2005
|
+
>;
|
|
2006
|
+
setProjectUserPassword?: Resolver<
|
|
2007
|
+
ResolversTypes['User'],
|
|
2008
|
+
ParentType,
|
|
2009
|
+
ContextType,
|
|
2010
|
+
RequireFields<Types.MutationSetProjectUserPasswordArgs, 'input'>
|
|
2011
|
+
>;
|
|
1963
2012
|
setupMfa?: Resolver<ResolversTypes['MfaSetupResponse'], ParentType, ContextType>;
|
|
1964
2013
|
startProjectExport?: Resolver<
|
|
1965
2014
|
ResolversTypes['ProjectSyncJob'],
|
|
@@ -2838,6 +2887,14 @@ export type ProjectUserApiKeyResolvers<
|
|
|
2838
2887
|
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
2839
2888
|
}>;
|
|
2840
2889
|
|
|
2890
|
+
export type ProjectUserCredentialExportResolvers<
|
|
2891
|
+
ContextType = any,
|
|
2892
|
+
ParentType extends ResolversParentTypes['ProjectUserCredentialExport'] =
|
|
2893
|
+
ResolversParentTypes['ProjectUserCredentialExport'],
|
|
2894
|
+
> = ResolversObject<{
|
|
2895
|
+
users?: Resolver<Array<ResolversTypes['ExportedProjectUserCredential']>, ParentType, ContextType>;
|
|
2896
|
+
}>;
|
|
2897
|
+
|
|
2841
2898
|
export type ProjectUserGroupResolvers<
|
|
2842
2899
|
ContextType = any,
|
|
2843
2900
|
ParentType extends ResolversParentTypes['ProjectUserGroup'] =
|
|
@@ -2853,6 +2910,16 @@ export type ProjectUserGroupResolvers<
|
|
|
2853
2910
|
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
2854
2911
|
}>;
|
|
2855
2912
|
|
|
2913
|
+
export type ProjectUserPasswordCredentialResolvers<
|
|
2914
|
+
ContextType = any,
|
|
2915
|
+
ParentType extends ResolversParentTypes['ProjectUserPasswordCredential'] =
|
|
2916
|
+
ResolversParentTypes['ProjectUserPasswordCredential'],
|
|
2917
|
+
> = ResolversObject<{
|
|
2918
|
+
fingerprint?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
2919
|
+
source?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
2920
|
+
updatedAt?: Resolver<ResolversTypes['Date'], ParentType, ContextType>;
|
|
2921
|
+
}>;
|
|
2922
|
+
|
|
2856
2923
|
export type ProjectUserPermissionResolvers<
|
|
2857
2924
|
ContextType = any,
|
|
2858
2925
|
ParentType extends ResolversParentTypes['ProjectUserPermission'] =
|
|
@@ -2880,6 +2947,12 @@ export type QueryResolvers<
|
|
|
2880
2947
|
RequireFields<Types.QueryApiKeysArgs, 'scope'>
|
|
2881
2948
|
>;
|
|
2882
2949
|
authSignupPolicy?: Resolver<ResolversTypes['AuthSignupPolicy'], ParentType, ContextType>;
|
|
2950
|
+
exportProjectUserCredentials?: Resolver<
|
|
2951
|
+
ResolversTypes['ProjectUserCredentialExport'],
|
|
2952
|
+
ParentType,
|
|
2953
|
+
ContextType,
|
|
2954
|
+
RequireFields<Types.QueryExportProjectUserCredentialsArgs, 'input'>
|
|
2955
|
+
>;
|
|
2883
2956
|
groups?: Resolver<
|
|
2884
2957
|
ResolversTypes['GroupPage'],
|
|
2885
2958
|
ParentType,
|
|
@@ -3437,6 +3510,11 @@ export type UserResolvers<
|
|
|
3437
3510
|
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
|
|
3438
3511
|
metadata?: Resolver<ResolversTypes['JSON'], ParentType, ContextType>;
|
|
3439
3512
|
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
3513
|
+
passwordCredential?: Resolver<
|
|
3514
|
+
Types.Maybe<ResolversTypes['ProjectUserPasswordCredential']>,
|
|
3515
|
+
ParentType,
|
|
3516
|
+
ContextType
|
|
3517
|
+
>;
|
|
3440
3518
|
permissionCount?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
|
3441
3519
|
pictureUrl?: Resolver<Types.Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
3442
3520
|
primaryTag?: Resolver<Types.Maybe<ResolversTypes['Tag']>, ParentType, ContextType>;
|
|
@@ -3758,6 +3836,8 @@ export type Resolvers<ContextType = any> = ResolversObject<{
|
|
|
3758
3836
|
CredentialExportData?: CredentialExportDataResolvers<ContextType>;
|
|
3759
3837
|
Date?: GraphQLScalarType;
|
|
3760
3838
|
ExchangeApiKeyResult?: ExchangeApiKeyResultResolvers<ContextType>;
|
|
3839
|
+
ExportedPasswordCredential?: ExportedPasswordCredentialResolvers<ContextType>;
|
|
3840
|
+
ExportedProjectUserCredential?: ExportedProjectUserCredentialResolvers<ContextType>;
|
|
3761
3841
|
Group?: GroupResolvers<ContextType>;
|
|
3762
3842
|
GroupPage?: GroupPageResolvers<ContextType>;
|
|
3763
3843
|
GroupPermission?: GroupPermissionResolvers<ContextType>;
|
|
@@ -3816,7 +3896,9 @@ export type Resolvers<ContextType = any> = ResolversObject<{
|
|
|
3816
3896
|
ProjectTag?: ProjectTagResolvers<ContextType>;
|
|
3817
3897
|
ProjectUser?: ProjectUserResolvers<ContextType>;
|
|
3818
3898
|
ProjectUserApiKey?: ProjectUserApiKeyResolvers<ContextType>;
|
|
3899
|
+
ProjectUserCredentialExport?: ProjectUserCredentialExportResolvers<ContextType>;
|
|
3819
3900
|
ProjectUserGroup?: ProjectUserGroupResolvers<ContextType>;
|
|
3901
|
+
ProjectUserPasswordCredential?: ProjectUserPasswordCredentialResolvers<ContextType>;
|
|
3820
3902
|
ProjectUserPermission?: ProjectUserPermissionResolvers<ContextType>;
|
|
3821
3903
|
Query?: QueryResolvers<ContextType>;
|
|
3822
3904
|
RefreshSessionResponse?: RefreshSessionResponseResolvers<ContextType>;
|
|
@@ -757,6 +757,11 @@ export type CreateUserAuthenticationMethodInput = {
|
|
|
757
757
|
};
|
|
758
758
|
|
|
759
759
|
export type CreateUserInput = {
|
|
760
|
+
/**
|
|
761
|
+
* Optional. Project-scope create only. Stores an unverified Email authentication method.
|
|
762
|
+
* A provider can only be linked to one user account (no sharing), and a user can only have one method per provider (no duplicates).
|
|
763
|
+
*/
|
|
764
|
+
email?: InputMaybe<Scalars['String']['input']>;
|
|
760
765
|
groupIds?: InputMaybe<Array<Scalars['ID']['input']>>;
|
|
761
766
|
metadata?: InputMaybe<Scalars['JSON']['input']>;
|
|
762
767
|
name: Scalars['String']['input'];
|
|
@@ -803,6 +808,15 @@ export type CredentialExportData = {
|
|
|
803
808
|
updatedAt: Scalars['Date']['output'];
|
|
804
809
|
};
|
|
805
810
|
|
|
811
|
+
/**
|
|
812
|
+
* A kind of credential that can be exported. Extensible: a later kind is added here,
|
|
813
|
+
* not as a second export.
|
|
814
|
+
*/
|
|
815
|
+
export enum CredentialKind {
|
|
816
|
+
/** The project password credential (bcrypt hash). */
|
|
817
|
+
Password = 'PASSWORD',
|
|
818
|
+
}
|
|
819
|
+
|
|
806
820
|
export type DeleteApiKeyInput = {
|
|
807
821
|
hardDelete?: InputMaybe<Scalars['Boolean']['input']>;
|
|
808
822
|
id: Scalars['ID']['input'];
|
|
@@ -848,6 +862,31 @@ export type ExchangeApiKeyResult = {
|
|
|
848
862
|
expiresIn: Scalars['Int']['output'];
|
|
849
863
|
};
|
|
850
864
|
|
|
865
|
+
export type ExportProjectUserCredentialsInput = {
|
|
866
|
+
/** Credential kinds to export. Defaults to `[PASSWORD]`. */
|
|
867
|
+
kinds?: InputMaybe<Array<CredentialKind>>;
|
|
868
|
+
/** Project scope the members belong to. */
|
|
869
|
+
scope: Scope;
|
|
870
|
+
/** Project members to export. Every id must be a member of the project, otherwise the whole call fails with not found (no partial export). */
|
|
871
|
+
userIds: Array<Scalars['ID']['input']>;
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
/** A stored password hash in CDM shape. Secret-equivalent: handle like a credential. */
|
|
875
|
+
export type ExportedPasswordCredential = {
|
|
876
|
+
__typename?: 'ExportedPasswordCredential';
|
|
877
|
+
/** Hash algorithm, for example `bcrypt`. */
|
|
878
|
+
algorithm: Scalars['String']['output'];
|
|
879
|
+
/** The stored hash string. */
|
|
880
|
+
hash: Scalars['String']['output'];
|
|
881
|
+
};
|
|
882
|
+
|
|
883
|
+
export type ExportedProjectUserCredential = {
|
|
884
|
+
__typename?: 'ExportedProjectUserCredential';
|
|
885
|
+
/** `null` when the member has no project password credential. */
|
|
886
|
+
password?: Maybe<ExportedPasswordCredential>;
|
|
887
|
+
userId: Scalars['ID']['output'];
|
|
888
|
+
};
|
|
889
|
+
|
|
851
890
|
export type GenerateMyMfaRecoveryCodesInput = {
|
|
852
891
|
factorId?: InputMaybe<Scalars['ID']['input']>;
|
|
853
892
|
};
|
|
@@ -1285,6 +1324,19 @@ export type Mutation = {
|
|
|
1285
1324
|
setMyNotificationPreference: NotificationPreference;
|
|
1286
1325
|
setMyPrimaryAuthenticationMethod: UserAuthenticationMethod;
|
|
1287
1326
|
setMyPrimaryMfaDevice: MfaDevice;
|
|
1327
|
+
/**
|
|
1328
|
+
* Set or replace a project member's Email authentication method as unverified.
|
|
1329
|
+
* `project.user_email_changed` carries ids only, never the address.
|
|
1330
|
+
*/
|
|
1331
|
+
setProjectUserEmail: User;
|
|
1332
|
+
/**
|
|
1333
|
+
* Set or replace a project member's password. Project scopes only: the operator supplies the
|
|
1334
|
+
* password, and the password policy is enforced server-side. Writes the project credential with
|
|
1335
|
+
* source `admin-set` (a later CDM import never overwrites it) and revokes the user's project-app grants.
|
|
1336
|
+
* The password is never returned, logged or carried by any event; `project.user_password_set`
|
|
1337
|
+
* carries ids and the credential source only.
|
|
1338
|
+
*/
|
|
1339
|
+
setProjectUserPassword: User;
|
|
1288
1340
|
setupMfa: MfaSetupResponse;
|
|
1289
1341
|
/**
|
|
1290
1342
|
* Enqueue an asynchronous CDM **export** job for the given project. The worker
|
|
@@ -1647,6 +1699,14 @@ export type MutationSetMyPrimaryMfaDeviceArgs = {
|
|
|
1647
1699
|
input: SetMyPrimaryMfaDeviceInput;
|
|
1648
1700
|
};
|
|
1649
1701
|
|
|
1702
|
+
export type MutationSetProjectUserEmailArgs = {
|
|
1703
|
+
input: SetProjectUserEmailInput;
|
|
1704
|
+
};
|
|
1705
|
+
|
|
1706
|
+
export type MutationSetProjectUserPasswordArgs = {
|
|
1707
|
+
input: SetProjectUserPasswordInput;
|
|
1708
|
+
};
|
|
1709
|
+
|
|
1650
1710
|
export type MutationStartProjectExportArgs = {
|
|
1651
1711
|
id: Scalars['ID']['input'];
|
|
1652
1712
|
input: StartProjectExportInput;
|
|
@@ -2520,6 +2580,12 @@ export type ProjectUserApiKey = Auditable & {
|
|
|
2520
2580
|
userId: Scalars['ID']['output'];
|
|
2521
2581
|
};
|
|
2522
2582
|
|
|
2583
|
+
/** Result of `exportProjectUserCredentials`. This is the one place a credential hash leaves Grant. */
|
|
2584
|
+
export type ProjectUserCredentialExport = {
|
|
2585
|
+
__typename?: 'ProjectUserCredentialExport';
|
|
2586
|
+
users: Array<ExportedProjectUserCredential>;
|
|
2587
|
+
};
|
|
2588
|
+
|
|
2523
2589
|
export type ProjectUserGroup = Auditable & {
|
|
2524
2590
|
__typename?: 'ProjectUserGroup';
|
|
2525
2591
|
createdAt: Scalars['Date']['output'];
|
|
@@ -2531,6 +2597,20 @@ export type ProjectUserGroup = Auditable & {
|
|
|
2531
2597
|
userId: Scalars['ID']['output'];
|
|
2532
2598
|
};
|
|
2533
2599
|
|
|
2600
|
+
/** Non-secret facts about a user's project password credential. Never contains the hash or the password. */
|
|
2601
|
+
export type ProjectUserPasswordCredential = {
|
|
2602
|
+
__typename?: 'ProjectUserPasswordCredential';
|
|
2603
|
+
/**
|
|
2604
|
+
* Lowercase hex SHA-256 of the stored hash string. A change detector, not a secret: it lets a
|
|
2605
|
+
* caller see that the password changed without learning anything usable from it.
|
|
2606
|
+
*/
|
|
2607
|
+
fingerprint: Scalars['String']['output'];
|
|
2608
|
+
/** How the credential was written (for example `reset`, `cdm-import` or `admin-set`). A plain string: the schema has no credential-source enum. */
|
|
2609
|
+
source: Scalars['String']['output'];
|
|
2610
|
+
/** When the stored credential last changed. */
|
|
2611
|
+
updatedAt: Scalars['Date']['output'];
|
|
2612
|
+
};
|
|
2613
|
+
|
|
2534
2614
|
export type ProjectUserPermission = Auditable & {
|
|
2535
2615
|
__typename?: 'ProjectUserPermission';
|
|
2536
2616
|
createdAt: Scalars['Date']['output'];
|
|
@@ -2548,6 +2628,14 @@ export type Query = {
|
|
|
2548
2628
|
apiKeys: ApiKeyPage;
|
|
2549
2629
|
/** Public signup policy. No authentication required. */
|
|
2550
2630
|
authSignupPolicy: AuthSignupPolicy;
|
|
2631
|
+
/**
|
|
2632
|
+
* Export project members' password hashes in CDM shape, for a downstream identity mirror.
|
|
2633
|
+
* This is the one audited exception to "APIs expose only whether a password exists": it
|
|
2634
|
+
* requires `ProjectUser:ExportCredentials` (held by no standard group), every call is audited,
|
|
2635
|
+
* and it returns hashes. Any non-member in `userIds` fails the whole call; members without a
|
|
2636
|
+
* project credential are listed with `password: null`.
|
|
2637
|
+
*/
|
|
2638
|
+
exportProjectUserCredentials: ProjectUserCredentialExport;
|
|
2551
2639
|
groups: GroupPage;
|
|
2552
2640
|
invitation?: Maybe<OrganizationInvitation>;
|
|
2553
2641
|
/** Evaluate authorization for the current session or API key token. */
|
|
@@ -2616,6 +2704,10 @@ export type QueryApiKeysArgs = {
|
|
|
2616
2704
|
sort?: InputMaybe<ApiKeySortInput>;
|
|
2617
2705
|
};
|
|
2618
2706
|
|
|
2707
|
+
export type QueryExportProjectUserCredentialsArgs = {
|
|
2708
|
+
input: ExportProjectUserCredentialsInput;
|
|
2709
|
+
};
|
|
2710
|
+
|
|
2619
2711
|
export type QueryGroupsArgs = {
|
|
2620
2712
|
ids?: InputMaybe<Array<Scalars['ID']['input']>>;
|
|
2621
2713
|
limit?: InputMaybe<Scalars['Int']['input']>;
|
|
@@ -3541,6 +3633,26 @@ export type SetMyPrimaryMfaDeviceInput = {
|
|
|
3541
3633
|
factorId: Scalars['ID']['input'];
|
|
3542
3634
|
};
|
|
3543
3635
|
|
|
3636
|
+
export type SetProjectUserEmailInput = {
|
|
3637
|
+
/**
|
|
3638
|
+
* Unverified Email authentication method. Project-scope only.
|
|
3639
|
+
* A provider can only be linked to one user account (no sharing), and a user can only have one method per provider (no duplicates).
|
|
3640
|
+
*/
|
|
3641
|
+
email: Scalars['String']['input'];
|
|
3642
|
+
scope: Scope;
|
|
3643
|
+
userId: Scalars['ID']['input'];
|
|
3644
|
+
};
|
|
3645
|
+
|
|
3646
|
+
export type SetProjectUserPasswordInput = {
|
|
3647
|
+
/**
|
|
3648
|
+
* The new password, chosen by the operator. Project-scope only. The password policy is enforced
|
|
3649
|
+
* server-side; the value is never returned, logged or carried by any event.
|
|
3650
|
+
*/
|
|
3651
|
+
password: Scalars['String']['input'];
|
|
3652
|
+
scope: Scope;
|
|
3653
|
+
userId: Scalars['ID']['input'];
|
|
3654
|
+
};
|
|
3655
|
+
|
|
3544
3656
|
/**
|
|
3545
3657
|
* Signing key for a scope (e.g. project). Used for RS256 API key tokens; public key is exposed in JWKS.
|
|
3546
3658
|
* Only project scopes (accountProject, organizationProject) have manageable keys; system key is internal.
|
|
@@ -4111,6 +4223,13 @@ export type User = Auditable & {
|
|
|
4111
4223
|
id: Scalars['ID']['output'];
|
|
4112
4224
|
metadata: Scalars['JSON']['output'];
|
|
4113
4225
|
name: Scalars['String']['output'];
|
|
4226
|
+
/**
|
|
4227
|
+
* Non-secret facts about the user's password credential in the request's project scope. `null` outside a
|
|
4228
|
+
* project scope, when the user has no project credential there, or when the caller lacks
|
|
4229
|
+
* `ProjectUser:ExportCredentials` (never an error). `fingerprint` is the lowercase hex SHA-256 of the
|
|
4230
|
+
* stored hash string: a change detector, not a secret. The password and the hash are never returned here.
|
|
4231
|
+
*/
|
|
4232
|
+
passwordCredential?: Maybe<ProjectUserPasswordCredential>;
|
|
4114
4233
|
permissionCount: Scalars['Int']['output'];
|
|
4115
4234
|
pictureUrl?: Maybe<Scalars['String']['output']>;
|
|
4116
4235
|
primaryTag?: Maybe<Tag>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
input ExportProjectUserCredentialsInput {
|
|
2
|
+
"Project scope the members belong to."
|
|
3
|
+
scope: Scope!
|
|
4
|
+
"Project members to export. Every id must be a member of the project, otherwise the whole call fails with not found (no partial export)."
|
|
5
|
+
userIds: [ID!]!
|
|
6
|
+
"Credential kinds to export. Defaults to `[PASSWORD]`."
|
|
7
|
+
kinds: [CredentialKind!] = [PASSWORD]
|
|
8
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
extend type Query {
|
|
2
|
+
"""
|
|
3
|
+
Export project members' password hashes in CDM shape, for a downstream identity mirror.
|
|
4
|
+
This is the one audited exception to "APIs expose only whether a password exists": it
|
|
5
|
+
requires `ProjectUser:ExportCredentials` (held by no standard group), every call is audited,
|
|
6
|
+
and it returns hashes. Any non-member in `userIds` fails the whole call; members without a
|
|
7
|
+
project credential are listed with `password: null`.
|
|
8
|
+
"""
|
|
9
|
+
exportProjectUserCredentials(
|
|
10
|
+
input: ExportProjectUserCredentialsInput!
|
|
11
|
+
): ProjectUserCredentialExport!
|
|
12
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Result of `exportProjectUserCredentials`. This is the one place a credential hash leaves Grant.
|
|
3
|
+
"""
|
|
4
|
+
type ProjectUserCredentialExport {
|
|
5
|
+
users: [ExportedProjectUserCredential!]!
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
type ExportedProjectUserCredential {
|
|
9
|
+
userId: ID!
|
|
10
|
+
"`null` when the member has no project password credential."
|
|
11
|
+
password: ExportedPasswordCredential
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
A stored password hash in CDM shape. Secret-equivalent: handle like a credential.
|
|
16
|
+
"""
|
|
17
|
+
type ExportedPasswordCredential {
|
|
18
|
+
"Hash algorithm, for example `bcrypt`."
|
|
19
|
+
algorithm: String!
|
|
20
|
+
"The stored hash string."
|
|
21
|
+
hash: String!
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Non-secret facts about a user's project password credential. Never contains the hash or the password.
|
|
3
|
+
"""
|
|
4
|
+
type ProjectUserPasswordCredential {
|
|
5
|
+
"How the credential was written (for example `reset`, `cdm-import` or `admin-set`). A plain string: the schema has no credential-source enum."
|
|
6
|
+
source: String!
|
|
7
|
+
"When the stored credential last changed."
|
|
8
|
+
updatedAt: Date!
|
|
9
|
+
"""
|
|
10
|
+
Lowercase hex SHA-256 of the stored hash string. A change detector, not a secret: it lets a
|
|
11
|
+
caller see that the password changed without learning anything usable from it.
|
|
12
|
+
"""
|
|
13
|
+
fingerprint: String!
|
|
14
|
+
}
|
|
@@ -8,4 +8,9 @@ input CreateUserInput {
|
|
|
8
8
|
permissionIds: [ID!]
|
|
9
9
|
scope: Scope!
|
|
10
10
|
primaryTagId: ID
|
|
11
|
+
"""
|
|
12
|
+
Optional. Project-scope create only. Stores an unverified Email authentication method.
|
|
13
|
+
A provider can only be linked to one user account (no sharing), and a user can only have one method per provider (no duplicates).
|
|
14
|
+
"""
|
|
15
|
+
email: String
|
|
11
16
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
input SetProjectUserEmailInput {
|
|
2
|
+
userId: ID!
|
|
3
|
+
"""
|
|
4
|
+
Unverified Email authentication method. Project-scope only.
|
|
5
|
+
A provider can only be linked to one user account (no sharing), and a user can only have one method per provider (no duplicates).
|
|
6
|
+
"""
|
|
7
|
+
email: String!
|
|
8
|
+
scope: Scope!
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
input SetProjectUserPasswordInput {
|
|
2
|
+
userId: ID!
|
|
3
|
+
"""
|
|
4
|
+
The new password, chosen by the operator. Project-scope only. The password policy is enforced
|
|
5
|
+
server-side; the value is never returned, logged or carried by any event.
|
|
6
|
+
"""
|
|
7
|
+
password: String!
|
|
8
|
+
scope: Scope!
|
|
9
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
extend type Mutation {
|
|
2
|
+
"""
|
|
3
|
+
Set or replace a project member's password. Project scopes only: the operator supplies the
|
|
4
|
+
password, and the password policy is enforced server-side. Writes the project credential with
|
|
5
|
+
source `admin-set` (a later CDM import never overwrites it) and revokes the user's project-app grants.
|
|
6
|
+
The password is never returned, logged or carried by any event; `project.user_password_set`
|
|
7
|
+
carries ids and the credential source only.
|
|
8
|
+
"""
|
|
9
|
+
setProjectUserPassword(input: SetProjectUserPasswordInput!): User!
|
|
10
|
+
}
|
|
@@ -14,6 +14,13 @@ type User implements Auditable {
|
|
|
14
14
|
tagCount: Int!
|
|
15
15
|
authenticationMethods: [UserAuthenticationMethod!]
|
|
16
16
|
accounts: [Account!]
|
|
17
|
+
"""
|
|
18
|
+
Non-secret facts about the user's password credential in the request's project scope. `null` outside a
|
|
19
|
+
project scope, when the user has no project credential there, or when the caller lacks
|
|
20
|
+
`ProjectUser:ExportCredentials` (never an error). `fingerprint` is the lowercase hex SHA-256 of the
|
|
21
|
+
stored hash string: a change detector, not a secret. The password and the hash are never returned here.
|
|
22
|
+
"""
|
|
23
|
+
passwordCredential: ProjectUserPasswordCredential
|
|
17
24
|
createdAt: Date!
|
|
18
25
|
updatedAt: Date!
|
|
19
26
|
deletedAt: Date
|
package/src/sdl-contract.test.ts
CHANGED
|
@@ -51,10 +51,12 @@ describe('operation documents', () => {
|
|
|
51
51
|
// 135 after project OAuth connections: get/upsert/clear (three operation documents).
|
|
52
52
|
// 136 after closed-install: AuthSignupPolicyDocument (publicSignupEnabled, bootstrapOpen).
|
|
53
53
|
// 137 after CDM imports by reference: RequestProjectSyncUploadUrlDocument.
|
|
54
|
+
// 138 after operator-set-email: SetProjectUserEmailDocument.
|
|
55
|
+
// 140 after operator-set-password: SetProjectUserPasswordDocument, ExportProjectUserCredentialsDocument.
|
|
54
56
|
// Updating this number is the point of the pin, not a nuisance: every change
|
|
55
57
|
// to it should be a line in a commit message.
|
|
56
58
|
it('finds every document under src/operations', () => {
|
|
57
|
-
expect(files).toHaveLength(
|
|
59
|
+
expect(files).toHaveLength(140);
|
|
58
60
|
});
|
|
59
61
|
|
|
60
62
|
it.each(files.map((f) => [relative(process.cwd(), f), f]))('%s validates', (_label, file) => {
|
|
@@ -67,7 +69,7 @@ describe('graph reachability', () => {
|
|
|
67
69
|
const schema = buildMergedSchema();
|
|
68
70
|
|
|
69
71
|
/**
|
|
70
|
-
* 175 of
|
|
72
|
+
* 175 of 389 declared types cannot be reached from Query or Mutation. They are
|
|
71
73
|
* not dead: most are consumed as generated TypeScript by apps/api, and the
|
|
72
74
|
* *SearchableField enums are runtime search configuration. But every one of them
|
|
73
75
|
* ships in the schema `makeExecutableSchema` serves.
|
|
@@ -80,6 +82,12 @@ describe('graph reachability', () => {
|
|
|
80
82
|
* Was 181 of 388 before pass 5 slice 4 removed six declarations that were
|
|
81
83
|
* unreferenced in SDL and in all TypeScript. The reachable count did not change
|
|
82
84
|
* (207 before and after), which is what makes those six safe to have deleted.
|
|
85
|
+
*
|
|
86
|
+
* operator-set-password declared seven types (382 -> 389 declared). While
|
|
87
|
+
* `passwordCredential` sat on `ProjectUser`, which no query or mutation returns,
|
|
88
|
+
* `ProjectUserPasswordCredential` was unreachable and the pin was 176. It now sits on
|
|
89
|
+
* `User`, so the type is reachable and the pin is back to 175; the other six new
|
|
90
|
+
* types are reachable through the new mutation and query.
|
|
83
91
|
*/
|
|
84
92
|
const UNREACHABLE_FROM_ROOT = 175;
|
|
85
93
|
|