@grantjs/schema 1.15.0 → 1.16.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grantjs/schema",
3
- "version": "1.15.0",
3
+ "version": "1.16.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -444,6 +444,7 @@ export type MeQuery = {
444
444
  requiresEmailVerification: boolean | null;
445
445
  verificationExpiry: Date | null;
446
446
  email: string | null;
447
+ hasOrganizationMembership: boolean;
447
448
  accounts: Array<{
448
449
  id: string;
449
450
  type: Types.AccountType;
@@ -1465,6 +1466,10 @@ export type ProjectSyncJobQuery = {
1465
1466
  usersCreated: number;
1466
1467
  userRolesAssigned: number;
1467
1468
  projectUserApiKeysCreated: number;
1469
+ passwordsImported: number;
1470
+ passwordsUpdated: number;
1471
+ passwordsUnchanged: number;
1472
+ passwordsSkippedExisting: number;
1468
1473
  warnings: Array<string>;
1469
1474
  } | null;
1470
1475
  };
@@ -4175,6 +4180,7 @@ export const MeDocument = {
4175
4180
  { kind: 'Field', name: { kind: 'Name', value: 'requiresEmailVerification' } },
4176
4181
  { kind: 'Field', name: { kind: 'Name', value: 'verificationExpiry' } },
4177
4182
  { kind: 'Field', name: { kind: 'Name', value: 'email' } },
4183
+ { kind: 'Field', name: { kind: 'Name', value: 'hasOrganizationMembership' } },
4178
4184
  ],
4179
4185
  },
4180
4186
  },
@@ -8017,6 +8023,10 @@ export const ProjectSyncJobDocument = {
8017
8023
  { kind: 'Field', name: { kind: 'Name', value: 'usersCreated' } },
8018
8024
  { kind: 'Field', name: { kind: 'Name', value: 'userRolesAssigned' } },
8019
8025
  { kind: 'Field', name: { kind: 'Name', value: 'projectUserApiKeysCreated' } },
8026
+ { kind: 'Field', name: { kind: 'Name', value: 'passwordsImported' } },
8027
+ { kind: 'Field', name: { kind: 'Name', value: 'passwordsUpdated' } },
8028
+ { kind: 'Field', name: { kind: 'Name', value: 'passwordsUnchanged' } },
8029
+ { kind: 'Field', name: { kind: 'Name', value: 'passwordsSkippedExisting' } },
8020
8030
  { kind: 'Field', name: { kind: 'Name', value: 'warnings' } },
8021
8031
  ],
8022
8032
  },
@@ -237,6 +237,8 @@ export type ResolversTypes = ResolversObject<{
237
237
  CdmModeInput: Types.CdmModeInput;
238
238
  CdmModeStrategy: Types.CdmModeStrategy;
239
239
  CdmOnConflict: Types.CdmOnConflict;
240
+ CdmPasswordAlgorithm: Types.CdmPasswordAlgorithm;
241
+ CdmPasswordInput: Types.CdmPasswordInput;
240
242
  ChangeMyPasswordInput: Types.ChangeMyPasswordInput;
241
243
  ChangeMyPasswordResult: ResolverTypeWrapper<Types.ChangeMyPasswordResult>;
242
244
  ClearProjectAppPictureInput: Types.ClearProjectAppPictureInput;
@@ -646,6 +648,7 @@ export type ResolversParentTypes = ResolversObject<{
646
648
  Boolean: Types.Scalars['Boolean']['output'];
647
649
  CdmKeyResolverInput: Types.CdmKeyResolverInput;
648
650
  CdmModeInput: Types.CdmModeInput;
651
+ CdmPasswordInput: Types.CdmPasswordInput;
649
652
  ChangeMyPasswordInput: Types.ChangeMyPasswordInput;
650
653
  ChangeMyPasswordResult: Types.ChangeMyPasswordResult;
651
654
  ClearProjectAppPictureInput: Types.ClearProjectAppPictureInput;
@@ -1430,6 +1433,7 @@ export type MeResponseResolvers<
1430
1433
  > = ResolversObject<{
1431
1434
  accounts?: Resolver<Array<ResolversTypes['Account']>, ParentType, ContextType>;
1432
1435
  email?: Resolver<Types.Maybe<ResolversTypes['String']>, ParentType, ContextType>;
1436
+ hasOrganizationMembership?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
1433
1437
  mfaVerified?: Resolver<Types.Maybe<ResolversTypes['Boolean']>, ParentType, ContextType>;
1434
1438
  requiresEmailVerification?: Resolver<
1435
1439
  Types.Maybe<ResolversTypes['Boolean']>,
@@ -3288,6 +3292,10 @@ export type SyncProjectResultResolvers<
3288
3292
  groupTagsLinked?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
3289
3293
  groupsCreated?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
3290
3294
  importId?: Resolver<Types.Maybe<ResolversTypes['String']>, ParentType, ContextType>;
3295
+ passwordsImported?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
3296
+ passwordsSkippedExisting?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
3297
+ passwordsUnchanged?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
3298
+ passwordsUpdated?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
3291
3299
  permissionsCreated?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
3292
3300
  projectGroupsLinked?: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
3293
3301
  projectId?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
@@ -448,8 +448,9 @@ export enum CdmIfMissing {
448
448
  export type CdmKeyResolverInput = {
449
449
  /**
450
450
  * `id` references an existing Grant user id. `email` resolves or creates a
451
- * global passwordless email authentication method. Other values are treated as
452
- * CDM-local external keys for project import/export.
451
+ * global email authentication method, passwordless unless the user carries a
452
+ * `password`. Other values are treated as CDM-local external keys for project
453
+ * import/export.
453
454
  */
454
455
  findBy?: InputMaybe<CdmFindBy>;
455
456
  ifMissing?: InputMaybe<CdmIfMissing>;
@@ -479,6 +480,31 @@ export enum CdmOnConflict {
479
480
  Update = 'update',
480
481
  }
481
482
 
483
+ /**
484
+ * Password hash algorithms a CDM import can carry. Only `bcrypt` is accepted; the
485
+ * enum leaves room for further algorithms without changing the input shape.
486
+ */
487
+ export enum CdmPasswordAlgorithm {
488
+ Bcrypt = 'bcrypt',
489
+ }
490
+
491
+ /**
492
+ * A password hash the importer already holds, to be stored as the user's email
493
+ * password credential (ADR 0010). Never the plaintext password.
494
+ */
495
+ export type CdmPasswordInput = {
496
+ algorithm: CdmPasswordAlgorithm;
497
+ /**
498
+ * A bcrypt hash in the modular-crypt form `$2a$`, `$2b$` or `$2y$`, a two-digit
499
+ * cost and 53 salt-and-hash characters (60 in all), such as the output of Go's
500
+ * `bcrypt.GenerateFromPassword`. The cost must be within the range the deployment
501
+ * accepts (4 to 15). It is written only to the credential store: it is not kept in
502
+ * metadata, searchable tokens, audit values, events or the stored job payload once
503
+ * the job finishes, and an invalid hash is refused without being echoed.
504
+ */
505
+ hash: Scalars['String']['input'];
506
+ };
507
+
482
508
  export type ChangeMyPasswordInput = {
483
509
  confirmPassword: Scalars['String']['input'];
484
510
  /** Required when a password already exists; omit when setting the first password. */
@@ -984,6 +1010,11 @@ export type MeResponse = {
984
1010
  __typename?: 'MeResponse';
985
1011
  accounts: Array<Account>;
986
1012
  email?: Maybe<Scalars['String']['output']>;
1013
+ /**
1014
+ * Whether the user belongs to at least one organization. A user with no accounts and no
1015
+ * organization membership has no workspace on this installation.
1016
+ */
1017
+ hasOrganizationMembership: Scalars['Boolean']['output'];
987
1018
  mfaVerified?: Maybe<Scalars['Boolean']['output']>;
988
1019
  requiresEmailVerification?: Maybe<Scalars['Boolean']['output']>;
989
1020
  verificationExpiry?: Maybe<Scalars['Date']['output']>;
@@ -3586,6 +3617,22 @@ export type SyncProjectResult = {
3586
3617
  groupTagsLinked: Scalars['Int']['output'];
3587
3618
  groupsCreated: Scalars['Int']['output'];
3588
3619
  importId?: Maybe<Scalars['String']['output']>;
3620
+ /** Users whose `password` hash was stored as their email credential for the first time. */
3621
+ passwordsImported: Scalars['Int']['output'];
3622
+ /**
3623
+ * Users whose `password` hash was not stored because the credential or the identity is
3624
+ * not the import's to write: a password set in Grant, an address the owner has verified,
3625
+ * or an identity that already existed and was not created by an earlier import of this
3626
+ * project.
3627
+ */
3628
+ passwordsSkippedExisting: Scalars['Int']['output'];
3629
+ /** Users whose imported credential already equalled the hash in the document. */
3630
+ passwordsUnchanged: Scalars['Int']['output'];
3631
+ /**
3632
+ * Users whose imported credential was replaced because the document carried a different
3633
+ * hash for it.
3634
+ */
3635
+ passwordsUpdated: Scalars['Int']['output'];
3589
3636
  permissionsCreated: Scalars['Int']['output'];
3590
3637
  projectGroupsLinked: Scalars['Int']['output'];
3591
3638
  projectId: Scalars['ID']['output'];
@@ -4089,6 +4136,22 @@ export type UserCdmInput = {
4089
4136
  key: CdmKeyResolverInput;
4090
4137
  metadata?: InputMaybe<Scalars['JSON']['input']>;
4091
4138
  name: Scalars['String']['input'];
4139
+ /**
4140
+ * Existing password credential to import for this user. Only valid with
4141
+ * `key.findBy: email`, because the credential lives on the email authentication
4142
+ * method; any other resolver is a validation error.
4143
+ *
4144
+ * Ownership is forward-only. An imported credential is marked as imported and stays
4145
+ * owned by the importing system while the email is unverified: a later import of this
4146
+ * project with a different hash replaces it, an identical one changes nothing. Once the
4147
+ * owner verifies the address, or the password is set, changed or reset in Grant, Grant owns
4148
+ * it and imports never touch it again. A credential is written only for an identity the
4149
+ * import creates, or one an earlier import of this project created whose email is still
4150
+ * unverified; any other existing identity, including one found through GitHub or Google,
4151
+ * is left untouched. An absent `password` never removes a
4152
+ * stored credential. See `SyncProjectResult` for the counters.
4153
+ */
4154
+ password?: InputMaybe<CdmPasswordInput>;
4092
4155
  /** Direct user → permission grants (document keys or catalog `resourceSlug:action` refs). */
4093
4156
  permissions?: InputMaybe<Array<Scalars['String']['input']>>;
4094
4157
  primaryTag?: InputMaybe<Scalars['String']['input']>;
@@ -23,5 +23,6 @@ query Me {
23
23
  requiresEmailVerification
24
24
  verificationExpiry
25
25
  email
26
+ hasOrganizationMembership
26
27
  }
27
28
  }
@@ -22,6 +22,10 @@ query ProjectSyncJob($id: ID!, $scope: Scope!, $jobId: ID!) {
22
22
  usersCreated
23
23
  userRolesAssigned
24
24
  projectUserApiKeysCreated
25
+ passwordsImported
26
+ passwordsUpdated
27
+ passwordsUnchanged
28
+ passwordsSkippedExisting
25
29
  warnings
26
30
  }
27
31
  warnings
@@ -4,4 +4,9 @@ type MeResponse {
4
4
  requiresEmailVerification: Boolean
5
5
  verificationExpiry: Date
6
6
  email: String
7
+ """
8
+ Whether the user belongs to at least one organization. A user with no accounts and no
9
+ organization membership has no workspace on this installation.
10
+ """
11
+ hasOrganizationMembership: Boolean!
7
12
  }
@@ -23,6 +23,14 @@ enum CdmIfMissing {
23
23
  createNew
24
24
  }
25
25
 
26
+ """
27
+ Password hash algorithms a CDM import can carry. Only `bcrypt` is accepted; the
28
+ enum leaves room for further algorithms without changing the input shape.
29
+ """
30
+ enum CdmPasswordAlgorithm {
31
+ bcrypt
32
+ }
33
+
26
34
  input CdmModeInput {
27
35
  strategy: CdmModeStrategy!
28
36
  onConflict: CdmOnConflict
@@ -39,8 +47,9 @@ input CdmKeyResolverInput {
39
47
  value: String!
40
48
  """
41
49
  `id` references an existing Grant user id. `email` resolves or creates a
42
- global passwordless email authentication method. Other values are treated as
43
- CDM-local external keys for project import/export.
50
+ global email authentication method, passwordless unless the user carries a
51
+ `password`. Other values are treated as CDM-local external keys for project
52
+ import/export.
44
53
  """
45
54
  findBy: CdmFindBy
46
55
  ifMissing: CdmIfMissing
@@ -128,6 +137,23 @@ input UserApiKeyCdmInput {
128
137
  metadata: JSON
129
138
  }
130
139
 
140
+ """
141
+ A password hash the importer already holds, to be stored as the user's email
142
+ password credential (ADR 0010). Never the plaintext password.
143
+ """
144
+ input CdmPasswordInput {
145
+ algorithm: CdmPasswordAlgorithm!
146
+ """
147
+ A bcrypt hash in the modular-crypt form `$2a$`, `$2b$` or `$2y$`, a two-digit
148
+ cost and 53 salt-and-hash characters (60 in all), such as the output of Go's
149
+ `bcrypt.GenerateFromPassword`. The cost must be within the range the deployment
150
+ accepts (4 to 15). It is written only to the credential store: it is not kept in
151
+ metadata, searchable tokens, audit values, events or the stored job payload once
152
+ the job finishes, and an invalid hash is refused without being echoed.
153
+ """
154
+ hash: String!
155
+ }
156
+
131
157
  input UserCdmInput {
132
158
  key: CdmKeyResolverInput!
133
159
  name: String!
@@ -147,6 +173,22 @@ input UserCdmInput {
147
173
  primaryTag: String
148
174
  apiKeys: [UserApiKeyCdmInput!]
149
175
  """
176
+ Existing password credential to import for this user. Only valid with
177
+ `key.findBy: email`, because the credential lives on the email authentication
178
+ method; any other resolver is a validation error.
179
+
180
+ Ownership is forward-only. An imported credential is marked as imported and stays
181
+ owned by the importing system while the email is unverified: a later import of this
182
+ project with a different hash replaces it, an identical one changes nothing. Once the
183
+ owner verifies the address, or the password is set, changed or reset in Grant, Grant owns
184
+ it and imports never touch it again. A credential is written only for an identity the
185
+ import creates, or one an earlier import of this project created whose email is still
186
+ unverified; any other existing identity, including one found through GitHub or Google,
187
+ is left untouched. An absent `password` never removes a
188
+ stored credential. See `SyncProjectResult` for the counters.
189
+ """
190
+ password: CdmPasswordInput
191
+ """
150
192
  Denormalized search tokens for project-scoped user list views.
151
193
  """
152
194
  searchable: JSON
@@ -16,6 +16,26 @@ type SyncProjectResult {
16
16
  usersCreated: Int!
17
17
  userRolesAssigned: Int!
18
18
  projectUserApiKeysCreated: Int!
19
+ """
20
+ Users whose `password` hash was stored as their email credential for the first time.
21
+ """
22
+ passwordsImported: Int!
23
+ """
24
+ Users whose imported credential was replaced because the document carried a different
25
+ hash for it.
26
+ """
27
+ passwordsUpdated: Int!
28
+ """
29
+ Users whose imported credential already equalled the hash in the document.
30
+ """
31
+ passwordsUnchanged: Int!
32
+ """
33
+ Users whose `password` hash was not stored because the credential or the identity is
34
+ not the import's to write: a password set in Grant, an address the owner has verified,
35
+ or an identity that already existed and was not created by an earlier import of this
36
+ project.
37
+ """
38
+ passwordsSkippedExisting: Int!
19
39
  resourcesCreated: Int!
20
40
  permissionsCreated: Int!
21
41
  tagsCreated: Int!