commit
e26524a6b9
|
@ -1,9 +1,7 @@
|
|||
{
|
||||
"version": "2.7.34-alpha.10",
|
||||
"version": "2.7.35",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"packages": ["packages/*"],
|
||||
"useNx": true,
|
||||
"command": {
|
||||
"publish": {
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
GoogleInnerConfig,
|
||||
OIDCConfig,
|
||||
OIDCInnerConfig,
|
||||
OIDCLogosConfig,
|
||||
SCIMConfig,
|
||||
SCIMInnerConfig,
|
||||
SettingsConfig,
|
||||
|
@ -191,6 +192,10 @@ export function getDefaultGoogleConfig(): GoogleInnerConfig | undefined {
|
|||
|
||||
// OIDC
|
||||
|
||||
export async function getOIDCLogosDoc(): Promise<OIDCLogosConfig | undefined> {
|
||||
return getConfig<OIDCLogosConfig>(ConfigType.OIDC_LOGOS)
|
||||
}
|
||||
|
||||
async function getOIDCConfigDoc(): Promise<OIDCConfig | undefined> {
|
||||
return getConfig<OIDCConfig>(ConfigType.OIDC)
|
||||
}
|
||||
|
|
|
@ -99,9 +99,15 @@
|
|||
bind:this={button}
|
||||
>
|
||||
{#if fieldIcon}
|
||||
<span class="option-extra icon">
|
||||
<Icon size="S" name={fieldIcon} />
|
||||
</span>
|
||||
{#if !useOptionIconImage}
|
||||
<span class="option-extra icon">
|
||||
<Icon size="S" name={fieldIcon} />
|
||||
</span>
|
||||
{:else}
|
||||
<span class="option-extra icon field-icon">
|
||||
<img src={fieldIcon} alt="icon" width="15" height="15" />
|
||||
</span>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if fieldColour}
|
||||
<span class="option-extra">
|
||||
|
@ -311,4 +317,8 @@
|
|||
max-width: 170px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.option-extra.icon.field-icon {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
let userOnboardResponse = null
|
||||
let userLimitReachedModal
|
||||
|
||||
let inviteFailureResponse = ""
|
||||
|
||||
$: queryIsEmail = emailValidator(query) === true
|
||||
$: prodAppId = apps.getProdAppID($store.appId)
|
||||
$: promptInvite = showInvite(
|
||||
|
@ -308,19 +310,6 @@
|
|||
let userInviteResponse
|
||||
try {
|
||||
userInviteResponse = await users.onboard(payload)
|
||||
|
||||
const newUser = userInviteResponse?.successful.find(
|
||||
user => user.email === newUserEmail
|
||||
)
|
||||
if (newUser) {
|
||||
notifications.success(
|
||||
userInviteResponse.created
|
||||
? "User created successfully"
|
||||
: "User invite successful"
|
||||
)
|
||||
} else {
|
||||
throw new Error("User invite failed")
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error.message)
|
||||
notifications.error("Error inviting user")
|
||||
|
@ -331,12 +320,31 @@
|
|||
|
||||
const onInviteUser = async () => {
|
||||
userOnboardResponse = await inviteUser()
|
||||
const originalQuery = query + ""
|
||||
query = null
|
||||
|
||||
const userInviteSuccess = userOnboardResponse?.successful
|
||||
if (userInviteSuccess && userInviteSuccess[0].email === query) {
|
||||
query = null
|
||||
query = userInviteSuccess[0].email
|
||||
const newUser = userOnboardResponse?.successful.find(
|
||||
user => user.email === originalQuery
|
||||
)
|
||||
if (newUser) {
|
||||
query = originalQuery
|
||||
notifications.success(
|
||||
userOnboardResponse.created
|
||||
? "User created successfully"
|
||||
: "User invite successful"
|
||||
)
|
||||
} else {
|
||||
const failedUser = userOnboardResponse?.unsuccessful.find(
|
||||
user => user.email === originalQuery
|
||||
)
|
||||
inviteFailureResponse =
|
||||
failedUser?.reason === "Unavailable"
|
||||
? "Email already in use. Please use a different email."
|
||||
: failedUser?.reason
|
||||
|
||||
notifications.error(inviteFailureResponse)
|
||||
}
|
||||
userOnboardResponse = null
|
||||
}
|
||||
|
||||
const onUpdateUserInvite = async (invite, role) => {
|
||||
|
|
|
@ -29,14 +29,13 @@
|
|||
}
|
||||
})
|
||||
|
||||
$: src = !$oidc.logo
|
||||
? OidcLogo
|
||||
: preDefinedIcons[$oidc.logo] || `/global/logos_oidc/${$oidc.logo}`
|
||||
$: oidcLogoImageURL = preDefinedIcons[$oidc.logo] ?? $oidc.logo
|
||||
$: logoSrc = oidcLogoImageURL ?? OidcLogo
|
||||
</script>
|
||||
|
||||
{#if show}
|
||||
<FancyButton
|
||||
icon={src}
|
||||
icon={logoSrc}
|
||||
on:click={() => {
|
||||
const url = `/api/global/auth/${$auth.tenantId}/oidc/configs/${$oidc.uuid}`
|
||||
if (samePage) {
|
||||
|
|
|
@ -382,18 +382,26 @@ class MongoIntegration implements IntegrationBase {
|
|||
return this.client.connect()
|
||||
}
|
||||
|
||||
createObjectIds(json: any) {
|
||||
matchId(value?: string) {
|
||||
return value?.match(/(?<=objectid\(['"]).*(?=['"]\))/gi)?.[0]
|
||||
}
|
||||
|
||||
hasObjectId(value?: any): boolean {
|
||||
return (
|
||||
typeof value === "string" && value.toLowerCase().startsWith("objectid")
|
||||
)
|
||||
}
|
||||
|
||||
createObjectIds(json: any): any {
|
||||
const self = this
|
||||
|
||||
function interpolateObjectIds(json: any) {
|
||||
for (let field of Object.keys(json || {})) {
|
||||
if (json[field] instanceof Object) {
|
||||
json[field] = self.createObjectIds(json[field])
|
||||
}
|
||||
if (
|
||||
typeof json[field] === "string" &&
|
||||
json[field].toLowerCase().startsWith("objectid")
|
||||
) {
|
||||
const id = json[field].match(/(?<=objectid\(['"]).*(?=['"]\))/gi)?.[0]
|
||||
if (self.hasObjectId(json[field])) {
|
||||
const id = self.matchId(json[field])
|
||||
if (id) {
|
||||
json[field] = ObjectId.createFromHexString(id)
|
||||
}
|
||||
|
@ -404,7 +412,14 @@ class MongoIntegration implements IntegrationBase {
|
|||
|
||||
if (Array.isArray(json)) {
|
||||
for (let i = 0; i < json.length; i++) {
|
||||
json[i] = interpolateObjectIds(json[i])
|
||||
if (self.hasObjectId(json[i])) {
|
||||
const id = self.matchId(json[i])
|
||||
if (id) {
|
||||
json[i] = ObjectId.createFromHexString(id)
|
||||
}
|
||||
} else {
|
||||
json[i] = interpolateObjectIds(json[i])
|
||||
}
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
|
|
@ -79,6 +79,12 @@ export interface OIDCConfigs {
|
|||
configs: OIDCInnerConfig[]
|
||||
}
|
||||
|
||||
export interface OIDCLogosInnerConfig {
|
||||
[key: string]: string
|
||||
}
|
||||
|
||||
export interface OIDCLogosConfig extends Config<OIDCLogosInnerConfig> {}
|
||||
|
||||
export interface OIDCInnerConfig {
|
||||
configUrl: string
|
||||
clientID: string
|
||||
|
|
|
@ -28,6 +28,7 @@ import {
|
|||
SSOConfig,
|
||||
SSOConfigType,
|
||||
UserCtx,
|
||||
OIDCLogosConfig,
|
||||
} from "@budibase/types"
|
||||
import * as pro from "@budibase/pro"
|
||||
|
||||
|
@ -280,13 +281,39 @@ export async function save(ctx: UserCtx<Config>) {
|
|||
}
|
||||
}
|
||||
|
||||
function enrichOIDCLogos(oidcLogos: OIDCLogosConfig) {
|
||||
if (!oidcLogos) {
|
||||
return
|
||||
}
|
||||
oidcLogos.config = Object.keys(oidcLogos.config || {}).reduce(
|
||||
(acc: any, key: string) => {
|
||||
if (!key.endsWith("Etag")) {
|
||||
const etag = oidcLogos.config[`${key}Etag`]
|
||||
const objectStoreUrl = objectStore.getGlobalFileUrl(
|
||||
oidcLogos.type,
|
||||
key,
|
||||
etag
|
||||
)
|
||||
acc[key] = objectStoreUrl
|
||||
} else {
|
||||
acc[key] = oidcLogos.config[key]
|
||||
}
|
||||
return acc
|
||||
},
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
export async function find(ctx: UserCtx) {
|
||||
try {
|
||||
// Find the config with the most granular scope based on context
|
||||
const type = ctx.params.type
|
||||
const scopedConfig = await configs.getConfig(type)
|
||||
let scopedConfig = await configs.getConfig(type)
|
||||
|
||||
if (scopedConfig) {
|
||||
if (type === ConfigType.OIDC_LOGOS) {
|
||||
enrichOIDCLogos(scopedConfig)
|
||||
}
|
||||
ctx.body = scopedConfig
|
||||
} else {
|
||||
// don't throw an error, there simply is nothing to return
|
||||
|
@ -300,16 +327,21 @@ export async function find(ctx: UserCtx) {
|
|||
export async function publicOidc(ctx: Ctx<void, GetPublicOIDCConfigResponse>) {
|
||||
try {
|
||||
// Find the config with the most granular scope based on context
|
||||
const config = await configs.getOIDCConfig()
|
||||
const oidcConfig = await configs.getOIDCConfig()
|
||||
const oidcCustomLogos = await configs.getOIDCLogosDoc()
|
||||
|
||||
if (!config) {
|
||||
if (oidcCustomLogos) {
|
||||
enrichOIDCLogos(oidcCustomLogos)
|
||||
}
|
||||
|
||||
if (!oidcConfig) {
|
||||
ctx.body = []
|
||||
} else {
|
||||
ctx.body = [
|
||||
{
|
||||
logo: config.logo,
|
||||
name: config.name,
|
||||
uuid: config.uuid,
|
||||
logo: oidcCustomLogos?.config[oidcConfig.logo] ?? oidcConfig.logo,
|
||||
name: oidcConfig.name,
|
||||
uuid: oidcConfig.uuid,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue