@finos/legend-application-studio
Version:
Legend Studio application core
208 lines • 11 kB
JavaScript
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { HttpStatus, NetworkClientError, ActionState, LogEvent, assertErrorThrown, } from '@finos/legend-shared';
import { ActionAlertActionType, ActionAlertType, LegendApplicationTelemetryHelper, APPLICATION_EVENT, } from '@finos/legend-application';
import { matchRoutes } from '@finos/legend-application/browser';
import { action, computed, flow, flowResult, makeObservable, observable, } from 'mobx';
import { User, SDLCServerClient } from '@finos/legend-server-sdlc';
import { LEGEND_STUDIO_APP_EVENT } from '../__lib__/LegendStudioEvent.js';
import { DepotServerClient } from '@finos/legend-server-depot';
import { LegendStudioEventHelper } from '../__lib__/LegendStudioEventHelper.js';
import { LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN } from '../__lib__/LegendStudioNavigation.js';
import { ShowcaseManagerState } from './ShowcaseManagerState.js';
import { getCurrentUserIDFromEngineServer } from '@finos/legend-graph';
export class LegendStudioBaseStore {
applicationStore;
sdlcServerClient;
depotServerClient;
pluginManager;
initState = ActionState.create();
isSDLCAuthorized = false;
isSDLCServerInitialized = false;
SDLCServerTermsOfServicesUrlsToView = [];
constructor(applicationStore) {
makeObservable(this, {
isSDLCAuthorized: observable,
SDLCServerTermsOfServicesUrlsToView: observable,
needsToAcceptSDLCServerTermsOfServices: computed,
initialize: flow,
initializeSDLCServerClient: flow,
dismissSDLCServerTermsOfServicesAlert: action,
});
this.applicationStore = applicationStore;
this.pluginManager = applicationStore.pluginManager;
// depot
this.depotServerClient = new DepotServerClient({
serverUrl: this.applicationStore.config.depotServerUrl,
});
this.depotServerClient.setTracerService(this.applicationStore.tracerService);
// sdlc
this.sdlcServerClient = new SDLCServerClient({
env: this.applicationStore.config.env,
serverUrl: this.applicationStore.config.sdlcServerUrl,
baseHeaders: this.applicationStore.config.sdlcServerBaseHeaders,
client: this.applicationStore.config.sdlcServerClient,
});
this.sdlcServerClient.setTracerService(this.applicationStore.tracerService);
}
*initialize() {
if (!this.initState.isInInitialState) {
this.applicationStore.notificationService.notifyIllegalState('Base store is re-initialized');
return;
}
this.initState.inProgress();
// initialization components asynchronously
// TODO: this is a nice non-blocking pattern for initialization
// we should do this for things like documentation, etc.
Promise.all([
ShowcaseManagerState.retrieveNullableState(this.applicationStore)?.initialize(),
]).catch((error) => {
// do nothing
});
// authorize SDLC, unless navigation location match SDLC-bypassed patterns
if (!matchRoutes([
{ path: LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN.VIEW_BY_GAV },
{
path: LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN.VIEW_BY_GAV_ENTITY,
},
{
path: LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN.PREVIEW_BY_GAV_ENTITY,
},
{ path: LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN.SHOWCASE },
{ path: LEGEND_STUDIO_SDLC_BYPASSED_ROUTE_PATTERN.PCT_REPORT },
], this.applicationStore.navigationService.navigator.getCurrentLocation())) {
// setup SDLC server client
yield flowResult(this.initializeSDLCServerClient());
// if SDLC server is not properly authorized/initialized, we would need to stop making call
// to SDLC server, as this could intertwine and mess up OIDC/OAuth authentication on the server
// See https://github.com/finos/legend-studio/pull/2205
// See https://github.com/finos/legend-sdlc/pull/628
if (!this.isSDLCServerInitialized) {
return;
}
try {
const currentUser = User.serialization.fromJson((yield this.sdlcServerClient.getCurrentUser()));
this.sdlcServerClient.setCurrentUser(currentUser);
this.applicationStore.identityService.setCurrentUser(currentUser.userId);
}
catch (error) {
assertErrorThrown(error);
this.applicationStore.logService.error(LogEvent.create(APPLICATION_EVENT.IDENTITY_AUTO_FETCH__FAILURE), error);
this.applicationStore.notificationService.notifyWarning(error.message);
}
}
else {
this.isSDLCAuthorized = undefined;
}
// retrieved the user identity is not already configured
if (this.applicationStore.identityService.isAnonymous) {
try {
this.applicationStore.identityService.setCurrentUser((yield getCurrentUserIDFromEngineServer(this.applicationStore.config.engineServerUrl)));
}
catch (error) {
assertErrorThrown(error);
this.applicationStore.logService.error(LogEvent.create(APPLICATION_EVENT.IDENTITY_AUTO_FETCH__FAILURE), error);
this.applicationStore.notificationService.notifyWarning(error.message);
}
}
// setup telemetry service
this.applicationStore.telemetryService.setup();
LegendApplicationTelemetryHelper.logEvent_ApplicationInitializationSucceeded(this.applicationStore.telemetryService, this.applicationStore);
LegendStudioEventHelper.notify_ApplicationLoadSucceeded(this.applicationStore.eventService);
this.initState.complete();
}
get needsToAcceptSDLCServerTermsOfServices() {
return Boolean(this.SDLCServerTermsOfServicesUrlsToView.length);
}
dismissSDLCServerTermsOfServicesAlert() {
this.SDLCServerTermsOfServicesUrlsToView = [];
}
*initializeSDLCServerClient() {
try {
this.isSDLCAuthorized =
(yield this.sdlcServerClient.isAuthorized());
if (!this.isSDLCAuthorized) {
this.applicationStore.navigationService.navigator.goToAddress(SDLCServerClient.authorizeCallbackUrl(this.applicationStore.config.sdlcServerUrl, this.applicationStore.navigationService.navigator.getCurrentAddress(), this.applicationStore.config.sdlcServerClient));
}
else {
// Only proceed intialization after passing authorization check
// check terms of service agreement status
this.SDLCServerTermsOfServicesUrlsToView =
(yield this.sdlcServerClient.hasAcceptedTermsOfService());
if (this.SDLCServerTermsOfServicesUrlsToView.length) {
this.applicationStore.alertService.setActionAlertInfo({
message: `Please read and accept the SDLC servers' terms of service`,
prompt: `Click 'Done' when you have accepted all the terms`,
type: ActionAlertType.CAUTION,
actions: [
{
label: 'See terms of services',
default: true,
handler: () => this.SDLCServerTermsOfServicesUrlsToView.forEach((url) => this.applicationStore.navigationService.navigator.visitAddress(url)),
type: ActionAlertActionType.PROCEED,
},
{
label: 'Done',
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
handler: () => {
this.dismissSDLCServerTermsOfServicesAlert();
this.applicationStore.navigationService.navigator.reload();
},
},
],
});
}
// fetch server features config and platforms
yield this.sdlcServerClient.fetchServerPlatforms();
yield this.sdlcServerClient.fetchServerFeaturesConfiguration();
// the sdlc server client is authorized and initialized
this.isSDLCServerInitialized = true;
}
}
catch (error) {
assertErrorThrown(error);
if (
// eslint-disable-next-line no-process-env
process.env.NODE_ENV === 'development' &&
error instanceof NetworkClientError &&
error.response.status === HttpStatus.UNAUTHORIZED) {
this.applicationStore.alertService.setActionAlertInfo({
message: 'The first time the application starts in development mode, the developer would need to authenticate using SDLC server. Please do so then manually reload the app',
type: ActionAlertType.STANDARD,
actions: [
{
label: 'Authenticate using SDLC',
type: ActionAlertActionType.PROCEED,
default: true,
handler: () => {
this.applicationStore.navigationService.navigator.visitAddress(this.sdlcServerClient.currentUserUrl);
this.applicationStore.alertService.setBlockingAlert({
message: 'Waiting for the developer to authenticate using SDLC server',
prompt: 'Please manually reload the application after authentication',
});
},
},
],
});
}
else {
this.applicationStore.logService.error(LogEvent.create(LEGEND_STUDIO_APP_EVENT.SDLC_MANAGER_FAILURE), error);
this.applicationStore.notificationService.notifyError(error);
}
}
}
}
//# sourceMappingURL=LegendStudioBaseStore.js.map