@solidxai/core 0.1.17-beta.1 → 0.1.17-beta.2

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.
@@ -145,6 +145,49 @@ export class UserService extends CRUDService<User> {
145
145
  };
146
146
  }
147
147
 
148
+ /**
149
+ * Asks the registered extension-user provider for role names, treating "no provider
150
+ * registered" and "provider named none for this DTO" identically as [].
151
+ *
152
+ * The one place that actually calls `IExtensionUserCreationProvider.roles()`.
153
+ * `resolveSelfRegistrationRoles` below and `AuthenticationService.resolveSignupRoles`'s
154
+ * `Provider` branch both delegate here rather than each re-deriving "look up the
155
+ * registry, call roles(), default to []". Lives on `UserService` - not on
156
+ * `SolidRegistry`, which stays a pure lookup/storage layer for every provider kind it
157
+ * holds - because `AuthenticationService` already injects `UserService` directly
158
+ * (mirrors `buildSignupTarget`, and the DI cycle runs the other way: `UserService`
159
+ * cannot inject `AuthenticationService` back).
160
+ */
161
+ resolveProviderRoles(dto: Record<string, any>): string[] {
162
+ return (
163
+ this.moduleRef
164
+ .get(SolidRegistry, { strict: false })
165
+ ?.getExtensionUserCreationProvider()
166
+ ?.roles(dto as any) ?? []
167
+ );
168
+ }
169
+
170
+ /**
171
+ * Role names for a self-provisioning user, mirroring SignupIntent.SelfRegistration's
172
+ * policy on the password/OTP paths: ask the extension-user provider first, and fall
173
+ * back to the configured `defaultRole` when it names none - either because there is
174
+ * no provider, or the provider declines to name any for this DTO.
175
+ *
176
+ * Safe to call for OAuth even though `OauthUserDto` carries no discriminator field:
177
+ * a provider whose `roles()` requires one already needs to default it for public
178
+ * register/OTP to work at all (see the extending-users docs), and once it does,
179
+ * this resolves the same way automatically - there is no separate obligation OAuth
180
+ * places on providers beyond what self-registration already requires.
181
+ */
182
+ private resolveSelfRegistrationRoles(dto: Record<string, any>): string[] {
183
+ const roles = this.resolveProviderRoles(dto);
184
+ if (roles.length) {
185
+ return roles;
186
+ }
187
+ const defaultRole = this.settingService.getConfigValue<SolidCoreSetting>("defaultRole");
188
+ return defaultRole ? [defaultRole] : [];
189
+ }
190
+
148
191
  async findOneByEmail(email: string): Promise<User> {
149
192
  return await this.repo.findOne({
150
193
  where: {
@@ -315,21 +358,26 @@ export class UserService extends CRUDService<User> {
315
358
 
316
359
  // if we are unable to find a user then we need to create one.
317
360
  if (!user) {
318
- const user = new User();
319
- user.username = oauthUserDto.email;
320
- user.email = oauthUserDto.email;
321
- user.fullName = oauthUserDto.name;
322
- user.lastLoginProvider = oauthUserDto.provider;
323
- user.accessCode = oauthUserDto.accessCode;
324
- user.googleAccessToken = oauthUserDto.accessToken;
325
- user.googleId = oauthUserDto.providerId;
326
- user.googleProfilePicture = oauthUserDto.picture;
327
-
328
- const savedUser = await this.repo.save(user);
361
+ // Social sign-in provisions an app user, so it is built and roled the same way
362
+ // public signup and OTP registration are: entity through the registered
363
+ // extension-user provider when there is one (see buildSignupTarget), roles
364
+ // through resolveSelfRegistrationRoles below, which asks that same provider
365
+ // first and falls back to `defaultRole`.
366
+ const { entity, repo } = await this.buildSignupTarget(oauthUserDto, true);
367
+ entity.username = oauthUserDto.email;
368
+ entity.email = oauthUserDto.email;
369
+ entity.fullName = oauthUserDto.name;
370
+ entity.lastLoginProvider = oauthUserDto.provider;
371
+ entity.accessCode = oauthUserDto.accessCode;
372
+ entity.googleAccessToken = oauthUserDto.accessToken;
373
+ entity.googleId = oauthUserDto.providerId;
374
+ entity.googleProfilePicture = oauthUserDto.picture;
375
+
376
+ const savedUser = await repo.save(entity);
329
377
 
330
378
  // Initialize the user roles
331
379
  await this.initializeRolesForNewUser(
332
- [this.settingService.getConfigValue<SolidCoreSetting>("defaultRole")],
380
+ this.resolveSelfRegistrationRoles(oauthUserDto),
333
381
  savedUser,
334
382
  );
335
383
  }
@@ -390,20 +438,22 @@ export class UserService extends CRUDService<User> {
390
438
  // facebookProviderFallback,
391
439
  );
392
440
 
393
- const newUser = new User();
394
- newUser.username = username;
395
- newUser.email = email;
396
- newUser.fullName = oauthUserDto.name;
397
- newUser.lastLoginProvider = oauthUserDto.provider;
398
- newUser.accessCode = oauthUserDto.accessCode;
399
- newUser.facebookAccessToken = oauthUserDto.accessToken;
400
- newUser.facebookId = oauthUserDto.providerId;
401
- newUser.facebookProfilePicture = oauthUserDto.picture;
441
+ // See resolveUserOnOauthGoogle for why entity and roles both go through the
442
+ // extension-user provider first, falling back to a plain User / `defaultRole`.
443
+ const { entity, repo } = await this.buildSignupTarget(oauthUserDto, true);
444
+ entity.username = username;
445
+ entity.email = email;
446
+ entity.fullName = oauthUserDto.name;
447
+ entity.lastLoginProvider = oauthUserDto.provider;
448
+ entity.accessCode = oauthUserDto.accessCode;
449
+ entity.facebookAccessToken = oauthUserDto.accessToken;
450
+ entity.facebookId = oauthUserDto.providerId;
451
+ entity.facebookProfilePicture = oauthUserDto.picture;
402
452
 
403
- const savedUser = await this.repo.save(newUser);
453
+ const savedUser = await repo.save(entity);
404
454
 
405
455
  await this.initializeRolesForNewUser(
406
- [this.settingService.getConfigValue<SolidCoreSetting>("defaultRole")],
456
+ this.resolveSelfRegistrationRoles(oauthUserDto),
407
457
  savedUser,
408
458
  );
409
459
  return savedUser;
@@ -432,20 +482,22 @@ export class UserService extends CRUDService<User> {
432
482
  });
433
483
 
434
484
  if (!user) {
435
- const newUser = new User();
436
- newUser.username = oauthUserDto.email;
437
- newUser.email = oauthUserDto.email;
438
- newUser.fullName = oauthUserDto.name;
439
- newUser.lastLoginProvider = oauthUserDto.provider;
440
- newUser.accessCode = oauthUserDto.accessCode;
441
- newUser.microsoftAccessToken = oauthUserDto.accessToken;
442
- newUser.microsoftId = oauthUserDto.providerId;
443
- newUser.microsoftProfilePicture = oauthUserDto.picture;
444
-
445
- const savedUser = await this.repo.save(newUser);
485
+ // See resolveUserOnOauthGoogle for why entity and roles both go through the
486
+ // extension-user provider first, falling back to a plain User / `defaultRole`.
487
+ const { entity, repo } = await this.buildSignupTarget(oauthUserDto, true);
488
+ entity.username = oauthUserDto.email;
489
+ entity.email = oauthUserDto.email;
490
+ entity.fullName = oauthUserDto.name;
491
+ entity.lastLoginProvider = oauthUserDto.provider;
492
+ entity.accessCode = oauthUserDto.accessCode;
493
+ entity.microsoftAccessToken = oauthUserDto.accessToken;
494
+ entity.microsoftId = oauthUserDto.providerId;
495
+ entity.microsoftProfilePicture = oauthUserDto.picture;
496
+
497
+ const savedUser = await repo.save(entity);
446
498
 
447
499
  await this.initializeRolesForNewUser(
448
- [this.settingService.getConfigValue<SolidCoreSetting>("defaultRole")],
500
+ this.resolveSelfRegistrationRoles(oauthUserDto),
449
501
  savedUser,
450
502
  );
451
503
  } else {
@@ -476,20 +528,22 @@ export class UserService extends CRUDService<User> {
476
528
  });
477
529
 
478
530
  if (!user) {
479
- const newUser = new User();
480
- newUser.username = oauthUserDto.email;
481
- newUser.email = oauthUserDto.email;
482
- newUser.fullName = oauthUserDto.name;
483
- newUser.lastLoginProvider = oauthUserDto.provider;
484
- newUser.accessCode = oauthUserDto.accessCode;
485
- newUser.microsoftActiveDirectoryAccessToken = oauthUserDto.accessToken;
486
- newUser.microsoftActiveDirectoryId = oauthUserDto.providerId;
487
- newUser.microsoftActiveDirectoryProfilePicture = oauthUserDto.picture;
488
-
489
- const savedUser = await this.repo.save(newUser);
531
+ // See resolveUserOnOauthGoogle for why entity and roles both go through the
532
+ // extension-user provider first, falling back to a plain User / `defaultRole`.
533
+ const { entity, repo } = await this.buildSignupTarget(oauthUserDto, true);
534
+ entity.username = oauthUserDto.email;
535
+ entity.email = oauthUserDto.email;
536
+ entity.fullName = oauthUserDto.name;
537
+ entity.lastLoginProvider = oauthUserDto.provider;
538
+ entity.accessCode = oauthUserDto.accessCode;
539
+ entity.microsoftActiveDirectoryAccessToken = oauthUserDto.accessToken;
540
+ entity.microsoftActiveDirectoryId = oauthUserDto.providerId;
541
+ entity.microsoftActiveDirectoryProfilePicture = oauthUserDto.picture;
542
+
543
+ const savedUser = await repo.save(entity);
490
544
 
491
545
  await this.initializeRolesForNewUser(
492
- [this.settingService.getConfigValue<SolidCoreSetting>("defaultRole")],
546
+ this.resolveSelfRegistrationRoles(oauthUserDto),
493
547
  savedUser,
494
548
  );
495
549
  } else {