@oneuptime/common 11.0.3 → 11.0.4
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/Models/DatabaseModels/GlobalConfig.ts +19 -0
- package/Models/DatabaseModels/GlobalOidc.ts +351 -0
- package/Models/DatabaseModels/GlobalOidcProject.ts +265 -0
- package/Models/DatabaseModels/GlobalSso.ts +312 -0
- package/Models/DatabaseModels/GlobalSsoProject.ts +268 -0
- package/Models/DatabaseModels/Index.ts +8 -0
- package/Models/DatabaseModels/Project.ts +31 -0
- package/Models/DatabaseModels/StatusPage.ts +82 -0
- package/Server/API/StatusPageAPI.ts +2 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/{1781587937032-MigrationName.ts → 1781750000000-MigrationName.ts} +2 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1782000000000-AddGlobalSsoAndOidc.ts +176 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1782100000000-AddStatusPageImageAltText.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1782200000000-AddRequireSsoForLoginToGlobalProviders.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1782300000000-MoveRequireSsoForLoginToGlobalConfig.ts +38 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1782310000000-MigrationName.ts +299 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1782400000000-RemoveIsTestedFromGlobalSsoAndOidc.ts +21 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -2
- package/Server/Middleware/UserAuthorization.ts +113 -42
- package/Server/Services/GlobalConfigService.ts +50 -0
- package/Server/Services/GlobalOidcProjectService.ts +85 -0
- package/Server/Services/GlobalOidcService.ts +10 -0
- package/Server/Services/GlobalSsoProjectService.ts +85 -0
- package/Server/Services/GlobalSsoService.ts +10 -0
- package/Server/Services/Index.ts +8 -0
- package/Server/Services/ProjectService.ts +44 -1
- package/Server/Utils/Cookie.ts +39 -5
- package/Server/Utils/JsonWebToken.ts +7 -0
- package/Server/Utils/ValidateGlobalProviderProjectTeams.ts +119 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +51 -13
- package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +163 -0
- package/Tests/Server/Utils/CookieSSOToken.test.ts +130 -0
- package/Types/JsonWebTokenData.ts +3 -0
- package/Types/SSO/SsoProviderType.ts +8 -0
- package/UI/Components/Accordion/Accordion.tsx +5 -1
- package/UI/Components/CardSelect/CardSelect.tsx +6 -1
- package/UI/Components/CategoryCheckbox/Index.tsx +2 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +2 -0
- package/UI/Components/CollapsibleSection/CollapsibleSection.tsx +8 -1
- package/UI/Components/Dropdown/Dropdown.tsx +2 -0
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +3 -0
- package/UI/Components/FilePicker/FilePicker.tsx +2 -0
- package/UI/Components/Forms/Fields/ColorPicker.tsx +2 -0
- package/UI/Components/Forms/Fields/FieldLabel.tsx +4 -0
- package/UI/Components/Forms/Fields/FormField.tsx +72 -15
- package/UI/Components/Forms/Fields/IconPicker.tsx +2 -0
- package/UI/Components/Forms/Validation.ts +107 -23
- package/UI/Components/Input/Input.tsx +4 -0
- package/UI/Components/Link/Link.tsx +23 -0
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +3 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +63 -2
- package/UI/Components/Radio/Radio.tsx +2 -0
- package/UI/Components/RadioButtons/GroupRadioButtons.tsx +6 -1
- package/UI/Components/Tabs/Tabs.tsx +63 -0
- package/UI/Components/TextArea/TextArea.tsx +2 -0
- package/UI/Components/TimePicker/TimePicker.tsx +2 -0
- package/UI/Components/Toggle/Toggle.tsx +2 -1
- package/UI/Components/Tooltip/Tooltip.tsx +6 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +20 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +379 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -0
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +276 -0
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -0
- package/build/dist/Models/DatabaseModels/GlobalSso.js +341 -0
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -0
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +279 -0
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +8 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +32 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +84 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +2 -0
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/{1781587937032-MigrationName.js → 1781750000000-MigrationName.js} +3 -3
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/{1781587937032-MigrationName.js.map → 1781750000000-MigrationName.js.map} +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782000000000-AddGlobalSsoAndOidc.js +73 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782000000000-AddGlobalSsoAndOidc.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782100000000-AddStatusPageImageAltText.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782100000000-AddStatusPageImageAltText.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782200000000-AddRequireSsoForLoginToGlobalProviders.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782200000000-AddRequireSsoForLoginToGlobalProviders.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782300000000-MoveRequireSsoForLoginToGlobalConfig.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782300000000-MoveRequireSsoForLoginToGlobalConfig.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782310000000-MigrationName.js +106 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782310000000-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782400000000-RemoveIsTestedFromGlobalSsoAndOidc.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1782400000000-RemoveIsTestedFromGlobalSsoAndOidc.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -2
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +77 -34
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +55 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcProjectService.js +80 -0
- package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -0
- package/build/dist/Server/Services/GlobalOidcService.js +9 -0
- package/build/dist/Server/Services/GlobalOidcService.js.map +1 -0
- package/build/dist/Server/Services/GlobalSsoProjectService.js +80 -0
- package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -0
- package/build/dist/Server/Services/GlobalSsoService.js +9 -0
- package/build/dist/Server/Services/GlobalSsoService.js.map +1 -0
- package/build/dist/Server/Services/Index.js +8 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +36 -1
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Utils/Cookie.js +32 -3
- package/build/dist/Server/Utils/Cookie.js.map +1 -1
- package/build/dist/Server/Utils/JsonWebToken.js +6 -0
- package/build/dist/Server/Utils/JsonWebToken.js.map +1 -1
- package/build/dist/Server/Utils/ValidateGlobalProviderProjectTeams.js +66 -0
- package/build/dist/Server/Utils/ValidateGlobalProviderProjectTeams.js.map +1 -0
- package/build/dist/Types/SSO/SsoProviderType.js +9 -0
- package/build/dist/Types/SSO/SsoProviderType.js.map +1 -0
- package/build/dist/UI/Components/Accordion/Accordion.js +5 -3
- package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
- package/build/dist/UI/Components/CardSelect/CardSelect.js +1 -1
- package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
- package/build/dist/UI/Components/CategoryCheckbox/Index.js +1 -1
- package/build/dist/UI/Components/CategoryCheckbox/Index.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/CollapsibleSection/CollapsibleSection.js +4 -2
- package/build/dist/UI/Components/CollapsibleSection/CollapsibleSection.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +2 -2
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/FilePicker/FilePicker.js +1 -1
- package/build/dist/UI/Components/FilePicker/FilePicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FieldLabel.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/FieldLabel.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +58 -22
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +64 -15
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +1 -1
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/Link/Link.js +22 -1
- package/build/dist/UI/Components/Link/Link.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +2 -2
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +46 -2
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Radio/Radio.js +1 -1
- package/build/dist/UI/Components/Radio/Radio.js.map +1 -1
- package/build/dist/UI/Components/RadioButtons/GroupRadioButtons.js +1 -1
- package/build/dist/UI/Components/RadioButtons/GroupRadioButtons.js.map +1 -1
- package/build/dist/UI/Components/Tabs/Tabs.js +50 -1
- package/build/dist/UI/Components/Tabs/Tabs.js.map +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
- package/build/dist/UI/Components/TimePicker/TimePicker.js +1 -1
- package/build/dist/UI/Components/TimePicker/TimePicker.js.map +1 -1
- package/build/dist/UI/Components/Toggle/Toggle.js +1 -1
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +6 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import User from "./User";
|
|
2
|
+
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
|
3
|
+
import Route from "../../Types/API/Route";
|
|
4
|
+
import URL from "../../Types/API/URL";
|
|
5
|
+
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
|
6
|
+
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
|
7
|
+
import TableEditionAccessControl from "../../Types/Database/AccessControl/TableEditionAccessControl";
|
|
8
|
+
import ColumnLength from "../../Types/Database/ColumnLength";
|
|
9
|
+
import ColumnType from "../../Types/Database/ColumnType";
|
|
10
|
+
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
|
11
|
+
import TableColumn from "../../Types/Database/TableColumn";
|
|
12
|
+
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
13
|
+
import TableMetadata from "../../Types/Database/TableMetadata";
|
|
14
|
+
import IconProp from "../../Types/Icon/IconProp";
|
|
15
|
+
import ObjectID from "../../Types/ObjectID";
|
|
16
|
+
import DigestMethod from "../../Types/SSO/DigestMethod";
|
|
17
|
+
import SignatureMethod from "../../Types/SSO/SignatureMethod";
|
|
18
|
+
import { Column, Entity, JoinColumn, ManyToOne } from "typeorm";
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* GlobalSSO is an instance-level (non-tenant) SAML 2.0 identity provider.
|
|
22
|
+
* It is configured by a master admin in the Admin Dashboard and is NOT scoped
|
|
23
|
+
* to any single project. It can be attached to specific projects (via
|
|
24
|
+
* GlobalSSOProject) or, when no project is attached, applies to every project
|
|
25
|
+
* the federated user is already a member of. Access is restricted to master
|
|
26
|
+
* admins through empty access-control arrays (master-admin/isRoot bypass).
|
|
27
|
+
*/
|
|
28
|
+
@TableEditionAccessControl({
|
|
29
|
+
requiresEnterprise: true,
|
|
30
|
+
})
|
|
31
|
+
@TableAccessControl({
|
|
32
|
+
create: [],
|
|
33
|
+
read: [],
|
|
34
|
+
delete: [],
|
|
35
|
+
update: [],
|
|
36
|
+
})
|
|
37
|
+
@CrudApiEndpoint(new Route("/global-sso"))
|
|
38
|
+
@TableMetadata({
|
|
39
|
+
tableName: "GlobalSSO",
|
|
40
|
+
singularName: "Global SSO",
|
|
41
|
+
pluralName: "Global SSO",
|
|
42
|
+
icon: IconProp.Lock,
|
|
43
|
+
tableDescription:
|
|
44
|
+
"Instance-wide SAML SSO that can be connected to any project on this OneUptime server",
|
|
45
|
+
})
|
|
46
|
+
@Entity({
|
|
47
|
+
name: "GlobalSSO",
|
|
48
|
+
})
|
|
49
|
+
export default class GlobalSSO extends BaseModel {
|
|
50
|
+
@ColumnAccessControl({
|
|
51
|
+
create: [],
|
|
52
|
+
read: [],
|
|
53
|
+
update: [],
|
|
54
|
+
})
|
|
55
|
+
@TableColumn({
|
|
56
|
+
required: true,
|
|
57
|
+
type: TableColumnType.ShortText,
|
|
58
|
+
title: "Name",
|
|
59
|
+
description: "Any friendly name of this SSO provider",
|
|
60
|
+
example: "Okta SAML (Company-wide)",
|
|
61
|
+
})
|
|
62
|
+
@Column({
|
|
63
|
+
nullable: false,
|
|
64
|
+
type: ColumnType.ShortText,
|
|
65
|
+
length: ColumnLength.ShortText,
|
|
66
|
+
})
|
|
67
|
+
public name?: string = undefined;
|
|
68
|
+
|
|
69
|
+
@ColumnAccessControl({
|
|
70
|
+
create: [],
|
|
71
|
+
read: [],
|
|
72
|
+
update: [],
|
|
73
|
+
})
|
|
74
|
+
@TableColumn({
|
|
75
|
+
required: true,
|
|
76
|
+
type: TableColumnType.LongText,
|
|
77
|
+
title: "Description",
|
|
78
|
+
description: "Friendly description of this SSO provider",
|
|
79
|
+
})
|
|
80
|
+
@Column({
|
|
81
|
+
nullable: false,
|
|
82
|
+
type: ColumnType.LongText,
|
|
83
|
+
})
|
|
84
|
+
public description?: string = undefined;
|
|
85
|
+
|
|
86
|
+
@ColumnAccessControl({
|
|
87
|
+
create: [],
|
|
88
|
+
read: [],
|
|
89
|
+
update: [],
|
|
90
|
+
})
|
|
91
|
+
@TableColumn({
|
|
92
|
+
required: true,
|
|
93
|
+
type: TableColumnType.ShortText,
|
|
94
|
+
title: "Signature Method",
|
|
95
|
+
description: "Signature Method used by this SSO provider",
|
|
96
|
+
example: "RSA-SHA256",
|
|
97
|
+
})
|
|
98
|
+
@Column({
|
|
99
|
+
nullable: false,
|
|
100
|
+
type: ColumnType.ShortText,
|
|
101
|
+
length: ColumnLength.ShortText,
|
|
102
|
+
})
|
|
103
|
+
public signatureMethod?: SignatureMethod = undefined;
|
|
104
|
+
|
|
105
|
+
@ColumnAccessControl({
|
|
106
|
+
create: [],
|
|
107
|
+
read: [],
|
|
108
|
+
update: [],
|
|
109
|
+
})
|
|
110
|
+
@TableColumn({
|
|
111
|
+
required: true,
|
|
112
|
+
type: TableColumnType.ShortText,
|
|
113
|
+
title: "Digest Method",
|
|
114
|
+
description: "Digest Method used by this SSO provider",
|
|
115
|
+
example: "SHA256",
|
|
116
|
+
})
|
|
117
|
+
@Column({
|
|
118
|
+
nullable: false,
|
|
119
|
+
type: ColumnType.ShortText,
|
|
120
|
+
length: ColumnLength.ShortText,
|
|
121
|
+
})
|
|
122
|
+
public digestMethod?: DigestMethod = undefined;
|
|
123
|
+
|
|
124
|
+
@ColumnAccessControl({
|
|
125
|
+
create: [],
|
|
126
|
+
read: [],
|
|
127
|
+
update: [],
|
|
128
|
+
})
|
|
129
|
+
@TableColumn({
|
|
130
|
+
required: true,
|
|
131
|
+
type: TableColumnType.LongURL,
|
|
132
|
+
title: "Sign on URL",
|
|
133
|
+
description: "Sign on URL (IdP SSO endpoint) of this SSO provider",
|
|
134
|
+
example: "https://example.com/saml/sso",
|
|
135
|
+
})
|
|
136
|
+
@Column({
|
|
137
|
+
nullable: false,
|
|
138
|
+
type: ColumnType.LongURL,
|
|
139
|
+
transformer: URL.getDatabaseTransformer(),
|
|
140
|
+
})
|
|
141
|
+
public signOnURL?: URL = undefined;
|
|
142
|
+
|
|
143
|
+
@ColumnAccessControl({
|
|
144
|
+
create: [],
|
|
145
|
+
read: [],
|
|
146
|
+
update: [],
|
|
147
|
+
})
|
|
148
|
+
@TableColumn({
|
|
149
|
+
required: true,
|
|
150
|
+
type: TableColumnType.VeryLongText,
|
|
151
|
+
title: "Issuer URL",
|
|
152
|
+
description: "Issuer URL (Entity ID) of this SSO provider",
|
|
153
|
+
example: "https://example.com/saml/metadata",
|
|
154
|
+
})
|
|
155
|
+
@Column({
|
|
156
|
+
nullable: false,
|
|
157
|
+
type: ColumnType.VeryLongText,
|
|
158
|
+
})
|
|
159
|
+
public issuerURL?: string = undefined;
|
|
160
|
+
|
|
161
|
+
@ColumnAccessControl({
|
|
162
|
+
create: [],
|
|
163
|
+
read: [],
|
|
164
|
+
update: [],
|
|
165
|
+
})
|
|
166
|
+
@TableColumn({
|
|
167
|
+
required: true,
|
|
168
|
+
type: TableColumnType.VeryLongText,
|
|
169
|
+
title: "Public Certificate",
|
|
170
|
+
description:
|
|
171
|
+
"Public X.509 signing certificate of this SSO provider used to validate SAML assertions",
|
|
172
|
+
})
|
|
173
|
+
@Column({
|
|
174
|
+
nullable: false,
|
|
175
|
+
type: ColumnType.VeryLongText,
|
|
176
|
+
})
|
|
177
|
+
public publicCertificate?: string = undefined;
|
|
178
|
+
|
|
179
|
+
@ColumnAccessControl({
|
|
180
|
+
create: [],
|
|
181
|
+
read: [],
|
|
182
|
+
update: [],
|
|
183
|
+
})
|
|
184
|
+
@TableColumn({
|
|
185
|
+
isDefaultValueColumn: true,
|
|
186
|
+
type: TableColumnType.Boolean,
|
|
187
|
+
title: "Disable Sign Up with SSO",
|
|
188
|
+
description:
|
|
189
|
+
"When enabled, users must be explicitly invited to a project before they can log in with this SSO provider. Brand new users are never created automatically.",
|
|
190
|
+
defaultValue: false,
|
|
191
|
+
example: true,
|
|
192
|
+
})
|
|
193
|
+
@Column({
|
|
194
|
+
type: ColumnType.Boolean,
|
|
195
|
+
default: false,
|
|
196
|
+
})
|
|
197
|
+
public disableSignUpWithSso?: boolean = undefined;
|
|
198
|
+
|
|
199
|
+
@ColumnAccessControl({
|
|
200
|
+
create: [],
|
|
201
|
+
read: [],
|
|
202
|
+
update: [],
|
|
203
|
+
})
|
|
204
|
+
@TableColumn({
|
|
205
|
+
isDefaultValueColumn: true,
|
|
206
|
+
type: TableColumnType.Boolean,
|
|
207
|
+
title: "Enabled",
|
|
208
|
+
description: "Is this SSO provider enabled?",
|
|
209
|
+
defaultValue: false,
|
|
210
|
+
example: true,
|
|
211
|
+
})
|
|
212
|
+
@Column({
|
|
213
|
+
type: ColumnType.Boolean,
|
|
214
|
+
default: false,
|
|
215
|
+
})
|
|
216
|
+
public isEnabled?: boolean = undefined;
|
|
217
|
+
|
|
218
|
+
@ColumnAccessControl({
|
|
219
|
+
create: [],
|
|
220
|
+
read: [],
|
|
221
|
+
update: [],
|
|
222
|
+
})
|
|
223
|
+
@TableColumn({
|
|
224
|
+
manyToOneRelationColumn: "createdByUserId",
|
|
225
|
+
type: TableColumnType.Entity,
|
|
226
|
+
modelType: User,
|
|
227
|
+
title: "Created by User",
|
|
228
|
+
description:
|
|
229
|
+
"Relation to User who created this object (if this object was created by a User)",
|
|
230
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
231
|
+
})
|
|
232
|
+
@ManyToOne(
|
|
233
|
+
() => {
|
|
234
|
+
return User;
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
eager: false,
|
|
238
|
+
nullable: true,
|
|
239
|
+
onDelete: "SET NULL",
|
|
240
|
+
orphanedRowAction: "nullify",
|
|
241
|
+
},
|
|
242
|
+
)
|
|
243
|
+
@JoinColumn({ name: "createdByUserId" })
|
|
244
|
+
public createdByUser?: User = undefined;
|
|
245
|
+
|
|
246
|
+
@ColumnAccessControl({
|
|
247
|
+
create: [],
|
|
248
|
+
read: [],
|
|
249
|
+
update: [],
|
|
250
|
+
})
|
|
251
|
+
@TableColumn({
|
|
252
|
+
type: TableColumnType.ObjectID,
|
|
253
|
+
title: "Created by User ID",
|
|
254
|
+
description:
|
|
255
|
+
"User ID who created this object (if this object was created by a User)",
|
|
256
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
257
|
+
})
|
|
258
|
+
@Column({
|
|
259
|
+
type: ColumnType.ObjectID,
|
|
260
|
+
nullable: true,
|
|
261
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
262
|
+
})
|
|
263
|
+
public createdByUserId?: ObjectID = undefined;
|
|
264
|
+
|
|
265
|
+
@ColumnAccessControl({
|
|
266
|
+
create: [],
|
|
267
|
+
read: [],
|
|
268
|
+
update: [],
|
|
269
|
+
})
|
|
270
|
+
@TableColumn({
|
|
271
|
+
manyToOneRelationColumn: "deletedByUserId",
|
|
272
|
+
type: TableColumnType.Entity,
|
|
273
|
+
title: "Deleted by User",
|
|
274
|
+
modelType: User,
|
|
275
|
+
description:
|
|
276
|
+
"Relation to User who deleted this object (if this object was deleted by a User)",
|
|
277
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
278
|
+
})
|
|
279
|
+
@ManyToOne(
|
|
280
|
+
() => {
|
|
281
|
+
return User;
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
cascade: false,
|
|
285
|
+
eager: false,
|
|
286
|
+
nullable: true,
|
|
287
|
+
onDelete: "SET NULL",
|
|
288
|
+
orphanedRowAction: "nullify",
|
|
289
|
+
},
|
|
290
|
+
)
|
|
291
|
+
@JoinColumn({ name: "deletedByUserId" })
|
|
292
|
+
public deletedByUser?: User = undefined;
|
|
293
|
+
|
|
294
|
+
@ColumnAccessControl({
|
|
295
|
+
create: [],
|
|
296
|
+
read: [],
|
|
297
|
+
update: [],
|
|
298
|
+
})
|
|
299
|
+
@TableColumn({
|
|
300
|
+
type: TableColumnType.ObjectID,
|
|
301
|
+
title: "Deleted by User ID",
|
|
302
|
+
description:
|
|
303
|
+
"User ID who deleted this object (if this object was deleted by a User)",
|
|
304
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
305
|
+
})
|
|
306
|
+
@Column({
|
|
307
|
+
type: ColumnType.ObjectID,
|
|
308
|
+
nullable: true,
|
|
309
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
310
|
+
})
|
|
311
|
+
public deletedByUserId?: ObjectID = undefined;
|
|
312
|
+
}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import GlobalSSO from "./GlobalSso";
|
|
2
|
+
import Project from "./Project";
|
|
3
|
+
import Team from "./Team";
|
|
4
|
+
import User from "./User";
|
|
5
|
+
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
|
6
|
+
import Route from "../../Types/API/Route";
|
|
7
|
+
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
|
8
|
+
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
|
9
|
+
import TableEditionAccessControl from "../../Types/Database/AccessControl/TableEditionAccessControl";
|
|
10
|
+
import ColumnType from "../../Types/Database/ColumnType";
|
|
11
|
+
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
|
12
|
+
import TableColumn from "../../Types/Database/TableColumn";
|
|
13
|
+
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
14
|
+
import TableMetadata from "../../Types/Database/TableMetadata";
|
|
15
|
+
import IconProp from "../../Types/Icon/IconProp";
|
|
16
|
+
import ObjectID from "../../Types/ObjectID";
|
|
17
|
+
import {
|
|
18
|
+
Column,
|
|
19
|
+
Entity,
|
|
20
|
+
Index,
|
|
21
|
+
JoinColumn,
|
|
22
|
+
JoinTable,
|
|
23
|
+
ManyToMany,
|
|
24
|
+
ManyToOne,
|
|
25
|
+
} from "typeorm";
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
* GlobalSSOProject attaches a GlobalSSO provider to a specific project and
|
|
29
|
+
* defines the default teams a federated user is provisioned into on first
|
|
30
|
+
* login. This is also the privilege-escalation allow-list: a SAML assertion
|
|
31
|
+
* can only ever provision a user into projects that a master admin has
|
|
32
|
+
* explicitly attached here. If a GlobalSSO has NO attached projects, it
|
|
33
|
+
* applies to all projects the user is already a member of (invite-first).
|
|
34
|
+
*/
|
|
35
|
+
@TableEditionAccessControl({
|
|
36
|
+
requiresEnterprise: true,
|
|
37
|
+
})
|
|
38
|
+
@TableAccessControl({
|
|
39
|
+
create: [],
|
|
40
|
+
read: [],
|
|
41
|
+
delete: [],
|
|
42
|
+
update: [],
|
|
43
|
+
})
|
|
44
|
+
@CrudApiEndpoint(new Route("/global-sso-project"))
|
|
45
|
+
@TableMetadata({
|
|
46
|
+
tableName: "GlobalSSOProject",
|
|
47
|
+
singularName: "Global SSO Project",
|
|
48
|
+
pluralName: "Global SSO Projects",
|
|
49
|
+
icon: IconProp.Lock,
|
|
50
|
+
tableDescription:
|
|
51
|
+
"Attaches an instance-wide SAML SSO provider to a project with default teams",
|
|
52
|
+
})
|
|
53
|
+
@Entity({
|
|
54
|
+
name: "GlobalSSOProject",
|
|
55
|
+
})
|
|
56
|
+
export default class GlobalSSOProject extends BaseModel {
|
|
57
|
+
@ColumnAccessControl({
|
|
58
|
+
create: [],
|
|
59
|
+
read: [],
|
|
60
|
+
update: [],
|
|
61
|
+
})
|
|
62
|
+
@TableColumn({
|
|
63
|
+
manyToOneRelationColumn: "globalSsoId",
|
|
64
|
+
type: TableColumnType.Entity,
|
|
65
|
+
modelType: GlobalSSO,
|
|
66
|
+
title: "Global SSO",
|
|
67
|
+
description:
|
|
68
|
+
"Relation to the Global SSO provider this attachment belongs to",
|
|
69
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
70
|
+
})
|
|
71
|
+
@ManyToOne(
|
|
72
|
+
() => {
|
|
73
|
+
return GlobalSSO;
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
eager: false,
|
|
77
|
+
nullable: false,
|
|
78
|
+
onDelete: "CASCADE",
|
|
79
|
+
orphanedRowAction: "nullify",
|
|
80
|
+
},
|
|
81
|
+
)
|
|
82
|
+
@JoinColumn({ name: "globalSsoId" })
|
|
83
|
+
public globalSso?: GlobalSSO = undefined;
|
|
84
|
+
|
|
85
|
+
@ColumnAccessControl({
|
|
86
|
+
create: [],
|
|
87
|
+
read: [],
|
|
88
|
+
update: [],
|
|
89
|
+
})
|
|
90
|
+
@Index()
|
|
91
|
+
@TableColumn({
|
|
92
|
+
type: TableColumnType.ObjectID,
|
|
93
|
+
required: true,
|
|
94
|
+
canReadOnRelationQuery: true,
|
|
95
|
+
title: "Global SSO ID",
|
|
96
|
+
description: "ID of the Global SSO provider this attachment belongs to",
|
|
97
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
98
|
+
})
|
|
99
|
+
@Column({
|
|
100
|
+
type: ColumnType.ObjectID,
|
|
101
|
+
nullable: false,
|
|
102
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
103
|
+
})
|
|
104
|
+
public globalSsoId?: ObjectID = undefined;
|
|
105
|
+
|
|
106
|
+
@ColumnAccessControl({
|
|
107
|
+
create: [],
|
|
108
|
+
read: [],
|
|
109
|
+
update: [],
|
|
110
|
+
})
|
|
111
|
+
@TableColumn({
|
|
112
|
+
manyToOneRelationColumn: "projectId",
|
|
113
|
+
type: TableColumnType.Entity,
|
|
114
|
+
modelType: Project,
|
|
115
|
+
title: "Project",
|
|
116
|
+
description: "Relation to the Project this SSO provider is attached to",
|
|
117
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
118
|
+
})
|
|
119
|
+
@ManyToOne(
|
|
120
|
+
() => {
|
|
121
|
+
return Project;
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
eager: false,
|
|
125
|
+
nullable: false,
|
|
126
|
+
onDelete: "CASCADE",
|
|
127
|
+
orphanedRowAction: "nullify",
|
|
128
|
+
},
|
|
129
|
+
)
|
|
130
|
+
@JoinColumn({ name: "projectId" })
|
|
131
|
+
public project?: Project = undefined;
|
|
132
|
+
|
|
133
|
+
@ColumnAccessControl({
|
|
134
|
+
create: [],
|
|
135
|
+
read: [],
|
|
136
|
+
update: [],
|
|
137
|
+
})
|
|
138
|
+
@Index()
|
|
139
|
+
@TableColumn({
|
|
140
|
+
type: TableColumnType.ObjectID,
|
|
141
|
+
required: true,
|
|
142
|
+
canReadOnRelationQuery: true,
|
|
143
|
+
title: "Project ID",
|
|
144
|
+
description: "ID of the Project this SSO provider is attached to",
|
|
145
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
146
|
+
})
|
|
147
|
+
@Column({
|
|
148
|
+
type: ColumnType.ObjectID,
|
|
149
|
+
nullable: false,
|
|
150
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
151
|
+
})
|
|
152
|
+
public projectId?: ObjectID = undefined;
|
|
153
|
+
|
|
154
|
+
@ColumnAccessControl({
|
|
155
|
+
create: [],
|
|
156
|
+
read: [],
|
|
157
|
+
update: [],
|
|
158
|
+
})
|
|
159
|
+
@TableColumn({
|
|
160
|
+
required: false,
|
|
161
|
+
type: TableColumnType.EntityArray,
|
|
162
|
+
modelType: Team,
|
|
163
|
+
title: "Default Teams",
|
|
164
|
+
description:
|
|
165
|
+
"Teams in this project that a federated user is added to on first SSO login",
|
|
166
|
+
example: [{ id: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e" }],
|
|
167
|
+
})
|
|
168
|
+
@ManyToMany(
|
|
169
|
+
() => {
|
|
170
|
+
return Team;
|
|
171
|
+
},
|
|
172
|
+
{ eager: false },
|
|
173
|
+
)
|
|
174
|
+
@JoinTable({
|
|
175
|
+
name: "GlobalSSOProjectTeam",
|
|
176
|
+
inverseJoinColumn: {
|
|
177
|
+
name: "teamId",
|
|
178
|
+
referencedColumnName: "_id",
|
|
179
|
+
},
|
|
180
|
+
joinColumn: {
|
|
181
|
+
name: "globalSsoProjectId",
|
|
182
|
+
referencedColumnName: "_id",
|
|
183
|
+
},
|
|
184
|
+
})
|
|
185
|
+
public teams?: Array<Team> = undefined;
|
|
186
|
+
|
|
187
|
+
@ColumnAccessControl({
|
|
188
|
+
create: [],
|
|
189
|
+
read: [],
|
|
190
|
+
update: [],
|
|
191
|
+
})
|
|
192
|
+
@TableColumn({
|
|
193
|
+
isDefaultValueColumn: true,
|
|
194
|
+
type: TableColumnType.Boolean,
|
|
195
|
+
title: "Enabled",
|
|
196
|
+
description: "Is this project attachment enabled?",
|
|
197
|
+
defaultValue: true,
|
|
198
|
+
example: true,
|
|
199
|
+
})
|
|
200
|
+
@Column({
|
|
201
|
+
type: ColumnType.Boolean,
|
|
202
|
+
default: true,
|
|
203
|
+
})
|
|
204
|
+
public isEnabled?: boolean = undefined;
|
|
205
|
+
|
|
206
|
+
@ColumnAccessControl({
|
|
207
|
+
create: [],
|
|
208
|
+
read: [],
|
|
209
|
+
update: [],
|
|
210
|
+
})
|
|
211
|
+
@TableColumn({
|
|
212
|
+
type: TableColumnType.ObjectID,
|
|
213
|
+
title: "Created by User ID",
|
|
214
|
+
description: "User ID who created this object",
|
|
215
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
216
|
+
})
|
|
217
|
+
@Column({
|
|
218
|
+
type: ColumnType.ObjectID,
|
|
219
|
+
nullable: true,
|
|
220
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
221
|
+
})
|
|
222
|
+
public createdByUserId?: ObjectID = undefined;
|
|
223
|
+
|
|
224
|
+
@ColumnAccessControl({
|
|
225
|
+
create: [],
|
|
226
|
+
read: [],
|
|
227
|
+
update: [],
|
|
228
|
+
})
|
|
229
|
+
@TableColumn({
|
|
230
|
+
manyToOneRelationColumn: "createdByUserId",
|
|
231
|
+
type: TableColumnType.Entity,
|
|
232
|
+
modelType: User,
|
|
233
|
+
title: "Created by User",
|
|
234
|
+
description: "Relation to User who created this object",
|
|
235
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
236
|
+
})
|
|
237
|
+
@ManyToOne(
|
|
238
|
+
() => {
|
|
239
|
+
return User;
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
eager: false,
|
|
243
|
+
nullable: true,
|
|
244
|
+
onDelete: "SET NULL",
|
|
245
|
+
orphanedRowAction: "nullify",
|
|
246
|
+
},
|
|
247
|
+
)
|
|
248
|
+
@JoinColumn({ name: "createdByUserId" })
|
|
249
|
+
public createdByUser?: User = undefined;
|
|
250
|
+
|
|
251
|
+
@ColumnAccessControl({
|
|
252
|
+
create: [],
|
|
253
|
+
read: [],
|
|
254
|
+
update: [],
|
|
255
|
+
})
|
|
256
|
+
@TableColumn({
|
|
257
|
+
type: TableColumnType.ObjectID,
|
|
258
|
+
title: "Deleted by User ID",
|
|
259
|
+
description: "User ID who deleted this object",
|
|
260
|
+
example: "5f8b9c0d-e1a2-4b3c-8d5e-6f7a8b9c0d1e",
|
|
261
|
+
})
|
|
262
|
+
@Column({
|
|
263
|
+
type: ColumnType.ObjectID,
|
|
264
|
+
nullable: true,
|
|
265
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
266
|
+
})
|
|
267
|
+
public deletedByUserId?: ObjectID = undefined;
|
|
268
|
+
}
|
|
@@ -172,6 +172,10 @@ import ProjectSmtpConfig from "./ProjectSmtpConfig";
|
|
|
172
172
|
//SSO
|
|
173
173
|
import ProjectSSO from "./ProjectSso";
|
|
174
174
|
import ProjectOIDC from "./ProjectOidc";
|
|
175
|
+
import GlobalSSO from "./GlobalSso";
|
|
176
|
+
import GlobalOIDC from "./GlobalOidc";
|
|
177
|
+
import GlobalSSOProject from "./GlobalSsoProject";
|
|
178
|
+
import GlobalOIDCProject from "./GlobalOidcProject";
|
|
175
179
|
import PromoCode from "./PromoCode";
|
|
176
180
|
import EnterpriseLicense from "./EnterpriseLicense";
|
|
177
181
|
import OpenSourceDeployment from "./OpenSourceDeployment";
|
|
@@ -583,6 +587,10 @@ const AllModelTypes: Array<{
|
|
|
583
587
|
|
|
584
588
|
ProjectSSO,
|
|
585
589
|
ProjectOIDC,
|
|
590
|
+
GlobalSSO,
|
|
591
|
+
GlobalOIDC,
|
|
592
|
+
GlobalSSOProject,
|
|
593
|
+
GlobalOIDCProject,
|
|
586
594
|
StatusPageSSO,
|
|
587
595
|
StatusPageOIDC,
|
|
588
596
|
StatusPageSCIM,
|
|
@@ -677,6 +677,37 @@ export default class Project extends TenantModel {
|
|
|
677
677
|
})
|
|
678
678
|
public requireSsoForLogin?: boolean = undefined;
|
|
679
679
|
|
|
680
|
+
@ColumnAccessControl({
|
|
681
|
+
create: [],
|
|
682
|
+
read: [
|
|
683
|
+
Permission.ProjectOwner,
|
|
684
|
+
Permission.ProjectAdmin,
|
|
685
|
+
Permission.ProjectMember,
|
|
686
|
+
Permission.Viewer,
|
|
687
|
+
Permission.ReadProject,
|
|
688
|
+
Permission.UnAuthorizedSsoUser,
|
|
689
|
+
Permission.ProjectUser,
|
|
690
|
+
],
|
|
691
|
+
update: [
|
|
692
|
+
Permission.ProjectOwner,
|
|
693
|
+
Permission.ProjectAdmin,
|
|
694
|
+
Permission.EditProject,
|
|
695
|
+
],
|
|
696
|
+
})
|
|
697
|
+
@TableColumn({
|
|
698
|
+
required: false,
|
|
699
|
+
type: TableColumnType.ObjectID,
|
|
700
|
+
title: "Require SSO with specific provider",
|
|
701
|
+
description:
|
|
702
|
+
"If set, SSO-enforced login for this project is only satisfied by an SSO token issued by this specific provider id (a Project SSO/OIDC or a Global SSO/OIDC). When null, any trusted SSO provider satisfies enforcement.",
|
|
703
|
+
})
|
|
704
|
+
@Column({
|
|
705
|
+
type: ColumnType.ObjectID,
|
|
706
|
+
nullable: true,
|
|
707
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
708
|
+
})
|
|
709
|
+
public requireSsoWithSsoProviderId?: ObjectID = undefined;
|
|
710
|
+
|
|
680
711
|
@ColumnAccessControl({
|
|
681
712
|
create: [Permission.User],
|
|
682
713
|
read: [],
|