/* * CloudBeaver - Cloud Database Manager * Copyright (C) 2020-2024 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ import { action, computed, observable } from 'mobx'; import { useObservableRef } from '@cloudbeaver/core-blocks'; import { ConnectionInfoResource, type ConnectionInitConfig, type DatabaseConnection, type DBDriver, DBDriverResource, type IConnectionInfoParams, USER_NAME_PROPERTY_ID, } from '@cloudbeaver/core-connections'; import { useService } from '@cloudbeaver/core-di'; import { NetworkHandlerAuthType } from '@cloudbeaver/core-sdk'; import type { ILoadableState } from '@cloudbeaver/core-utils'; import type { IConnectionAuthenticationConfig } from '../../ConnectionAuthentication/IConnectionAuthenticationConfig.js'; interface IState extends ILoadableState { readonly authModelId: string | null; driver: DBDriver | null; connection: DatabaseConnection | null; config: IConnectionAuthenticationConfig; authenticating: boolean; loading: boolean; loaded: boolean; exception: Error | null; authException: Error | null; load: () => Promise; login: () => Promise; getConfig: () => ConnectionInitConfig; } export function useDatabaseCredentialsAuthDialog( key: IConnectionInfoParams, networkHandlers: string[], resetCredentials?: boolean, onInit?: () => void, ) { const connectionInfoResource = useService(ConnectionInfoResource); const dbDriverResource = useService(DBDriverResource); const state: IState = useObservableRef( () => ({ get authModelId() { if (!this.connection?.authNeeded && !this.resetCredentials) { return null; } return this.connection?.authModel || this.driver?.defaultAuthModel || null; }, connection: null as DatabaseConnection | null, driver: null as DBDriver | null, authenticating: false, loading: false, loaded: false, exception: null, authException: null, config: { credentials: {}, networkHandlersConfig: [], saveCredentials: false, } as IConnectionAuthenticationConfig, async load() { if (this.loaded || this.loading) { return; } try { this.exception = null; this.loading = true; const connection = await this.connectionInfoResource.load(this.key, [ 'includeAuthProperties', 'includeNetworkHandlersConfig', 'includeAuthNeeded', ]); const driver = await this.dbDriverResource.load(connection.driverId); if (connection.authNeeded) { const property = connection.authProperties.find(property => property.id === USER_NAME_PROPERTY_ID); if (property?.value) { this.config.credentials[USER_NAME_PROPERTY_ID] = property.value; } } for (const id of this.networkHandlers) { const handler = connection.networkHandlersConfig.find(handler => handler.id === id); if (handler) { this.config.networkHandlersConfig.push({ id: handler.id, authType: handler.authType, userName: handler.userName, password: handler.password, savePassword: handler.savePassword, }); } } this.config.saveCredentials = connection.saveCredentials; this.connection = connection; this.driver = driver; this.loaded = true; } catch (exception: any) { this.exception = exception; } finally { this.loading = false; } }, async login() { if (this.authenticating) { return; } try { this.authException = null; this.authenticating = true; await this.connectionInfoResource.init(this.getConfig()); this.onInit?.(); } catch (exception: any) { this.authException = exception; } finally { this.authenticating = false; } }, getConfig() { const config: ConnectionInitConfig = { projectId: this.key.projectId, connectionId: this.key.connectionId, }; if (this.authModelId) { if (Object.keys(this.config.credentials).length > 0) { config.credentials = this.config.credentials; } config.saveCredentials = this.config.saveCredentials; } if (this.config.networkHandlersConfig.length > 0) { config.networkCredentials = this.config.networkHandlersConfig; } return config; }, isLoading() { return this.loading; }, isLoaded() { return this.loaded; }, isError() { return !!this.exception; }, }), { authModelId: computed, config: observable, connection: observable.ref, driver: observable.ref, authenticating: observable.ref, loading: observable.ref, loaded: observable.ref, exception: observable.ref, authException: observable.ref, load: action.bound, login: action.bound, }, { connectionInfoResource, dbDriverResource, key, networkHandlers, resetCredentials, onInit }, ); return state; }