@solidxai/core 0.1.9-beta.8 → 0.1.9

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.
Files changed (44) hide show
  1. package/.claude/settings.local.json +15 -0
  2. package/LICENSE +89 -0
  3. package/README.md +3 -1
  4. package/dist/passport-strategies/facebook-oauth.strategy.d.ts +5 -3
  5. package/dist/passport-strategies/facebook-oauth.strategy.d.ts.map +1 -1
  6. package/dist/passport-strategies/facebook-oauth.strategy.js +41 -18
  7. package/dist/passport-strategies/facebook-oauth.strategy.js.map +1 -1
  8. package/dist/seeders/seed-data/solid-core-metadata.json +1 -1
  9. package/dist/services/authentication.service.d.ts +12 -13
  10. package/dist/services/authentication.service.d.ts.map +1 -1
  11. package/dist/services/authentication.service.js +40 -16
  12. package/dist/services/authentication.service.js.map +1 -1
  13. package/dist/services/settings/default-settings-provider.service.d.ts +16 -0
  14. package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
  15. package/dist/services/settings/default-settings-provider.service.js +75 -12
  16. package/dist/services/settings/default-settings-provider.service.js.map +1 -1
  17. package/dist/services/user.service.d.ts +10 -8
  18. package/dist/services/user.service.d.ts.map +1 -1
  19. package/dist/services/user.service.js +85 -46
  20. package/dist/services/user.service.js.map +1 -1
  21. package/package.json +2 -2
  22. package/src/passport-strategies/facebook-oauth.strategy.ts +82 -31
  23. package/src/seeders/seed-data/solid-core-metadata.json +1 -1
  24. package/src/services/1.js +6 -0
  25. package/src/services/authentication.service.ts +217 -141
  26. package/src/services/settings/default-settings-provider.service.ts +80 -17
  27. package/src/services/user.service.ts +149 -77
  28. package/dev-grooming-docs/ozzy-prompts.txt +0 -70
  29. package/dist-tests/api/authenticate.spec.js +0 -119
  30. package/dist-tests/api/authenticate.spec.js.map +0 -1
  31. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +0 -97
  32. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +0 -1
  33. package/dist-tests/api/ping.spec.js +0 -21
  34. package/dist-tests/api/ping.spec.js.map +0 -1
  35. package/dist-tests/helpers/auth.js +0 -41
  36. package/dist-tests/helpers/auth.js.map +0 -1
  37. package/dist-tests/helpers/env.js +0 -11
  38. package/dist-tests/helpers/env.js.map +0 -1
  39. package/docs/grouping-enhancements.md +0 -89
  40. package/docs/java-spring/README.md +0 -3
  41. package/docs/java-spring/solid-core-module-deep-dive-report.md +0 -1317
  42. package/docs/seed-changes.md +0 -65
  43. package/docs/test-data-workflow.md +0 -200
  44. package/docs/type-declaration-import-issue.md +0 -24
@@ -38,16 +38,19 @@ import { SignInDto } from "../dtos/sign-in.dto";
38
38
  import { SignUpDto } from "../dtos/sign-up.dto";
39
39
  import { User } from "../entities/user.entity";
40
40
  import { EventDetails, EventType } from "../interfaces";
41
- import { ActiveUserData } from '../interfaces/active-user-data.interface';
42
- import { HashingService } from './hashing.service';
43
- import { InvalidatedRefreshTokenError, RefreshTokenIdsStorageService } from './refresh-token-ids-storage.service';
44
- import { SsoCodeStorageService } from './sso-code-storage.service';
45
- import { RoleMetadataService } from './role-metadata.service';
46
- import { SettingService } from './setting.service';
47
- import { UserActivityHistoryService } from './user-activity-history.service';
48
- import { UserService } from './user.service';
49
- import { SmsFactory } from 'src/factories/sms.factory';
50
- import { SolidRegistry } from 'src/helpers/solid-registry';
41
+ import { ActiveUserData } from "../interfaces/active-user-data.interface";
42
+ import { HashingService } from "./hashing.service";
43
+ import {
44
+ InvalidatedRefreshTokenError,
45
+ RefreshTokenIdsStorageService,
46
+ } from "./refresh-token-ids-storage.service";
47
+ import { SsoCodeStorageService } from "./sso-code-storage.service";
48
+ import { RoleMetadataService } from "./role-metadata.service";
49
+ import { SettingService } from "./setting.service";
50
+ import { UserActivityHistoryService } from "./user-activity-history.service";
51
+ import { UserService } from "./user.service";
52
+ import { SmsFactory } from "src/factories/sms.factory";
53
+ import { SolidRegistry } from "src/helpers/solid-registry";
51
54
 
52
55
  enum LoginProvider {
53
56
  LOCAL = "local",
@@ -62,32 +65,32 @@ interface otp {
62
65
 
63
66
  @Injectable()
64
67
  export class AuthenticationService {
65
- private readonly logger = new Logger(AuthenticationService.name);
66
- // private readonly mailService: IMail;
67
- constructor(
68
- private readonly userService: UserService,
69
- // @InjectRepository(User) private readonly userRepository: Repository<User>,
70
- private readonly userRepository: UserRepository,
71
- private readonly hashingService: HashingService,
72
- private readonly jwtService: JwtService,
73
- private readonly refreshTokenIdsStorage: RefreshTokenIdsStorageService,
74
- private readonly httpService: HttpService,
75
- // private readonly mailService: SMTPEMailService,
76
- private readonly mailServiceFactory: MailFactory,
77
- // private readonly smsService: Msg91OTPService,
78
- private readonly smsFactory: SmsFactory,
79
- private readonly eventEmitter: EventEmitter2,
80
- private readonly settingService: SettingService,
81
- private readonly roleMetadataService: RoleMetadataService,
82
- private readonly userActivityHistoryService: UserActivityHistoryService,
83
- private readonly ssoCodeStorage: SsoCodeStorageService,
84
-
85
- @InjectDataSource()
86
- private readonly dataSource: DataSource,
87
- private readonly solidRegistry: SolidRegistry,
88
- ) {
89
- // this.mailService = this.mailServiceFactory.getMailService();
90
- }
68
+ private readonly logger = new Logger(AuthenticationService.name);
69
+ // private readonly mailService: IMail;
70
+ constructor(
71
+ private readonly userService: UserService,
72
+ // @InjectRepository(User) private readonly userRepository: Repository<User>,
73
+ private readonly userRepository: UserRepository,
74
+ private readonly hashingService: HashingService,
75
+ private readonly jwtService: JwtService,
76
+ private readonly refreshTokenIdsStorage: RefreshTokenIdsStorageService,
77
+ private readonly httpService: HttpService,
78
+ // private readonly mailService: SMTPEMailService,
79
+ private readonly mailServiceFactory: MailFactory,
80
+ // private readonly smsService: Msg91OTPService,
81
+ private readonly smsFactory: SmsFactory,
82
+ private readonly eventEmitter: EventEmitter2,
83
+ private readonly settingService: SettingService,
84
+ private readonly roleMetadataService: RoleMetadataService,
85
+ private readonly userActivityHistoryService: UserActivityHistoryService,
86
+ private readonly ssoCodeStorage: SsoCodeStorageService,
87
+
88
+ @InjectDataSource()
89
+ private readonly dataSource: DataSource,
90
+ private readonly solidRegistry: SolidRegistry,
91
+ ) {
92
+ // this.mailService = this.mailServiceFactory.getMailService();
93
+ }
91
94
 
92
95
  private async getCompanyLogo(): Promise<string> {
93
96
  return this.settingService.getConfigValue<SolidCoreSetting>("companylogo");
@@ -153,58 +156,102 @@ export class AuthenticationService {
153
156
  }
154
157
  }
155
158
 
156
- private static readonly SIGNUP_DTO_KEYS = new Set(['username', 'email', 'password', 'fullName', 'mobile', 'roles', 'forcePasswordChange']);
159
+ private static readonly SIGNUP_DTO_KEYS = new Set([
160
+ "username",
161
+ "email",
162
+ "password",
163
+ "fullName",
164
+ "mobile",
165
+ "roles",
166
+ "forcePasswordChange",
167
+ ]);
157
168
 
158
- async signUp(signUpDto: SignUpDto & Record<string, any>, activeUser: ActiveUserData = null): Promise<User> {
159
- const hasExtensionFields = Object.keys(signUpDto).some(k => !AuthenticationService.SIGNUP_DTO_KEYS.has(k));
160
- if (hasExtensionFields) {
161
- const provider = this.solidRegistry.getExtensionUserCreationProvider();
162
- if (!provider) {
163
- throw new InternalServerErrorException(
164
- 'No ExtensionUserCreationProvider registered. Register one to handle extension user creation.',
165
- );
166
- }
167
- const entity = await provider.buildExtensionEntity(signUpDto);
168
- const effectiveDto = { ...signUpDto, roles: provider.roles(signUpDto) };
169
- return this.performSignUp(effectiveDto, entity, provider.repo as Repository<User>);
170
- }
171
- return this.performSignUp(signUpDto, new User(), this.userRepository);
172
- }
173
-
174
- private async performSignUp<T extends User>(signUpDto: SignUpDto, entity: T, repo: Repository<T>): Promise<T> {
175
- try {
176
- const onForcePasswordChange = this.settingService.getConfigValue<SolidCoreSetting>('forceChangePasswordOnFirstLogin');
177
- const activateUserOnRegistration = this.settingService.getConfigValue<SolidCoreSetting>('activateUserOnRegistration');
178
- const defaultRole = this.settingService.getConfigValue<SolidCoreSetting>('defaultRole');
179
-
180
- var { user, pwd, autoGeneratedPwd } = await this.populateForSignup<T>(entity, signUpDto, activateUserOnRegistration, onForcePasswordChange);
181
- const privateDto = signUpDto as { isAllowedToGenerateApiKeys?: boolean };
182
- if (privateDto.isAllowedToGenerateApiKeys !== undefined) {
183
- user.isAllowedToGenerateApiKeys = privateDto.isAllowedToGenerateApiKeys;
184
- }
185
- const savedUser = await repo.save(user);
186
- const userRoles = signUpDto.roles ?? [];
187
- if ((signUpDto.roles?.length ?? 0) === 0 && signUpDto.username !== 'sa' && defaultRole) {
188
- userRoles.push(defaultRole);
189
- }
190
- await this.handlePostSignup(savedUser, userRoles, pwd, autoGeneratedPwd);
191
-
192
- return savedUser;
193
- } catch (err) {
194
- const pgUniqueViolationErrorCode = '23505';
195
- if (err.code === pgUniqueViolationErrorCode) {
196
- throw new ConflictException(parseUniqueConstraintError(err.detail || ERROR_MESSAGES.UNIQUE_CONSTRAINT_VIOLATION));
197
- }
198
- throw err;
199
- }
169
+ async signUp(
170
+ signUpDto: SignUpDto & Record<string, any>,
171
+ activeUser: ActiveUserData = null,
172
+ ): Promise<User> {
173
+ const hasExtensionFields = Object.keys(signUpDto).some(
174
+ (k) => !AuthenticationService.SIGNUP_DTO_KEYS.has(k),
175
+ );
176
+ if (hasExtensionFields) {
177
+ const provider = this.solidRegistry.getExtensionUserCreationProvider();
178
+ if (!provider) {
179
+ throw new InternalServerErrorException(
180
+ "No ExtensionUserCreationProvider registered. Register one to handle extension user creation.",
181
+ );
182
+ }
183
+ const entity = await provider.buildExtensionEntity(signUpDto);
184
+ const effectiveDto = { ...signUpDto, roles: provider.roles(signUpDto) };
185
+ return this.performSignUp(
186
+ effectiveDto,
187
+ entity,
188
+ provider.repo as Repository<User>,
189
+ );
200
190
  }
191
+ return this.performSignUp(signUpDto, new User(), this.userRepository);
192
+ }
201
193
 
202
- /** @deprecated Use IExtensionUserCreationProvider instead. Kept for backward compatibility. */
203
- async signupForExtensionUser<T extends User, U extends CreateUserDto>(signUpDto: SignUpDto, extensionUserDto: U, extensionUserRepo: Repository<T>): Promise<T> {
204
- // @ts-ignore
205
- const entity = extensionUserRepo.merge(extensionUserRepo.create() as T, extensionUserDto);
206
- return this.performSignUp(signUpDto, entity, extensionUserRepo);
194
+ private async performSignUp<T extends User>(
195
+ signUpDto: SignUpDto,
196
+ entity: T,
197
+ repo: Repository<T>,
198
+ ): Promise<T> {
199
+ try {
200
+ const onForcePasswordChange =
201
+ this.settingService.getConfigValue<SolidCoreSetting>(
202
+ "forceChangePasswordOnFirstLogin",
203
+ );
204
+ const activateUserOnRegistration =
205
+ this.settingService.getConfigValue<SolidCoreSetting>(
206
+ "activateUserOnRegistration",
207
+ );
208
+ const defaultRole =
209
+ this.settingService.getConfigValue<SolidCoreSetting>("defaultRole");
210
+
211
+ var { user, pwd, autoGeneratedPwd } = await this.populateForSignup<T>(
212
+ entity,
213
+ signUpDto,
214
+ activateUserOnRegistration,
215
+ onForcePasswordChange,
216
+ );
217
+ const privateDto = signUpDto as { isAllowedToGenerateApiKeys?: boolean };
218
+ if (privateDto.isAllowedToGenerateApiKeys !== undefined) {
219
+ user.isAllowedToGenerateApiKeys = privateDto.isAllowedToGenerateApiKeys;
220
+ }
221
+ const savedUser = await repo.save(user);
222
+ const userRoles = signUpDto.roles ?? [];
223
+ if (
224
+ (signUpDto.roles?.length ?? 0) === 0 &&
225
+ signUpDto.username !== "sa" &&
226
+ defaultRole
227
+ ) {
228
+ userRoles.push(defaultRole);
229
+ }
230
+ await this.handlePostSignup(savedUser, userRoles, pwd, autoGeneratedPwd);
231
+
232
+ return savedUser;
233
+ } catch (err) {
234
+ const pgUniqueViolationErrorCode = "23505";
235
+ if (err.code === pgUniqueViolationErrorCode) {
236
+ throw new ConflictException(
237
+ parseUniqueConstraintError(
238
+ err.detail || ERROR_MESSAGES.UNIQUE_CONSTRAINT_VIOLATION,
239
+ ),
240
+ );
241
+ }
242
+ throw err;
207
243
  }
244
+ }
245
+
246
+ /** @deprecated Use IExtensionUserCreationProvider instead. Kept for backward compatibility. */
247
+ async signupForExtensionUser<T extends User>(
248
+ signUpDto: SignUpDto,
249
+ extensionUserDto: DeepPartial<T>,
250
+ extensionUserRepo: Repository<T>,
251
+ ): Promise<T> {
252
+ const entity = extensionUserRepo.create(extensionUserDto);
253
+ return this.performSignUp(signUpDto, entity, extensionUserRepo);
254
+ }
208
255
 
209
256
  private async populateForSignup<T extends User>(
210
257
  user: T,
@@ -489,20 +536,27 @@ export class AuthenticationService {
489
536
  );
490
537
  }
491
538
 
492
- private async upsertUserWithRegistrationVerificationTokens(existingUser: User, signUpDto: OTPSignUpDto, validationSource: string): Promise<User> {
493
- let user = existingUser;
494
- if (isEmpty(user)) {
495
- user = this.createUser(signUpDto);
496
- user.active = false; // User will be activated only after OTP verification, hence setting active to false for new user.
497
- await this.assignRegistrationOtp(validationSource, user);
498
- await this.userRepository.save(user);
499
- await this.userService.addRoleToUser(user.username, this.settingService.getConfigValue<SolidCoreSetting>('defaultRole'));
500
- } else {
501
- await this.assignRegistrationOtp(validationSource, user);
502
- await this.userRepository.save(user);
503
- }
504
- return user;
539
+ private async upsertUserWithRegistrationVerificationTokens(
540
+ existingUser: User,
541
+ signUpDto: OTPSignUpDto,
542
+ validationSource: string,
543
+ ): Promise<User> {
544
+ let user = existingUser;
545
+ if (isEmpty(user)) {
546
+ user = this.createUser(signUpDto);
547
+ user.active = false; // User will be activated only after OTP verification, hence setting active to false for new user.
548
+ await this.assignRegistrationOtp(validationSource, user);
549
+ await this.userRepository.save(user);
550
+ await this.userService.addRoleToUser(
551
+ user.username,
552
+ this.settingService.getConfigValue<SolidCoreSetting>("defaultRole"),
553
+ );
554
+ } else {
555
+ await this.assignRegistrationOtp(validationSource, user);
556
+ await this.userRepository.save(user);
505
557
  }
558
+ return user;
559
+ }
506
560
 
507
561
  // Create a new user entity.
508
562
  private createUser(signUpDto: OTPSignUpDto) {
@@ -1068,16 +1122,16 @@ export class AuthenticationService {
1068
1122
  }
1069
1123
  }
1070
1124
 
1071
- private buildUserPayload(user: User) {
1072
- const { id, username, email, mobile, lastLoginProvider } = user;
1073
- const roles = user.roles.map((role) => role.name);
1074
- return { id, username, email, mobile, lastLoginProvider, roles };
1075
- }
1125
+ private buildUserPayload(user: User) {
1126
+ const { id, username, email, mobile, lastLoginProvider } = user;
1127
+ const roles = user.roles.map((role) => role.name);
1128
+ return { id, username, email, mobile, lastLoginProvider, roles };
1129
+ }
1076
1130
 
1077
- private async buildLoginTokenResponse(user: User) {
1078
- const { accessToken, refreshToken } = await this.generateTokens(user);
1079
- return { accessToken, refreshToken, user: this.buildUserPayload(user) };
1080
- }
1131
+ private async buildLoginTokenResponse(user: User) {
1132
+ const { accessToken, refreshToken } = await this.generateTokens(user);
1133
+ return { accessToken, refreshToken, user: this.buildUserPayload(user) };
1134
+ }
1081
1135
 
1082
1136
  async changePassword(
1083
1137
  changePasswordDto: ChangePasswordDto,
@@ -1590,9 +1644,19 @@ export class AuthenticationService {
1590
1644
  }
1591
1645
 
1592
1646
  async validateUserUsingFacebook(user: User) {
1647
+ if (!user.facebookAccessToken || !user.facebookId) {
1648
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
1649
+ }
1650
+
1593
1651
  try {
1594
1652
  const response = await this.httpService.axiosRef.get(
1595
- `https://graph.facebook.com/me?fields=id,name,email&access_token=${user.facebookAccessToken}`,
1653
+ `https://graph.facebook.com/me`,
1654
+ {
1655
+ params: { fields: "id,name,email" },
1656
+ headers: {
1657
+ Authorization: `Bearer ${user.facebookAccessToken}`,
1658
+ },
1659
+ },
1596
1660
  );
1597
1661
  const userProfile = response.data;
1598
1662
 
@@ -1605,7 +1669,10 @@ export class AuthenticationService {
1605
1669
  throw new UnauthorizedException(ERROR_MESSAGES.INVALID_USER_PROFILE);
1606
1670
  }
1607
1671
  } catch (error) {
1608
- throw new UnauthorizedException("Facebook OAuth profile fetch failed");
1672
+ if (error instanceof UnauthorizedException) {
1673
+ throw error;
1674
+ }
1675
+ throw new UnauthorizedException(ERROR_MESSAGES.USER_NOT_FOUND);
1609
1676
  }
1610
1677
  }
1611
1678
 
@@ -1846,43 +1913,52 @@ export class AuthenticationService {
1846
1913
  const refreshTokenState =
1847
1914
  await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(user.id);
1848
1915
 
1849
- const response = {
1850
- user: {
1851
- email: user.email,
1852
- mobile: user.mobile,
1853
- username: user.username,
1854
- // forcePasswordChange: user.forcePasswordChange,
1855
- id: user.id,
1856
- roles: user.roles.map((role) => role.name)
1857
- },
1858
- refreshToken: refreshTokenState.currentRefreshToken,
1859
- // ...tokens
1860
- }
1861
- return response;
1862
- }
1916
+ const response = {
1917
+ user: {
1918
+ email: user.email,
1919
+ mobile: user.mobile,
1920
+ username: user.username,
1921
+ // forcePasswordChange: user.forcePasswordChange,
1922
+ id: user.id,
1923
+ roles: user.roles.map((role) => role.name),
1924
+ },
1925
+ refreshToken: refreshTokenState.currentRefreshToken,
1926
+ // ...tokens
1927
+ };
1928
+ return response;
1929
+ }
1863
1930
 
1864
- async generateSsoCode(activeUser: ActiveUserData, rawAccessToken: string): Promise<{ ssoCode: string }> {
1865
- const refreshTokenState = await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(activeUser.sub);
1866
- if (!refreshTokenState?.currentRefreshToken) {
1867
- throw new UnauthorizedException('No active session found');
1868
- }
1869
- const ssoCode = await this.ssoCodeStorage.generateCode(
1870
- activeUser.sub,
1871
- rawAccessToken,
1872
- refreshTokenState.currentRefreshToken,
1873
- );
1874
- return { ssoCode };
1931
+ async generateSsoCode(
1932
+ activeUser: ActiveUserData,
1933
+ rawAccessToken: string,
1934
+ ): Promise<{ ssoCode: string }> {
1935
+ const refreshTokenState =
1936
+ await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(
1937
+ activeUser.sub,
1938
+ );
1939
+ if (!refreshTokenState?.currentRefreshToken) {
1940
+ throw new UnauthorizedException("No active session found");
1875
1941
  }
1942
+ const ssoCode = await this.ssoCodeStorage.generateCode(
1943
+ activeUser.sub,
1944
+ rawAccessToken,
1945
+ refreshTokenState.currentRefreshToken,
1946
+ );
1947
+ return { ssoCode };
1948
+ }
1876
1949
 
1877
- async exchangeSsoCode(code: string) {
1878
- const { userId, accessToken, refreshToken } = await this.ssoCodeStorage.consumeCode(code);
1879
- const user = await this.userRepository.findOne({ where: { id: userId }, relations: { roles: true } });
1880
- if (!user) {
1881
- throw new UnauthorizedException('User not found');
1882
- }
1883
- return { accessToken, refreshToken, user: this.buildUserPayload(user) };
1950
+ async exchangeSsoCode(code: string) {
1951
+ const { userId, accessToken, refreshToken } =
1952
+ await this.ssoCodeStorage.consumeCode(code);
1953
+ const user = await this.userRepository.findOne({
1954
+ where: { id: userId },
1955
+ relations: { roles: true },
1956
+ });
1957
+ if (!user) {
1958
+ throw new UnauthorizedException("User not found");
1884
1959
  }
1885
-
1960
+ return { accessToken, refreshToken, user: this.buildUserPayload(user) };
1961
+ }
1886
1962
  }
1887
1963
 
1888
1964
  function parseUniqueConstraintError(detail: string): string {
@@ -23,9 +23,27 @@ const getSolidCoreSettings = (isProd: boolean) =>
23
23
  sortOrder: 50,
24
24
  controlType: "boolean",
25
25
  },
26
- { moduleName: "solid-core", key: "iamFacebookOAuthEnabled", value: false, level: SettingLevel.SystemAdminEditable },
27
- { moduleName: "solid-core", key: "iamMicrosoftOAuthEnabled", value: false, level: SettingLevel.SystemAdminEditable },
28
- {
26
+ {
27
+ moduleName: "solid-core",
28
+ key: "iamFacebookOAuthEnabled",
29
+ value: false,
30
+ level: SettingLevel.SystemAdminEditable,
31
+ label: "Allow Login / Signup With Facebook",
32
+ group: "authentication-settings",
33
+ sortOrder: 50,
34
+ controlType: "boolean",
35
+ },
36
+ {
37
+ moduleName: "solid-core",
38
+ key: "iamMicrosoftOAuthEnabled",
39
+ value: false,
40
+ level: SettingLevel.SystemAdminEditable,
41
+ label: "Allow Login / Signup With Microsoft",
42
+ group: "authentication-settings",
43
+ sortOrder: 50,
44
+ controlType: "boolean",
45
+ },
46
+ {
29
47
  moduleName: "solid-core",
30
48
  key: "authPagesLayout",
31
49
  value: "center",
@@ -277,11 +295,12 @@ const getSolidCoreSettings = (isProd: boolean) =>
277
295
  level: SettingLevel.SystemAdminEditable,
278
296
  encrypted: true,
279
297
  label: "AI Code Builder Configuration",
280
- description: "Structured configuration for AI providers and model assignments.",
298
+ description:
299
+ "Structured configuration for AI providers and model assignments.",
281
300
  group: "ai-settings",
282
301
  sortOrder: 10,
283
302
  controlType: "custom",
284
- settingsWidget: "solidXGenAiCodeBuilderConfigWidget"
303
+ settingsWidget: "solidXGenAiCodeBuilderConfigWidget",
285
304
  },
286
305
  {
287
306
  moduleName: "solid-core",
@@ -616,19 +635,63 @@ const getSolidCoreSettings = (isProd: boolean) =>
616
635
  controlType: "shortText",
617
636
  },
618
637
 
619
- // facebook-oauth-settings-provider.service.ts
620
- { moduleName: "solid-core", key: "FACEBOOK_CLIENT_ID", value: process.env.IAM_FACEBOOK_OAUTH_CLIENT_ID, level: SettingLevel.SystemAdminReadonly },
621
- { moduleName: "solid-core", key: "FACEBOOK_CLIENT_SECRET", value: process.env.IAM_FACEBOOK_OAUTH_CLIENT_SECRET, level: SettingLevel.SystemEnv },
622
- { moduleName: "solid-core", key: "FACEBOOK_CALLBACK_URL", value: process.env.IAM_FACEBOOK_OAUTH_CALLBACK_URL, level: SettingLevel.SystemAdminReadonly },
623
- { moduleName: "solid-core", key: "FACEBOOK_REDIRECT_URL", value: process.env.IAM_FACEBOOK_OAUTH_REDIRECT_URL, level: SettingLevel.SystemAdminReadonly },
638
+ // facebook-oauth-settings-provider.service.ts
639
+ {
640
+ moduleName: "solid-core",
641
+ key: "FACEBOOK_CLIENT_ID",
642
+ value: process.env.IAM_FACEBOOK_OAUTH_CLIENT_ID,
643
+ level: SettingLevel.SystemAdminReadonly,
644
+ },
645
+ {
646
+ moduleName: "solid-core",
647
+ key: "FACEBOOK_CLIENT_SECRET",
648
+ value: process.env.IAM_FACEBOOK_OAUTH_CLIENT_SECRET,
649
+ level: SettingLevel.SystemEnv,
650
+ },
651
+ {
652
+ moduleName: "solid-core",
653
+ key: "FACEBOOK_CALLBACK_URL",
654
+ value: process.env.IAM_FACEBOOK_OAUTH_CALLBACK_URL,
655
+ level: SettingLevel.SystemAdminReadonly,
656
+ },
657
+ {
658
+ moduleName: "solid-core",
659
+ key: "FACEBOOK_REDIRECT_URL",
660
+ value: process.env.IAM_FACEBOOK_OAUTH_REDIRECT_URL,
661
+ level: SettingLevel.SystemAdminReadonly,
662
+ },
624
663
 
625
-
626
- // microsoft-oauth-settings-provider.service.ts
627
- { moduleName: "solid-core", key: "MICROSOFT_CLIENT_ID", value: process.env.IAM_MICROSOFT_OAUTH_CLIENT_ID, level: SettingLevel.SystemAdminReadonly },
628
- { moduleName: "solid-core", key: "MICROSOFT_CLIENT_SECRET", value: process.env.IAM_MICROSOFT_OAUTH_CLIENT_SECRET, level: SettingLevel.SystemEnv },
629
- { moduleName: "solid-core", key: "MICROSOFT_TENANT_ID", value: process.env.IAM_MICROSOFT_OAUTH_TENANT_ID || 'common', level: SettingLevel.SystemAdminReadonly },
630
- { moduleName: "solid-core", key: "MICROSOFT_CALLBACK_URL", value: process.env.IAM_MICROSOFT_OAUTH_CALLBACK_URL, level: SettingLevel.SystemAdminReadonly },
631
- { moduleName: "solid-core", key: "MICROSOFT_REDIRECT_URL", value: process.env.IAM_MICROSOFT_OAUTH_REDIRECT_URL, level: SettingLevel.SystemAdminReadonly },
664
+ // microsoft-oauth-settings-provider.service.ts
665
+ {
666
+ moduleName: "solid-core",
667
+ key: "MICROSOFT_CLIENT_ID",
668
+ value: process.env.IAM_MICROSOFT_OAUTH_CLIENT_ID,
669
+ level: SettingLevel.SystemAdminReadonly,
670
+ },
671
+ {
672
+ moduleName: "solid-core",
673
+ key: "MICROSOFT_CLIENT_SECRET",
674
+ value: process.env.IAM_MICROSOFT_OAUTH_CLIENT_SECRET,
675
+ level: SettingLevel.SystemEnv,
676
+ },
677
+ {
678
+ moduleName: "solid-core",
679
+ key: "MICROSOFT_TENANT_ID",
680
+ value: process.env.IAM_MICROSOFT_OAUTH_TENANT_ID || "common",
681
+ level: SettingLevel.SystemAdminReadonly,
682
+ },
683
+ {
684
+ moduleName: "solid-core",
685
+ key: "MICROSOFT_CALLBACK_URL",
686
+ value: process.env.IAM_MICROSOFT_OAUTH_CALLBACK_URL,
687
+ level: SettingLevel.SystemAdminReadonly,
688
+ },
689
+ {
690
+ moduleName: "solid-core",
691
+ key: "MICROSOFT_REDIRECT_URL",
692
+ value: process.env.IAM_MICROSOFT_OAUTH_REDIRECT_URL,
693
+ level: SettingLevel.SystemAdminReadonly,
694
+ },
632
695
 
633
696
  // iam-settings-provider.service.ts
634
697
  {