@oneuptime/common 11.0.3 → 11.0.5

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 (228) hide show
  1. package/Models/DatabaseModels/GlobalConfig.ts +19 -0
  2. package/Models/DatabaseModels/GlobalOidc.ts +351 -0
  3. package/Models/DatabaseModels/GlobalOidcProject.ts +265 -0
  4. package/Models/DatabaseModels/GlobalSso.ts +312 -0
  5. package/Models/DatabaseModels/GlobalSsoProject.ts +268 -0
  6. package/Models/DatabaseModels/Index.ts +8 -0
  7. package/Models/DatabaseModels/Project.ts +31 -0
  8. package/Models/DatabaseModels/StatusPage.ts +82 -0
  9. package/Server/API/StatusPageAPI.ts +2 -0
  10. package/Server/Infrastructure/GlobalCache.ts +11 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/{1781587937032-MigrationName.ts → 1781750000000-MigrationName.ts} +2 -2
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1782000000000-AddGlobalSsoAndOidc.ts +176 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1782100000000-AddStatusPageImageAltText.ts +25 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1782200000000-AddRequireSsoForLoginToGlobalProviders.ts +25 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1782300000000-MoveRequireSsoForLoginToGlobalConfig.ts +38 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1782310000000-MigrationName.ts +299 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1782400000000-RemoveIsTestedFromGlobalSsoAndOidc.ts +21 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -2
  19. package/Server/Middleware/UserAuthorization.ts +113 -42
  20. package/Server/Services/CephClusterService.ts +22 -10
  21. package/Server/Services/CloudResourceService.ts +22 -10
  22. package/Server/Services/DockerHostService.ts +22 -10
  23. package/Server/Services/DockerSwarmClusterService.ts +22 -10
  24. package/Server/Services/GlobalConfigService.ts +50 -0
  25. package/Server/Services/GlobalOidcProjectService.ts +85 -0
  26. package/Server/Services/GlobalOidcService.ts +10 -0
  27. package/Server/Services/GlobalSsoProjectService.ts +85 -0
  28. package/Server/Services/GlobalSsoService.ts +10 -0
  29. package/Server/Services/HostService.ts +22 -10
  30. package/Server/Services/Index.ts +8 -0
  31. package/Server/Services/KubernetesClusterService.ts +22 -10
  32. package/Server/Services/PodmanHostService.ts +22 -10
  33. package/Server/Services/ProjectService.ts +44 -1
  34. package/Server/Services/ProxmoxClusterService.ts +22 -10
  35. package/Server/Services/RumApplicationService.ts +22 -10
  36. package/Server/Services/ServerlessFunctionService.ts +22 -10
  37. package/Server/Utils/Cookie.ts +39 -5
  38. package/Server/Utils/JsonWebToken.ts +7 -0
  39. package/Server/Utils/ValidateGlobalProviderProjectTeams.ts +119 -0
  40. package/Tests/Server/Infrastructure/GlobalCache.test.ts +43 -0
  41. package/Tests/Server/Middleware/UserAuthorization.test.ts +51 -13
  42. package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +163 -0
  43. package/Tests/Server/Utils/CookieSSOToken.test.ts +130 -0
  44. package/Types/JsonWebTokenData.ts +3 -0
  45. package/Types/SSO/SsoProviderType.ts +8 -0
  46. package/UI/Components/Accordion/Accordion.tsx +5 -1
  47. package/UI/Components/CardSelect/CardSelect.tsx +6 -1
  48. package/UI/Components/CategoryCheckbox/Index.tsx +2 -1
  49. package/UI/Components/Charts/Area/AreaChart.tsx +4 -8
  50. package/UI/Components/Charts/Bar/BarChart.tsx +4 -8
  51. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +4 -8
  52. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +1 -1
  53. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +1 -1
  54. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +1 -1
  55. package/UI/Components/Charts/Line/LineChart.tsx +4 -8
  56. package/UI/Components/CodeEditor/CodeEditor.tsx +2 -0
  57. package/UI/Components/CollapsibleSection/CollapsibleSection.tsx +8 -1
  58. package/UI/Components/Dropdown/Dropdown.tsx +2 -0
  59. package/UI/Components/EditionLabel/EditionLabel.tsx +68 -16
  60. package/UI/Components/EntityDropdown/EntityDropdown.tsx +3 -0
  61. package/UI/Components/FilePicker/FilePicker.tsx +2 -0
  62. package/UI/Components/Forms/Fields/ColorPicker.tsx +2 -0
  63. package/UI/Components/Forms/Fields/FieldLabel.tsx +4 -0
  64. package/UI/Components/Forms/Fields/FormField.tsx +72 -15
  65. package/UI/Components/Forms/Fields/IconPicker.tsx +2 -0
  66. package/UI/Components/Forms/Validation.ts +107 -23
  67. package/UI/Components/Input/Input.tsx +4 -0
  68. package/UI/Components/Link/Link.tsx +23 -0
  69. package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
  70. package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +3 -0
  71. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +63 -2
  72. package/UI/Components/Modal/Modal.tsx +4 -1
  73. package/UI/Components/Radio/Radio.tsx +2 -0
  74. package/UI/Components/RadioButtons/GroupRadioButtons.tsx +6 -1
  75. package/UI/Components/Tabs/Tabs.tsx +63 -0
  76. package/UI/Components/TextArea/TextArea.tsx +2 -0
  77. package/UI/Components/TimePicker/TimePicker.tsx +2 -0
  78. package/UI/Components/Toggle/Toggle.tsx +2 -1
  79. package/UI/Components/Tooltip/Tooltip.tsx +6 -1
  80. package/build/dist/Models/DatabaseModels/GlobalConfig.js +20 -0
  81. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  82. package/build/dist/Models/DatabaseModels/GlobalOidc.js +379 -0
  83. package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -0
  84. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +276 -0
  85. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -0
  86. package/build/dist/Models/DatabaseModels/GlobalSso.js +341 -0
  87. package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -0
  88. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +279 -0
  89. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -0
  90. package/build/dist/Models/DatabaseModels/Index.js +8 -0
  91. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  92. package/build/dist/Models/DatabaseModels/Project.js +32 -0
  93. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  94. package/build/dist/Models/DatabaseModels/StatusPage.js +84 -0
  95. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  96. package/build/dist/Server/API/StatusPageAPI.js +2 -0
  97. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  98. package/build/dist/Server/Infrastructure/GlobalCache.js +13 -0
  99. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  100. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/{1781587937032-MigrationName.js → 1781750000000-MigrationName.js} +3 -3
  101. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/{1781587937032-MigrationName.js.map → 1781750000000-MigrationName.js.map} +1 -1
  102. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782000000000-AddGlobalSsoAndOidc.js +73 -0
  103. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782000000000-AddGlobalSsoAndOidc.js.map +1 -0
  104. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782100000000-AddStatusPageImageAltText.js +14 -0
  105. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782100000000-AddStatusPageImageAltText.js.map +1 -0
  106. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782200000000-AddRequireSsoForLoginToGlobalProviders.js +14 -0
  107. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782200000000-AddRequireSsoForLoginToGlobalProviders.js.map +1 -0
  108. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782300000000-MoveRequireSsoForLoginToGlobalConfig.js +23 -0
  109. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782300000000-MoveRequireSsoForLoginToGlobalConfig.js.map +1 -0
  110. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782310000000-MigrationName.js +106 -0
  111. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782310000000-MigrationName.js.map +1 -0
  112. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782400000000-RemoveIsTestedFromGlobalSsoAndOidc.js +14 -0
  113. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782400000000-RemoveIsTestedFromGlobalSsoAndOidc.js.map +1 -0
  114. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -2
  115. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  116. package/build/dist/Server/Middleware/UserAuthorization.js +77 -34
  117. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  118. package/build/dist/Server/Services/CephClusterService.js +19 -2
  119. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  120. package/build/dist/Server/Services/CloudResourceService.js +19 -2
  121. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  122. package/build/dist/Server/Services/DockerHostService.js +19 -2
  123. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  124. package/build/dist/Server/Services/DockerSwarmClusterService.js +19 -2
  125. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  126. package/build/dist/Server/Services/GlobalConfigService.js +55 -0
  127. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  128. package/build/dist/Server/Services/GlobalOidcProjectService.js +80 -0
  129. package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -0
  130. package/build/dist/Server/Services/GlobalOidcService.js +9 -0
  131. package/build/dist/Server/Services/GlobalOidcService.js.map +1 -0
  132. package/build/dist/Server/Services/GlobalSsoProjectService.js +80 -0
  133. package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -0
  134. package/build/dist/Server/Services/GlobalSsoService.js +9 -0
  135. package/build/dist/Server/Services/GlobalSsoService.js.map +1 -0
  136. package/build/dist/Server/Services/HostService.js +19 -2
  137. package/build/dist/Server/Services/HostService.js.map +1 -1
  138. package/build/dist/Server/Services/Index.js +8 -0
  139. package/build/dist/Server/Services/Index.js.map +1 -1
  140. package/build/dist/Server/Services/KubernetesClusterService.js +19 -2
  141. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  142. package/build/dist/Server/Services/PodmanHostService.js +19 -2
  143. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  144. package/build/dist/Server/Services/ProjectService.js +36 -1
  145. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  146. package/build/dist/Server/Services/ProxmoxClusterService.js +19 -2
  147. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  148. package/build/dist/Server/Services/RumApplicationService.js +19 -2
  149. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  150. package/build/dist/Server/Services/ServerlessFunctionService.js +19 -2
  151. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  152. package/build/dist/Server/Utils/Cookie.js +32 -3
  153. package/build/dist/Server/Utils/Cookie.js.map +1 -1
  154. package/build/dist/Server/Utils/JsonWebToken.js +6 -0
  155. package/build/dist/Server/Utils/JsonWebToken.js.map +1 -1
  156. package/build/dist/Server/Utils/ValidateGlobalProviderProjectTeams.js +66 -0
  157. package/build/dist/Server/Utils/ValidateGlobalProviderProjectTeams.js.map +1 -0
  158. package/build/dist/Types/SSO/SsoProviderType.js +9 -0
  159. package/build/dist/Types/SSO/SsoProviderType.js.map +1 -0
  160. package/build/dist/UI/Components/Accordion/Accordion.js +5 -3
  161. package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
  162. package/build/dist/UI/Components/CardSelect/CardSelect.js +1 -1
  163. package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
  164. package/build/dist/UI/Components/CategoryCheckbox/Index.js +1 -1
  165. package/build/dist/UI/Components/CategoryCheckbox/Index.js.map +1 -1
  166. package/build/dist/UI/Components/Charts/Area/AreaChart.js +2 -6
  167. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  168. package/build/dist/UI/Components/Charts/Bar/BarChart.js +2 -6
  169. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  170. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +8 -8
  171. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  172. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +1 -1
  173. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  174. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +1 -1
  175. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  176. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +1 -1
  177. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  178. package/build/dist/UI/Components/Charts/Line/LineChart.js +2 -6
  179. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  180. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +1 -1
  181. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  182. package/build/dist/UI/Components/CollapsibleSection/CollapsibleSection.js +4 -2
  183. package/build/dist/UI/Components/CollapsibleSection/CollapsibleSection.js.map +1 -1
  184. package/build/dist/UI/Components/Dropdown/Dropdown.js +1 -1
  185. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  186. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +31 -5
  187. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  188. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +2 -2
  189. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  190. package/build/dist/UI/Components/FilePicker/FilePicker.js +1 -1
  191. package/build/dist/UI/Components/FilePicker/FilePicker.js.map +1 -1
  192. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +1 -1
  193. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
  194. package/build/dist/UI/Components/Forms/Fields/FieldLabel.js +1 -1
  195. package/build/dist/UI/Components/Forms/Fields/FieldLabel.js.map +1 -1
  196. package/build/dist/UI/Components/Forms/Fields/FormField.js +58 -22
  197. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  198. package/build/dist/UI/Components/Forms/Fields/IconPicker.js +1 -1
  199. package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
  200. package/build/dist/UI/Components/Forms/Validation.js +64 -15
  201. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  202. package/build/dist/UI/Components/Input/Input.js +1 -1
  203. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  204. package/build/dist/UI/Components/Link/Link.js +22 -1
  205. package/build/dist/UI/Components/Link/Link.js.map +1 -1
  206. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
  207. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
  208. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +2 -2
  209. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
  210. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +46 -2
  211. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  212. package/build/dist/UI/Components/Modal/Modal.js +1 -1
  213. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  214. package/build/dist/UI/Components/Radio/Radio.js +1 -1
  215. package/build/dist/UI/Components/Radio/Radio.js.map +1 -1
  216. package/build/dist/UI/Components/RadioButtons/GroupRadioButtons.js +1 -1
  217. package/build/dist/UI/Components/RadioButtons/GroupRadioButtons.js.map +1 -1
  218. package/build/dist/UI/Components/Tabs/Tabs.js +50 -1
  219. package/build/dist/UI/Components/Tabs/Tabs.js.map +1 -1
  220. package/build/dist/UI/Components/TextArea/TextArea.js +1 -1
  221. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  222. package/build/dist/UI/Components/TimePicker/TimePicker.js +1 -1
  223. package/build/dist/UI/Components/TimePicker/TimePicker.js.map +1 -1
  224. package/build/dist/UI/Components/Toggle/Toggle.js +1 -1
  225. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  226. package/build/dist/UI/Components/Tooltip/Tooltip.js +6 -1
  227. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  228. package/package.json +1 -1
@@ -0,0 +1,299 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1782310000000 implements MigrationInterface {
4
+ public name = "MigrationName1782310000000";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `ALTER TABLE "GlobalSSO" DROP CONSTRAINT "FK_GlobalSSO_createdByUserId"`,
9
+ );
10
+ await queryRunner.query(
11
+ `ALTER TABLE "GlobalSSO" DROP CONSTRAINT "FK_GlobalSSO_deletedByUserId"`,
12
+ );
13
+ await queryRunner.query(
14
+ `ALTER TABLE "GlobalOIDC" DROP CONSTRAINT "FK_GlobalOIDC_createdByUserId"`,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "GlobalOIDC" DROP CONSTRAINT "FK_GlobalOIDC_deletedByUserId"`,
18
+ );
19
+ await queryRunner.query(
20
+ `ALTER TABLE "GlobalSSOProject" DROP CONSTRAINT "FK_GlobalSSOProject_globalSsoId"`,
21
+ );
22
+ await queryRunner.query(
23
+ `ALTER TABLE "GlobalSSOProject" DROP CONSTRAINT "FK_GlobalSSOProject_projectId"`,
24
+ );
25
+ await queryRunner.query(
26
+ `ALTER TABLE "GlobalSSOProject" DROP CONSTRAINT "FK_GlobalSSOProject_createdByUserId"`,
27
+ );
28
+ await queryRunner.query(
29
+ `ALTER TABLE "GlobalOIDCProject" DROP CONSTRAINT "FK_GlobalOIDCProject_globalOidcId"`,
30
+ );
31
+ await queryRunner.query(
32
+ `ALTER TABLE "GlobalOIDCProject" DROP CONSTRAINT "FK_GlobalOIDCProject_projectId"`,
33
+ );
34
+ await queryRunner.query(
35
+ `ALTER TABLE "GlobalOIDCProject" DROP CONSTRAINT "FK_GlobalOIDCProject_createdByUserId"`,
36
+ );
37
+ await queryRunner.query(
38
+ `ALTER TABLE "GlobalSSOProjectTeam" DROP CONSTRAINT "FK_GlobalSSOProjectTeam_globalSsoProjectId"`,
39
+ );
40
+ await queryRunner.query(
41
+ `ALTER TABLE "GlobalSSOProjectTeam" DROP CONSTRAINT "FK_GlobalSSOProjectTeam_teamId"`,
42
+ );
43
+ await queryRunner.query(
44
+ `ALTER TABLE "GlobalOIDCProjectTeam" DROP CONSTRAINT "FK_GlobalOIDCProjectTeam_globalOidcProjectId"`,
45
+ );
46
+ await queryRunner.query(
47
+ `ALTER TABLE "GlobalOIDCProjectTeam" DROP CONSTRAINT "FK_GlobalOIDCProjectTeam_teamId"`,
48
+ );
49
+ await queryRunner.query(
50
+ `DROP INDEX "public"."IDX_GlobalSSOProject_globalSsoId"`,
51
+ );
52
+ await queryRunner.query(
53
+ `DROP INDEX "public"."IDX_GlobalSSOProject_projectId"`,
54
+ );
55
+ await queryRunner.query(
56
+ `DROP INDEX "public"."IDX_GlobalSSOProject_globalSsoId_projectId"`,
57
+ );
58
+ await queryRunner.query(
59
+ `DROP INDEX "public"."IDX_GlobalOIDCProject_globalOidcId"`,
60
+ );
61
+ await queryRunner.query(
62
+ `DROP INDEX "public"."IDX_GlobalOIDCProject_projectId"`,
63
+ );
64
+ await queryRunner.query(
65
+ `DROP INDEX "public"."IDX_GlobalOIDCProject_globalOidcId_projectId"`,
66
+ );
67
+ await queryRunner.query(
68
+ `DROP INDEX "public"."IDX_GlobalSSOProjectTeam_globalSsoProjectId"`,
69
+ );
70
+ await queryRunner.query(
71
+ `DROP INDEX "public"."IDX_GlobalSSOProjectTeam_teamId"`,
72
+ );
73
+ await queryRunner.query(
74
+ `DROP INDEX "public"."IDX_GlobalOIDCProjectTeam_globalOidcProjectId"`,
75
+ );
76
+ await queryRunner.query(
77
+ `DROP INDEX "public"."IDX_GlobalOIDCProjectTeam_teamId"`,
78
+ );
79
+ await queryRunner.query(
80
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
81
+ );
82
+ await queryRunner.query(
83
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
84
+ );
85
+ await queryRunner.query(
86
+ `CREATE INDEX "IDX_71298cc376a253647839650fb0" ON "GlobalSSOProject" ("globalSsoId") `,
87
+ );
88
+ await queryRunner.query(
89
+ `CREATE INDEX "IDX_a58c789ff9fe63f416b0146084" ON "GlobalSSOProject" ("projectId") `,
90
+ );
91
+ await queryRunner.query(
92
+ `CREATE INDEX "IDX_8e4bf7b1571a065aad6feed4bc" ON "GlobalOIDCProject" ("globalOidcId") `,
93
+ );
94
+ await queryRunner.query(
95
+ `CREATE INDEX "IDX_e8522835aea64186bc53722f31" ON "GlobalOIDCProject" ("projectId") `,
96
+ );
97
+ await queryRunner.query(
98
+ `CREATE INDEX "IDX_390d2b4b9718741c13a9bf3646" ON "GlobalSSOProjectTeam" ("globalSsoProjectId") `,
99
+ );
100
+ await queryRunner.query(
101
+ `CREATE INDEX "IDX_c088ff9d9ca99dd93a8cbeec50" ON "GlobalSSOProjectTeam" ("teamId") `,
102
+ );
103
+ await queryRunner.query(
104
+ `CREATE INDEX "IDX_8c9b95c3d5d24e56c003467e82" ON "GlobalOIDCProjectTeam" ("globalOidcProjectId") `,
105
+ );
106
+ await queryRunner.query(
107
+ `CREATE INDEX "IDX_c11b9a707701e7c10b5b86c9a2" ON "GlobalOIDCProjectTeam" ("teamId") `,
108
+ );
109
+ await queryRunner.query(
110
+ `ALTER TABLE "GlobalSSO" ADD CONSTRAINT "FK_1003cf4114a89a4ff7ec16e7406" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
111
+ );
112
+ await queryRunner.query(
113
+ `ALTER TABLE "GlobalSSO" ADD CONSTRAINT "FK_4f520827496e355d4bdfda66120" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
114
+ );
115
+ await queryRunner.query(
116
+ `ALTER TABLE "GlobalOIDC" ADD CONSTRAINT "FK_b04eac8e1886aefae5e2b16cddc" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
117
+ );
118
+ await queryRunner.query(
119
+ `ALTER TABLE "GlobalOIDC" ADD CONSTRAINT "FK_0febb2e4c4d8703fce4bc816b36" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
120
+ );
121
+ await queryRunner.query(
122
+ `ALTER TABLE "GlobalSSOProject" ADD CONSTRAINT "FK_71298cc376a253647839650fb0b" FOREIGN KEY ("globalSsoId") REFERENCES "GlobalSSO"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
123
+ );
124
+ await queryRunner.query(
125
+ `ALTER TABLE "GlobalSSOProject" ADD CONSTRAINT "FK_a58c789ff9fe63f416b01460840" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
126
+ );
127
+ await queryRunner.query(
128
+ `ALTER TABLE "GlobalSSOProject" ADD CONSTRAINT "FK_91f47fc5d7c0f09bec7c9dd3e86" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
129
+ );
130
+ await queryRunner.query(
131
+ `ALTER TABLE "GlobalOIDCProject" ADD CONSTRAINT "FK_8e4bf7b1571a065aad6feed4bca" FOREIGN KEY ("globalOidcId") REFERENCES "GlobalOIDC"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
132
+ );
133
+ await queryRunner.query(
134
+ `ALTER TABLE "GlobalOIDCProject" ADD CONSTRAINT "FK_e8522835aea64186bc53722f314" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
135
+ );
136
+ await queryRunner.query(
137
+ `ALTER TABLE "GlobalOIDCProject" ADD CONSTRAINT "FK_63f1d796f2f259be00f402e936c" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
138
+ );
139
+ await queryRunner.query(
140
+ `ALTER TABLE "GlobalSSOProjectTeam" ADD CONSTRAINT "FK_390d2b4b9718741c13a9bf36467" FOREIGN KEY ("globalSsoProjectId") REFERENCES "GlobalSSOProject"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
141
+ );
142
+ await queryRunner.query(
143
+ `ALTER TABLE "GlobalSSOProjectTeam" ADD CONSTRAINT "FK_c088ff9d9ca99dd93a8cbeec50a" FOREIGN KEY ("teamId") REFERENCES "Team"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
144
+ );
145
+ await queryRunner.query(
146
+ `ALTER TABLE "GlobalOIDCProjectTeam" ADD CONSTRAINT "FK_8c9b95c3d5d24e56c003467e820" FOREIGN KEY ("globalOidcProjectId") REFERENCES "GlobalOIDCProject"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
147
+ );
148
+ await queryRunner.query(
149
+ `ALTER TABLE "GlobalOIDCProjectTeam" ADD CONSTRAINT "FK_c11b9a707701e7c10b5b86c9a21" FOREIGN KEY ("teamId") REFERENCES "Team"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
150
+ );
151
+ }
152
+
153
+ public async down(queryRunner: QueryRunner): Promise<void> {
154
+ await queryRunner.query(
155
+ `ALTER TABLE "GlobalOIDCProjectTeam" DROP CONSTRAINT "FK_c11b9a707701e7c10b5b86c9a21"`,
156
+ );
157
+ await queryRunner.query(
158
+ `ALTER TABLE "GlobalOIDCProjectTeam" DROP CONSTRAINT "FK_8c9b95c3d5d24e56c003467e820"`,
159
+ );
160
+ await queryRunner.query(
161
+ `ALTER TABLE "GlobalSSOProjectTeam" DROP CONSTRAINT "FK_c088ff9d9ca99dd93a8cbeec50a"`,
162
+ );
163
+ await queryRunner.query(
164
+ `ALTER TABLE "GlobalSSOProjectTeam" DROP CONSTRAINT "FK_390d2b4b9718741c13a9bf36467"`,
165
+ );
166
+ await queryRunner.query(
167
+ `ALTER TABLE "GlobalOIDCProject" DROP CONSTRAINT "FK_63f1d796f2f259be00f402e936c"`,
168
+ );
169
+ await queryRunner.query(
170
+ `ALTER TABLE "GlobalOIDCProject" DROP CONSTRAINT "FK_e8522835aea64186bc53722f314"`,
171
+ );
172
+ await queryRunner.query(
173
+ `ALTER TABLE "GlobalOIDCProject" DROP CONSTRAINT "FK_8e4bf7b1571a065aad6feed4bca"`,
174
+ );
175
+ await queryRunner.query(
176
+ `ALTER TABLE "GlobalSSOProject" DROP CONSTRAINT "FK_91f47fc5d7c0f09bec7c9dd3e86"`,
177
+ );
178
+ await queryRunner.query(
179
+ `ALTER TABLE "GlobalSSOProject" DROP CONSTRAINT "FK_a58c789ff9fe63f416b01460840"`,
180
+ );
181
+ await queryRunner.query(
182
+ `ALTER TABLE "GlobalSSOProject" DROP CONSTRAINT "FK_71298cc376a253647839650fb0b"`,
183
+ );
184
+ await queryRunner.query(
185
+ `ALTER TABLE "GlobalOIDC" DROP CONSTRAINT "FK_0febb2e4c4d8703fce4bc816b36"`,
186
+ );
187
+ await queryRunner.query(
188
+ `ALTER TABLE "GlobalOIDC" DROP CONSTRAINT "FK_b04eac8e1886aefae5e2b16cddc"`,
189
+ );
190
+ await queryRunner.query(
191
+ `ALTER TABLE "GlobalSSO" DROP CONSTRAINT "FK_4f520827496e355d4bdfda66120"`,
192
+ );
193
+ await queryRunner.query(
194
+ `ALTER TABLE "GlobalSSO" DROP CONSTRAINT "FK_1003cf4114a89a4ff7ec16e7406"`,
195
+ );
196
+ await queryRunner.query(
197
+ `DROP INDEX "public"."IDX_c11b9a707701e7c10b5b86c9a2"`,
198
+ );
199
+ await queryRunner.query(
200
+ `DROP INDEX "public"."IDX_8c9b95c3d5d24e56c003467e82"`,
201
+ );
202
+ await queryRunner.query(
203
+ `DROP INDEX "public"."IDX_c088ff9d9ca99dd93a8cbeec50"`,
204
+ );
205
+ await queryRunner.query(
206
+ `DROP INDEX "public"."IDX_390d2b4b9718741c13a9bf3646"`,
207
+ );
208
+ await queryRunner.query(
209
+ `DROP INDEX "public"."IDX_e8522835aea64186bc53722f31"`,
210
+ );
211
+ await queryRunner.query(
212
+ `DROP INDEX "public"."IDX_8e4bf7b1571a065aad6feed4bc"`,
213
+ );
214
+ await queryRunner.query(
215
+ `DROP INDEX "public"."IDX_a58c789ff9fe63f416b0146084"`,
216
+ );
217
+ await queryRunner.query(
218
+ `DROP INDEX "public"."IDX_71298cc376a253647839650fb0"`,
219
+ );
220
+ await queryRunner.query(
221
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
222
+ );
223
+ await queryRunner.query(
224
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
225
+ );
226
+ await queryRunner.query(
227
+ `CREATE INDEX "IDX_GlobalOIDCProjectTeam_teamId" ON "GlobalOIDCProjectTeam" ("teamId") `,
228
+ );
229
+ await queryRunner.query(
230
+ `CREATE INDEX "IDX_GlobalOIDCProjectTeam_globalOidcProjectId" ON "GlobalOIDCProjectTeam" ("globalOidcProjectId") `,
231
+ );
232
+ await queryRunner.query(
233
+ `CREATE INDEX "IDX_GlobalSSOProjectTeam_teamId" ON "GlobalSSOProjectTeam" ("teamId") `,
234
+ );
235
+ await queryRunner.query(
236
+ `CREATE INDEX "IDX_GlobalSSOProjectTeam_globalSsoProjectId" ON "GlobalSSOProjectTeam" ("globalSsoProjectId") `,
237
+ );
238
+ await queryRunner.query(
239
+ `CREATE UNIQUE INDEX "IDX_GlobalOIDCProject_globalOidcId_projectId" ON "GlobalOIDCProject" ("globalOidcId", "projectId") `,
240
+ );
241
+ await queryRunner.query(
242
+ `CREATE INDEX "IDX_GlobalOIDCProject_projectId" ON "GlobalOIDCProject" ("projectId") `,
243
+ );
244
+ await queryRunner.query(
245
+ `CREATE INDEX "IDX_GlobalOIDCProject_globalOidcId" ON "GlobalOIDCProject" ("globalOidcId") `,
246
+ );
247
+ await queryRunner.query(
248
+ `CREATE UNIQUE INDEX "IDX_GlobalSSOProject_globalSsoId_projectId" ON "GlobalSSOProject" ("globalSsoId", "projectId") `,
249
+ );
250
+ await queryRunner.query(
251
+ `CREATE INDEX "IDX_GlobalSSOProject_projectId" ON "GlobalSSOProject" ("projectId") `,
252
+ );
253
+ await queryRunner.query(
254
+ `CREATE INDEX "IDX_GlobalSSOProject_globalSsoId" ON "GlobalSSOProject" ("globalSsoId") `,
255
+ );
256
+ await queryRunner.query(
257
+ `ALTER TABLE "GlobalOIDCProjectTeam" ADD CONSTRAINT "FK_GlobalOIDCProjectTeam_teamId" FOREIGN KEY ("teamId") REFERENCES "Team"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
258
+ );
259
+ await queryRunner.query(
260
+ `ALTER TABLE "GlobalOIDCProjectTeam" ADD CONSTRAINT "FK_GlobalOIDCProjectTeam_globalOidcProjectId" FOREIGN KEY ("globalOidcProjectId") REFERENCES "GlobalOIDCProject"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
261
+ );
262
+ await queryRunner.query(
263
+ `ALTER TABLE "GlobalSSOProjectTeam" ADD CONSTRAINT "FK_GlobalSSOProjectTeam_teamId" FOREIGN KEY ("teamId") REFERENCES "Team"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
264
+ );
265
+ await queryRunner.query(
266
+ `ALTER TABLE "GlobalSSOProjectTeam" ADD CONSTRAINT "FK_GlobalSSOProjectTeam_globalSsoProjectId" FOREIGN KEY ("globalSsoProjectId") REFERENCES "GlobalSSOProject"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
267
+ );
268
+ await queryRunner.query(
269
+ `ALTER TABLE "GlobalOIDCProject" ADD CONSTRAINT "FK_GlobalOIDCProject_createdByUserId" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
270
+ );
271
+ await queryRunner.query(
272
+ `ALTER TABLE "GlobalOIDCProject" ADD CONSTRAINT "FK_GlobalOIDCProject_projectId" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
273
+ );
274
+ await queryRunner.query(
275
+ `ALTER TABLE "GlobalOIDCProject" ADD CONSTRAINT "FK_GlobalOIDCProject_globalOidcId" FOREIGN KEY ("globalOidcId") REFERENCES "GlobalOIDC"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
276
+ );
277
+ await queryRunner.query(
278
+ `ALTER TABLE "GlobalSSOProject" ADD CONSTRAINT "FK_GlobalSSOProject_createdByUserId" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
279
+ );
280
+ await queryRunner.query(
281
+ `ALTER TABLE "GlobalSSOProject" ADD CONSTRAINT "FK_GlobalSSOProject_projectId" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
282
+ );
283
+ await queryRunner.query(
284
+ `ALTER TABLE "GlobalSSOProject" ADD CONSTRAINT "FK_GlobalSSOProject_globalSsoId" FOREIGN KEY ("globalSsoId") REFERENCES "GlobalSSO"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
285
+ );
286
+ await queryRunner.query(
287
+ `ALTER TABLE "GlobalOIDC" ADD CONSTRAINT "FK_GlobalOIDC_deletedByUserId" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
288
+ );
289
+ await queryRunner.query(
290
+ `ALTER TABLE "GlobalOIDC" ADD CONSTRAINT "FK_GlobalOIDC_createdByUserId" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
291
+ );
292
+ await queryRunner.query(
293
+ `ALTER TABLE "GlobalSSO" ADD CONSTRAINT "FK_GlobalSSO_deletedByUserId" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
294
+ );
295
+ await queryRunner.query(
296
+ `ALTER TABLE "GlobalSSO" ADD CONSTRAINT "FK_GlobalSSO_createdByUserId" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
297
+ );
298
+ }
299
+ }
@@ -0,0 +1,21 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class RemoveIsTestedFromGlobalSsoAndOidc1782400000000
4
+ implements MigrationInterface
5
+ {
6
+ public name = "RemoveIsTestedFromGlobalSsoAndOidc1782400000000";
7
+
8
+ public async up(queryRunner: QueryRunner): Promise<void> {
9
+ await queryRunner.query(`ALTER TABLE "GlobalSSO" DROP COLUMN "isTested"`);
10
+ await queryRunner.query(`ALTER TABLE "GlobalOIDC" DROP COLUMN "isTested"`);
11
+ }
12
+
13
+ public async down(queryRunner: QueryRunner): Promise<void> {
14
+ await queryRunner.query(
15
+ `ALTER TABLE "GlobalOIDC" ADD "isTested" boolean NOT NULL DEFAULT false`,
16
+ );
17
+ await queryRunner.query(
18
+ `ALTER TABLE "GlobalSSO" ADD "isTested" boolean NOT NULL DEFAULT false`,
19
+ );
20
+ }
21
+ }
@@ -386,10 +386,16 @@ import { MigrationName1781250074195 } from "./1781250074195-MigrationName";
386
386
  import { AddTelemetryEntityLabels1781300000000 } from "./1781300000000-AddTelemetryEntityLabels";
387
387
  import { AddServiceTelemetrySdkLanguage1781400000000 } from "./1781400000000-AddServiceTelemetrySdkLanguage";
388
388
  import { AddProxmoxAndCephClusterTables1781500000000 } from "./1781500000000-AddProxmoxAndCephClusterTables";
389
- import { MigrationName1781587937032 } from "./1781587937032-MigrationName";
390
389
  import { AddProxmoxCephV2Columns1781600000000 } from "./1781600000000-AddProxmoxCephV2Columns";
391
390
  import { AddProxmoxCephActivityAndRules1781600000001 } from "./1781600000001-AddProxmoxCephActivityAndRules";
392
391
  import { AddProxmoxCephV3Columns1781700000000 } from "./1781700000000-AddProxmoxCephV3Columns";
392
+ import { MigrationName1781750000000 } from "./1781750000000-MigrationName";
393
+ import { AddGlobalSsoAndOidc1782000000000 } from "./1782000000000-AddGlobalSsoAndOidc";
394
+ import { AddStatusPageImageAltText1782100000000 } from "./1782100000000-AddStatusPageImageAltText";
395
+ import { AddRequireSsoForLoginToGlobalProviders1782200000000 } from "./1782200000000-AddRequireSsoForLoginToGlobalProviders";
396
+ import { MoveRequireSsoForLoginToGlobalConfig1782300000000 } from "./1782300000000-MoveRequireSsoForLoginToGlobalConfig";
397
+ import { MigrationName1782310000000 } from "./1782310000000-MigrationName";
398
+ import { RemoveIsTestedFromGlobalSsoAndOidc1782400000000 } from "./1782400000000-RemoveIsTestedFromGlobalSsoAndOidc";
393
399
 
394
400
  export default [
395
401
  InitialMigration,
@@ -783,5 +789,11 @@ export default [
783
789
  AddProxmoxCephV2Columns1781600000000,
784
790
  AddProxmoxCephActivityAndRules1781600000001,
785
791
  AddProxmoxCephV3Columns1781700000000,
786
- MigrationName1781587937032,
792
+ MigrationName1781750000000,
793
+ AddGlobalSsoAndOidc1782000000000,
794
+ AddStatusPageImageAltText1782100000000,
795
+ AddRequireSsoForLoginToGlobalProviders1782200000000,
796
+ MoveRequireSsoForLoginToGlobalConfig1782300000000,
797
+ MigrationName1782310000000,
798
+ RemoveIsTestedFromGlobalSsoAndOidc1782400000000,
787
799
  ];
@@ -1,8 +1,8 @@
1
1
  import AccessTokenService from "../Services/AccessTokenService";
2
+ import GlobalConfigService from "../Services/GlobalConfigService";
2
3
  import ProjectService from "../Services/ProjectService";
3
4
  import TeamMemberService from "../Services/TeamMemberService";
4
5
  import UserService from "../Services/UserService";
5
- import QueryHelper from "../Types/Database/QueryHelper";
6
6
  import CookieUtil from "../Utils/Cookie";
7
7
  import {
8
8
  ExpressRequest,
@@ -16,7 +16,6 @@ import logger, { getLogAttributesFromRequest } from "../Utils/Logger";
16
16
  import Response from "../Utils/Response";
17
17
  import ProjectMiddleware from "./ProjectAuthorization";
18
18
  import SpanUtil from "../Utils/Telemetry/SpanUtil";
19
- import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
20
19
  import Dictionary from "../../Types/Dictionary";
21
20
  import Exception from "../../Types/Exception/Exception";
22
21
  import NotAuthenticatedException from "../../Types/Exception/NotAuthenticatedException";
@@ -35,7 +34,6 @@ import Permission, {
35
34
  UserTenantAccessPermission,
36
35
  } from "../../Types/Permission";
37
36
  import UserType from "../../Types/UserType";
38
- import Project from "../../Models/DatabaseModels/Project";
39
37
  import UserPermissionUtil from "../Utils/UserPermission/UserPermission";
40
38
 
41
39
  export default class UserMiddleware {
@@ -170,6 +168,7 @@ export default class UserMiddleware {
170
168
  req: ExpressRequest,
171
169
  projectId: ObjectID,
172
170
  userId: ObjectID,
171
+ requiredSsoProviderId?: ObjectID | undefined,
173
172
  ): boolean {
174
173
  const ssoTokens: Dictionary<string> = this.getSsoTokens(req);
175
174
 
@@ -181,6 +180,25 @@ export default class UserMiddleware {
181
180
  decodedData.projectId?.toString() === projectId.toString() &&
182
181
  decodedData.userId.toString() === userId.toString()
183
182
  ) {
183
+ /*
184
+ * Specific-IdP enforcement: when the project requires a specific SSO
185
+ * provider, the token must carry a matching `ssoProviderId`
186
+ * discriminator. Tokens issued before this field existed (no
187
+ * discriminator) do not satisfy a specific-provider requirement.
188
+ */
189
+ if (requiredSsoProviderId) {
190
+ const tokenProviderId: string | undefined = decodedData.ssoProviderId
191
+ ? decodedData.ssoProviderId.toString()
192
+ : undefined;
193
+
194
+ if (
195
+ !tokenProviderId ||
196
+ tokenProviderId !== requiredSsoProviderId.toString()
197
+ ) {
198
+ return false;
199
+ }
200
+ }
201
+
184
202
  return true;
185
203
  }
186
204
  }
@@ -493,12 +511,15 @@ export default class UserMiddleware {
493
511
  }): Promise<UserTenantAccessPermission | null> {
494
512
  const { req, tenantId, userId } = data;
495
513
 
514
+ const isMasterAdmin: boolean =
515
+ (req as OneUptimeRequest).userAuthorization?.isMasterAdmin === true;
516
+
496
517
  /*
497
518
  * Resolve the SSO requirement and the tenant permission in parallel.
498
519
  * `getRequireSsoForLogin` is cached in-process for 60s, so this is
499
520
  * usually free; the tenant permission lookup is the expensive call.
500
521
  */
501
- const [requireSsoForLogin, tenantPermission]: [
522
+ const [projectRequireSsoForLogin, tenantPermission]: [
502
523
  boolean,
503
524
  UserTenantAccessPermission | null,
504
525
  ] = await Promise.all([
@@ -515,11 +536,42 @@ export default class UserMiddleware {
515
536
  AccessTokenService.getUserTenantAccessPermission(userId, tenantId),
516
537
  ]);
517
538
 
518
- if (
519
- requireSsoForLogin &&
520
- !UserMiddleware.doesSsoTokenForProjectExist(req, tenantId, userId)
521
- ) {
522
- throw new SsoAuthorizationException();
539
+ /*
540
+ * The instance-wide "Require SSO for Login" flag (GlobalConfig) forces SSO
541
+ * on every project. Master admins are exempt so a misconfigured global SSO
542
+ * can't lock them out — a project's own requireSsoForLogin still applies to
543
+ * them. Only checked when the project doesn't already enforce SSO.
544
+ */
545
+ let requireSsoForLogin: boolean = projectRequireSsoForLogin;
546
+ if (!requireSsoForLogin && !isMasterAdmin) {
547
+ requireSsoForLogin =
548
+ await GlobalConfigService.getRequireSsoForLogin().catch(() => {
549
+ return false;
550
+ });
551
+ }
552
+
553
+ if (requireSsoForLogin) {
554
+ /*
555
+ * Only resolve the specific-provider requirement when SSO is enforced.
556
+ * The provider-id cache is already warm from getRequireSsoForLogin above.
557
+ */
558
+ const requiredSsoProviderId: ObjectID | null =
559
+ await ProjectService.getRequireSsoWithSsoProviderId(tenantId).catch(
560
+ () => {
561
+ return null;
562
+ },
563
+ );
564
+
565
+ if (
566
+ !UserMiddleware.doesSsoTokenForProjectExist(
567
+ req,
568
+ tenantId,
569
+ userId,
570
+ requiredSsoProviderId ?? undefined,
571
+ )
572
+ ) {
573
+ throw new SsoAuthorizationException();
574
+ }
523
575
  }
524
576
 
525
577
  return tenantPermission;
@@ -535,48 +587,67 @@ export default class UserMiddleware {
535
587
  return null;
536
588
  }
537
589
 
538
- const projects: Array<Project> = await ProjectService.findBy({
539
- query: {
540
- _id: QueryHelper.any(
541
- projectIds.map((i: ObjectID) => {
542
- return i.toString();
543
- }) || [],
544
- ),
545
- },
546
- select: {
547
- requireSsoForLogin: true,
548
- },
549
- limit: LIMIT_PER_PROJECT,
550
- skip: 0,
551
- props: {
552
- isRoot: true,
553
- },
554
- });
590
+ const isMasterAdmin: boolean =
591
+ (req as OneUptimeRequest).userAuthorization?.isMasterAdmin === true;
592
+
593
+ /*
594
+ * Instance-wide "Require SSO for Login" forces SSO on every project. Master
595
+ * admins are exempt. Resolved once (cached) rather than per project.
596
+ */
597
+ const globalRequireSsoForLogin: boolean = isMasterAdmin
598
+ ? false
599
+ : await GlobalConfigService.getRequireSsoForLogin().catch(() => {
600
+ return false;
601
+ });
555
602
 
556
603
  /*
557
- * Resolve permissions for every project in parallel. With the previous
558
- * for-await loop this scaled linearly with project count, adding one
559
- * round-trip per project even on cache hits.
604
+ * Resolve permissions for every project in parallel. A project's own
605
+ * requireSsoForLogin is read through the cached getter; the global flag is
606
+ * OR'd in so enforcement matches the single-tenant path.
560
607
  */
561
608
  const resolved: Array<{
562
609
  projectId: ObjectID;
563
610
  permission: UserTenantAccessPermission | null;
564
611
  }> = await Promise.all(
565
612
  projectIds.map(async (projectId: ObjectID) => {
566
- if (
567
- projects.find((p: Project) => {
568
- return p._id === projectId.toString() && p.requireSsoForLogin;
569
- }) &&
570
- !UserMiddleware.doesSsoTokenForProjectExist(req, projectId, userId)
571
- ) {
572
- return {
573
- projectId,
574
- permission:
575
- UserPermissionUtil.getDefaultUserTenantAccessPermission(
576
- projectId,
577
- ),
578
- };
613
+ const projectRequireSsoForLogin: boolean =
614
+ await ProjectService.getRequireSsoForLogin(projectId).catch(() => {
615
+ /*
616
+ * Unknown/inaccessible project: do not enforce SSO here. Actual
617
+ * access is still gated by AccessTokenService below.
618
+ */
619
+ return false;
620
+ });
621
+
622
+ const requireSsoForLogin: boolean =
623
+ projectRequireSsoForLogin || globalRequireSsoForLogin;
624
+
625
+ if (requireSsoForLogin) {
626
+ const requiredSsoProviderId: ObjectID | null =
627
+ await ProjectService.getRequireSsoWithSsoProviderId(
628
+ projectId,
629
+ ).catch(() => {
630
+ return null;
631
+ });
632
+
633
+ if (
634
+ !UserMiddleware.doesSsoTokenForProjectExist(
635
+ req,
636
+ projectId,
637
+ userId,
638
+ requiredSsoProviderId ?? undefined,
639
+ )
640
+ ) {
641
+ return {
642
+ projectId,
643
+ permission:
644
+ UserPermissionUtil.getDefaultUserTenantAccessPermission(
645
+ projectId,
646
+ ),
647
+ };
648
+ }
579
649
  }
650
+
580
651
  return {
581
652
  projectId,
582
653
  permission: await AccessTokenService.getUserTenantAccessPermission(
@@ -200,21 +200,33 @@ export class Service extends DatabaseService<Model> {
200
200
  )
201
201
  .digest("hex");
202
202
 
203
- const cached: string | null = await GlobalCache.getString(
204
- LAST_SEEN_CACHE_NAMESPACE,
205
- cacheKey,
206
- );
203
+ let cached: string | null = null;
204
+ try {
205
+ cached = await GlobalCache.getString(LAST_SEEN_CACHE_NAMESPACE, cacheKey);
206
+ } catch {
207
+ /*
208
+ * Cache unavailable — fail open and refresh lastSeenAt anyway. A
209
+ * cache error must never skip the DB write below, otherwise the
210
+ * resource is wrongly marked "disconnected" while telemetry is
211
+ * still flowing. Mirrors shouldRunMaintenance's fail-open stance.
212
+ */
213
+ cached = null;
214
+ }
207
215
 
208
216
  if (cached === extrasFingerprint) {
209
217
  return; // same data was written recently
210
218
  }
211
219
 
212
- await GlobalCache.setString(
213
- LAST_SEEN_CACHE_NAMESPACE,
214
- cacheKey,
215
- extrasFingerprint,
216
- { expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS },
217
- );
220
+ try {
221
+ await GlobalCache.setString(
222
+ LAST_SEEN_CACHE_NAMESPACE,
223
+ cacheKey,
224
+ extrasFingerprint,
225
+ { expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS },
226
+ );
227
+ } catch {
228
+ // Best-effort throttle write; proceed with the DB update regardless.
229
+ }
218
230
 
219
231
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
220
232
  const data: any = {
@@ -170,21 +170,33 @@ export class Service extends DatabaseService<Model> {
170
170
  )
171
171
  .digest("hex");
172
172
 
173
- const cached: string | null = await GlobalCache.getString(
174
- LAST_SEEN_CACHE_NAMESPACE,
175
- cacheKey,
176
- );
173
+ let cached: string | null = null;
174
+ try {
175
+ cached = await GlobalCache.getString(LAST_SEEN_CACHE_NAMESPACE, cacheKey);
176
+ } catch {
177
+ /*
178
+ * Cache unavailable — fail open and refresh lastSeenAt anyway. A
179
+ * cache error must never skip the DB write below, otherwise the
180
+ * resource is wrongly marked "disconnected" while telemetry is
181
+ * still flowing. Mirrors shouldRunMaintenance's fail-open stance.
182
+ */
183
+ cached = null;
184
+ }
177
185
 
178
186
  if (cached === extrasFingerprint) {
179
187
  return; // same data was written recently
180
188
  }
181
189
 
182
- await GlobalCache.setString(
183
- LAST_SEEN_CACHE_NAMESPACE,
184
- cacheKey,
185
- extrasFingerprint,
186
- { expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS },
187
- );
190
+ try {
191
+ await GlobalCache.setString(
192
+ LAST_SEEN_CACHE_NAMESPACE,
193
+ cacheKey,
194
+ extrasFingerprint,
195
+ { expiresInSeconds: LAST_SEEN_THROTTLE_SECONDS },
196
+ );
197
+ } catch {
198
+ // Best-effort throttle write; proceed with the DB update regardless.
199
+ }
188
200
 
189
201
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
190
202
  const data: any = {