@genesislcap/blank-app-seed 3.41.0 → 3.41.1

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 (28) hide show
  1. package/.genx/package.json +1 -1
  2. package/CHANGELOG.md +8 -0
  3. package/client-tmp/angular/angular.json +0 -3
  4. package/client-tmp/angular/src/app/app.component.ts +6 -12
  5. package/client-tmp/angular/src/app/guards/auth.guard.ts +1 -1
  6. package/client-tmp/angular/src/app/layouts/default/default.layout.html +0 -1
  7. package/client-tmp/angular/src/app/layouts/default/default.layout.ts +2 -6
  8. package/client-tmp/angular/src/app/services/route.service.ts +2 -2
  9. package/client-tmp/angular/src/app/share/foundation-auth.ts +15 -29
  10. package/client-tmp/angular/src/app/share/foundation-login.ts +47 -0
  11. package/client-tmp/react/package.json +1 -1
  12. package/client-tmp/react/src/App.tsx +8 -3
  13. package/client-tmp/react/src/config.ts +2 -2
  14. package/client-tmp/react/src/guards/ProtectedGuard.tsx +3 -6
  15. package/client-tmp/react/src/layouts/default/DefaultLayout.tsx +17 -12
  16. package/client-tmp/react/src/pages/AuthPage/AuthPage.tsx +6 -14
  17. package/client-tmp/react/src/pbc/container.tsx +1 -1
  18. package/client-tmp/react/src/share/foundation-login.ts +19 -28
  19. package/client-tmp/react/src/store/RoutesContext.tsx +1 -1
  20. package/client-tmp/react/src/utils/history.ts +5 -0
  21. package/client-tmp/react/src/utils/index.ts +1 -0
  22. package/client-tmp/react/webpack.config.js +1 -15
  23. package/client-tmp/web-components/package.json +1 -4
  24. package/client-tmp/web-components/src/layouts/default.ts +0 -4
  25. package/client-tmp/web-components/src/routes/config.ts +81 -36
  26. package/package.json +1 -1
  27. package/client-tmp/angular/src/proxy.conf.json +0 -12
  28. package/server/{{appName}}-app/src/main/genesis/scripts/genesis-router.kts +0 -13
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/blank-app-seed-config",
3
3
  "description": "Genesis Blank App Seed Configuration",
4
- "version": "3.41.0",
4
+ "version": "3.41.1",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
7
7
  "lint": "eslint .",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.41.1](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.41.0...v3.41.1) (2025-03-18)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * revert changes e50c69a
9
+ * revert cookies (#438) 754f30a
10
+
3
11
  ## [3.41.0](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v3.40.1...v3.41.0) (2025-03-06)
4
12
 
5
13
 
@@ -74,9 +74,6 @@
74
74
  },
75
75
  "serve": {
76
76
  "builder": "@angular-builders/custom-webpack:dev-server",
77
- "options": {
78
- "proxyConfig": "src/proxy.conf.json"
79
- },
80
77
  "configurations": {
81
78
  "production": {
82
79
  "buildTarget": "{{pkgName}}:build:production"
@@ -1,12 +1,11 @@
1
1
  import { AfterViewInit, Component, ElementRef, OnDestroy, OnInit } from '@angular/core';
2
2
  import { Router, NavigationEnd } from '@angular/router';
3
- import { Connect } from '@genesislcap/foundation-comms';
4
- import { customEventFactory, registerStylesTarget } from '../pbc/utils';
5
- import { configureFoundationAuth } from './share/foundation-auth';
3
+ import getLayoutNameByRoute from './utils/getLayoutNameByRoute';
4
+ import type { LayoutComponentName } from './types/layout';
5
+ import { configureFoundationLogin } from './share/foundation-login';
6
6
  import { registerComponents } from './share/genesis-components';
7
7
  import { getStore } from './store';
8
- import type { LayoutComponentName } from './types/layout';
9
- import getLayoutNameByRoute from './utils/getLayoutNameByRoute';
8
+ import { customEventFactory, registerStylesTarget } from '../pbc/utils';
10
9
  {{#if FDC3.channels.length}}
11
10
  import { listenToChannel, onFDC3Ready } from './utils';
12
11
  {{/if}}
@@ -21,17 +20,12 @@ export class AppComponent implements OnInit, OnDestroy, AfterViewInit {
21
20
  title = '{{capitalCase appName}}';
22
21
  store = getStore();
23
22
 
24
- // @ts-ignore
25
- @Connect connect: Connect;
26
-
27
23
  constructor(
28
24
  private el: ElementRef,
29
25
  router: Router,
30
26
  ) {
31
- // @ts-ignore
32
- configureFoundationAuth({ router, connectService: this.connect });
33
-
34
-
27
+ configureFoundationLogin({ router });
28
+
35
29
  // Set layout componet based on route
36
30
  router.events.subscribe((event: any) => {
37
31
  if (event instanceof NavigationEnd) {
@@ -9,7 +9,7 @@ export class AuthGuard extends PermissionsGuard {
9
9
  override async canActivate(): Promise<boolean> {
10
10
  if (!this.user.isAuthenticated) {
11
11
  this.user.trackPath();
12
- await this.router.navigate([`/${AUTH_PATH}`]);
12
+ this.router.navigate([`/${AUTH_PATH}`]);
13
13
  return false;
14
14
  }
15
15
  return true;
@@ -5,7 +5,6 @@
5
5
  show-luminance-toggle-button
6
6
  show-misc-toggle-button
7
7
  (luminance-icon-clicked)="onLuminanceToogle()"
8
- (logout-clicked)="onLogout()"
9
8
  [navigateTo]="navigateAngular"
10
9
  [routeNavItems]="navItems"
11
10
  >
@@ -29,15 +29,11 @@ export class DefaultLayoutComponent extends BaseLayout implements AfterViewInit
29
29
  configureDesignSystem(this.designSystemProviderElement.nativeElement, designTokens);
30
30
  registerStylesTarget(this.el.nativeElement, 'layout');
31
31
  }
32
-
32
+
33
33
  navigateAngular = (path: string) => {
34
34
  this.router.navigate([path]);
35
35
  };
36
-
37
- onLogout = () => {
38
- this.router.navigate(['/login']);
39
- };
40
-
36
+
41
37
  onLuminanceToogle = (): void => {
42
38
  baseLayerLuminance.setValueFor(
43
39
  this.designSystemProviderElement.nativeElement,
@@ -39,7 +39,7 @@ export class RouteService {
39
39
  navItems: [
40
40
  {
41
41
  navId: 'header',
42
- title: '{{#if this.title}}{{capitalCase this.title}}{{else}}{{this.name}}{{/if}}',
42
+ title: '{{#if this.title}}{{this.title}}{{else}}{{this.name}}{{/if}}',
43
43
  icon: {
44
44
  name: '{{this.icon}}',
45
45
  variant: 'solid',
@@ -53,7 +53,7 @@ export class RouteService {
53
53
 
54
54
  /**
55
55
  * @privateRemarks
56
- * The shell has access to context, so it's possible for it to return a pre-mapped framework variant of routes.
56
+ * The shell has access to context, so it's possible for it to return a pre-mapped framework variant of routes.
57
57
  * In this iteration we're doing it inline, given the angular version may move and here we know the shape we need.
58
58
  */
59
59
  pbcRoutes(): Routes {
@@ -1,34 +1,20 @@
1
+ // import { configure } from '@genesislcap/foundation-auth/config';
1
2
  import type { Router } from '@angular/router';
2
- import { configure, defaultAuthConfig } from '@genesislcap/foundation-auth/config';
3
- import type { Connect } from '@genesislcap/foundation-comms';
4
- import { getUser } from '@genesislcap/foundation-user';
5
- import { GENESIS_SOCKET_URL } from '@genesislcap/foundation-utils';
6
- import { AUTH_PATH } from '../app.config';
7
3
 
8
4
  /**
9
5
  * Configure the micro frontend
10
6
  */
11
- export const configureFoundationAuth = ({ router, connectService,}: { router: Router; connectService: Connect; }) => {
12
- const baseElement = document.querySelector('base');
13
- const basePath = baseElement?.getAttribute('href') || '';
14
-
15
- configure({
16
- name: 'client-app-login',
17
- omitRoutes: ['request-account', 'forgot-password'],
18
- fields: {
19
- ...defaultAuthConfig.fields,
20
- username: {
21
- ...defaultAuthConfig.fields.username,
22
- },
23
- },
24
- hostPath: basePath + AUTH_PATH,
25
- postLoginRedirect: async () => {
26
- const url = GENESIS_SOCKET_URL;
27
- await connectService.connect(url);
28
-
29
- const lastPath = getUser().lastPath()?.replace(basePath, '');
30
-
31
- router.navigate([lastPath ?? '{{kebabCase routes.[0].name}}']);
32
- },
33
- });
34
- };
7
+ export const configureFoundationAuth = ({
8
+ router,
9
+ connectService,
10
+ }: {
11
+ router: Router;
12
+ connectService: any;
13
+ }) => null
14
+ // configure({
15
+ // omitRoutes: ['request-account'],
16
+ // postLoginRedirect: async () => {
17
+ // await connectService.init();
18
+ // router.navigate([`/${INTERNAL_URLS.homepage}`]);
19
+ // },
20
+ // });
@@ -0,0 +1,47 @@
1
+ import {configure, define} from '@genesislcap/foundation-login';
2
+ import type { Router } from '@angular/router';
3
+ import { getUser } from '@genesislcap/foundation-user';
4
+ import { css, DI } from '@genesislcap/web-core';
5
+ import { AUTH_PATH } from '../app.config';
6
+ import logo from '../../assets/logo.svg';
7
+
8
+ // eslint-disable-next-line
9
+ declare var ENABLE_SSO: boolean;
10
+
11
+ const ssoSettings =
12
+ typeof ENABLE_SSO !== 'undefined' && ENABLE_SSO === true
13
+ ? {
14
+ autoAuth: true,
15
+ sso: {
16
+ toggled: true,
17
+ identityProvidersPath: 'sso/list',
18
+ },
19
+ }
20
+ : {};
21
+
22
+ /**
23
+ * Configure the micro frontend
24
+ */
25
+ export const configureFoundationLogin = ({
26
+ router,
27
+ }: {
28
+ router: Router;
29
+ }) => {
30
+ configure(DI.getOrCreateDOMContainer(), {
31
+ // autoConnect: true, // < Guard in place to ensure connection. Keeping the connect form in place for now.
32
+ autoAuth: true, // < Allow users to skip login
33
+ showConnectionIndicator: true,
34
+ hostPath: AUTH_PATH,
35
+ redirectHandler: () => {
36
+ router.navigate([getUser().lastPath() ?? '{{kebabCase routes.[0].name}}'])
37
+ },
38
+ ...ssoSettings,
39
+ logo: css `
40
+ content: url("${logo}");
41
+ `,
42
+ });
43
+
44
+ return define({
45
+ name: `client-app-login`,
46
+ });
47
+ }
@@ -58,7 +58,7 @@
58
58
  "history": "^5.3.0",
59
59
  "react": "^19.0.0",
60
60
  "react-dom": "^19.0.0",
61
- "react-router": "^7.1.3",
61
+ "react-router-dom": "7.0.2",
62
62
  "web-vitals": "^2.1.4"
63
63
  },
64
64
  "devDependencies": {
@@ -1,6 +1,7 @@
1
1
  import { useEffect, useState } from 'react';
2
- import {Routes, Route, useLocation, BrowserRouter} from 'react-router';
2
+ import { unstable_HistoryRouter as HistoryRouter, Routes, Route, useLocation } from 'react-router-dom';
3
3
  import {
4
+ history,
4
5
  setApiHost,
5
6
  getLayoutNameByRoute,
6
7
  {{#if FDC3.channels.length~}}
@@ -16,6 +17,7 @@ import { AuthProvider } from './store/AuthContext';
16
17
  import { RoutesProvider, useRoutesContext } from './store/RoutesContext';
17
18
  import AuthPage from './pages/AuthPage/AuthPage';
18
19
  import { registerComponents as genesisRegisterComponents } from './share/genesis-components';
20
+ import { configureFoundationLogin } from './share/foundation-login';
19
21
  import ProtectedGuard from './guards/ProtectedGuard';
20
22
  import { storeService } from '@/services/store.service';
21
23
 
@@ -31,8 +33,10 @@ const DynamicLayout = () => {
31
33
 
32
34
  useEffect(() => {
33
35
  handleRouteChange(location);
36
+ const unlisten = history.listen(handleRouteChange);
34
37
 
35
38
  return () => {
39
+ unlisten();
36
40
  }
37
41
  }, [location]);
38
42
 
@@ -78,6 +82,7 @@ const App: React.FC<AppProps> = ({ rootElement }) => {
78
82
 
79
83
  setApiHost();
80
84
  genesisRegisterComponents();
85
+ configureFoundationLogin({ router: history });
81
86
 
82
87
  useEffect(() => {
83
88
  registerStylesTarget(document.body, 'main');
@@ -102,11 +107,11 @@ const App: React.FC<AppProps> = ({ rootElement }) => {
102
107
  return (
103
108
  <AuthProvider>
104
109
  <RoutesProvider>
105
- <BrowserRouter>
110
+ <HistoryRouter history={history as any}>
106
111
  <Routes>
107
112
  <Route path="*" element={<DynamicLayout />} />
108
113
  </Routes>
109
- </BrowserRouter>
114
+ </HistoryRouter>
110
115
  </RoutesProvider>
111
116
  </AuthProvider>
112
117
  );
@@ -2,11 +2,11 @@ import { RouteLayouts } from './types/RouteLayouts';
2
2
  import { environment } from '@environment';
3
3
 
4
4
  export const routeLayouts: RouteLayouts = {
5
- '/login': 'blank',
5
+ '/auth': 'blank',
6
6
  '/': 'blank',
7
7
  };
8
8
 
9
- export const AUTH_PATH = 'login';
9
+ export const AUTH_PATH = 'auth';
10
10
  export const NOT_PERMITTED_PATH = 'not-permitted';
11
11
 
12
12
  export const API_DATA = {
@@ -1,5 +1,6 @@
1
1
  import { useState, useEffect, ReactNode } from 'react';
2
- import {RouteObject, useNavigate} from 'react-router';
2
+ import { RouteObject } from 'react-router';
3
+ import { useNavigate } from 'react-router-dom';
3
4
  import isConnectedHelper from '@/helpers/isConnectedHelper';
4
5
  import isAuthenticatedHelper from '@/helpers/isAuthenticatedHelper';
5
6
  import hasPermissionHelper from '@/helpers/hasPermissionHelper';
@@ -55,11 +56,7 @@ const ProtectedGuard: React.FC<{ children: ReactNode }> = ({ children }: { child
55
56
  }
56
57
 
57
58
  if (permissionState) {
58
- const baseElement = document.querySelector('base');
59
- const basePath = baseElement?.getAttribute('href') || '';
60
-
61
- const redirect = `${basePath}${redirectUrlByPermissionState[permissionState]}`;
62
- navigate(`/${redirect}`);
59
+ navigate(`/${redirectUrlByPermissionState[permissionState]}`);
63
60
  }
64
61
  }, [routes, isConnected, isAuthenticated, hasPermission]);
65
62
 
@@ -1,6 +1,7 @@
1
1
  import React, { ReactNode, useEffect, useRef } from 'react';
2
- import { RouteObject, useNavigate } from 'react-router';
2
+ import { RouteObject } from 'react-router';
3
3
  import { configureDesignSystem, getNavItems } from '@genesislcap/foundation-ui';
4
+ import { useNavigate } from 'react-router-dom';
4
5
  import {
5
6
  baseLayerLuminance,
6
7
  StandardLuminance,
@@ -9,9 +10,6 @@ import styles from './DefaultLayout.module.css';
9
10
  import PBCElementsRenderer from '@/pbc/elementsRenderer';
10
11
  import * as designTokens from '@/styles/design-tokens.json';
11
12
  import { useRoutesContext } from '@/store/RoutesContext';
12
- import { connectService } from '@/services/connect.service.ts';
13
- import { getUser } from '@genesislcap/foundation-user';
14
- import { AUTH_PATH } from '@/config';
15
13
 
16
14
  interface DefaultLayoutProps {
17
15
  children: ReactNode;
@@ -27,6 +25,7 @@ type ExtendedRouteObject = RouteObject & {
27
25
  const DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {
28
26
  const navigate = useNavigate();
29
27
  const designSystemProviderRef = useRef<HTMLElement>(null);
28
+ const foundationHeaderRef = useRef<HTMLElement>(null);
30
29
  const routes = useRoutesContext() as ExtendedRouteObject[];
31
30
  const navItems = getNavItems(routes.flatMap((route) => ({
32
31
  path: route.path || '',
@@ -44,18 +43,25 @@ const DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {
44
43
  );
45
44
  }
46
45
  };
47
-
48
- if (!connectService.isConnected()) {
49
- getUser().trackPath();
50
- navigate(`/${AUTH_PATH}`)
51
- }
52
-
46
+
53
47
  useEffect(() => {
54
48
  if (designSystemProviderRef.current) {
55
49
  configureDesignSystem(designSystemProviderRef.current, designTokens);
56
50
  }
57
51
 
52
+ const handleLuminanceIconClicked = () => {
53
+ onLuminanceToggle();
54
+ };
55
+
56
+ const foundationHeader = foundationHeaderRef.current;
57
+ if (foundationHeader) {
58
+ foundationHeader.addEventListener('luminance-icon-clicked', handleLuminanceIconClicked);
59
+ }
60
+
58
61
  return () => {
62
+ if (foundationHeader) {
63
+ foundationHeader.removeEventListener('luminance-icon-clicked', handleLuminanceIconClicked);
64
+ }
59
65
  };
60
66
  }, []);
61
67
 
@@ -65,8 +71,7 @@ const DefaultLayout: React.FC<DefaultLayoutProps> = ({ children }) => {
65
71
  <rapid-design-system-provider ref={designSystemProviderRef} class={className}>
66
72
  <PBCElementsRenderer target={['layout-start']} />
67
73
  <foundation-header
68
- onluminance-icon-clicked={onLuminanceToggle}
69
- onlogout-clicked={() => navigate(`/${AUTH_PATH}`)}
74
+ ref={foundationHeaderRef}
70
75
  show-luminance-toggle-button
71
76
  show-misc-toggle-button
72
77
  routeNavItems={navItems}
@@ -1,20 +1,12 @@
1
- import React, {useEffect} from 'react';
1
+ import React from 'react';
2
2
  import './AuthPage.css';
3
- import { configureFoundationLogin } from "@/share/foundation-login.ts";
4
- import { useNavigate } from "react-router";
5
3
 
6
4
  const AuthPage: React.FC = () => {
7
- const navigate = useNavigate();
8
-
9
- useEffect(() => {
10
- configureFoundationLogin({ navigate });
11
- }, []);
12
-
13
- return (
14
- <section className="auth-page">
15
- <client-app-login></client-app-login>
16
- </section>
17
- );
5
+ return (
6
+ <section className="auth-page">
7
+ <client-app-login></client-app-login>
8
+ </section>
9
+ );
18
10
  };
19
11
 
20
12
  export default AuthPage;
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect, useRef, RouteObject } from 'react';
2
2
  import { deriveElementTag } from './utils';
3
3
  import { useRoutesContext } from '@/store/RoutesContext';
4
- import { useLocation } from 'react-router';
4
+ import { useLocation } from 'react-router-dom';
5
5
 
6
6
  type ExtendedRouteObject = RouteObject & {
7
7
  data?: {
@@ -1,37 +1,28 @@
1
- import { configure, defaultAuthConfig } from '@genesislcap/foundation-auth/config';
1
+ import {configure, define} from '@genesislcap/foundation-login';
2
2
  import { getUser } from '@genesislcap/foundation-user';
3
- import { AUTH_PATH } from '@/config';
4
- import { GENESIS_SOCKET_URL } from '@genesislcap/foundation-utils';
5
- import { Connect } from '@genesislcap/foundation-comms';
6
3
  import { DI } from '@genesislcap/web-core';
7
- import type { NavigateFunction } from 'react-router';
4
+ import { AUTH_PATH } from '@/config';
5
+ import type { Router } from '@/utils/history';
8
6
 
9
7
  /**
10
8
  * Configure the micro frontend
11
9
  */
12
- export const configureFoundationLogin = ({navigate}: { navigate: NavigateFunction}) => {
13
- const baseElement = document.querySelector('base');
14
- const basePath = baseElement?.getAttribute('href') || '';
15
- const connect = DI.getOrCreateDOMContainer().get(Connect);
16
-
17
-
18
- configure({
19
- name: 'client-app-login',
20
- omitRoutes: ['request-account', 'forgot-password'],
21
- fields: {
22
- ...defaultAuthConfig.fields,
23
- username: {
24
- ...defaultAuthConfig.fields.username,
25
- },
10
+ export const configureFoundationLogin = ({ router }:{ router: Router }) => {
11
+ configure(DI.getOrCreateDOMContainer(), {
12
+ autoConnect: true,
13
+ autoAuth: true, // < Allow users to skip login
14
+ showConnectionIndicator: true,
15
+ hostPath: AUTH_PATH,
16
+ redirectHandler: () => {
17
+ // workaround for redirect from foundation-login
18
+ setTimeout(() => {
19
+ const lastPath = getUser().lastPath() ?? '/{{kebabCase routes.[0].name}}';
20
+ router.push(lastPath);
21
+ }, 0);
26
22
  },
27
- hostPath: basePath + AUTH_PATH,
28
- postLoginRedirect: async () => {
29
- const url = GENESIS_SOCKET_URL;
30
- await connect.connect(url);
23
+ });
31
24
 
32
- const redirectUrl = '/{{kebabCase routes.[0].name}}';
33
- navigate(redirectUrl);
34
- },
35
- })
25
+ return define({
26
+ name: `client-app-login`,
27
+ });
36
28
  }
37
-
@@ -1,5 +1,5 @@
1
1
  import React, { createContext, useContext, ReactNode } from 'react';
2
- import { RouteObject, Navigate } from 'react-router';
2
+ import { RouteObject, Navigate } from 'react-router-dom';
3
3
  import { getApp } from '@genesislcap/foundation-shell/app';
4
4
  import AuthPage from '@/pages/AuthPage/AuthPage';
5
5
  import NotFoundPage from '@/pages/NotFoundPage/NotFoundPage';
@@ -0,0 +1,5 @@
1
+ import { createBrowserHistory, History } from 'history';
2
+
3
+ export type Router = History;
4
+
5
+ export const history = createBrowserHistory() as History;
@@ -1,3 +1,4 @@
1
+ export * from './history';
1
2
  export * from './fdc3';
2
3
  export * from './layout';
3
4
  export * from './permissions';
@@ -7,7 +7,7 @@ module.exports = (env, argv) => {
7
7
  const https = process.env.HTTPS === 'true';
8
8
  const open = !(process.env.NO_OPEN === 'true');
9
9
  const environmentFile = mode === 'production'
10
- ? 'environment.prod.ts'
10
+ ? 'environment.prod.ts'
11
11
  : 'environment.ts';
12
12
  const environmentPath = resolve(__dirname, 'src/environments', environmentFile);
13
13
 
@@ -76,20 +76,6 @@ module.exports = (env, argv) => {
76
76
  ],
77
77
  devServer: {
78
78
  server: https ? 'https' : 'http',
79
- proxy: [
80
- {
81
- context: "/sm",
82
- "target": "{{apiHost}}",
83
- "secure": false,
84
- "pathRewrite": {"^/sm": ""},
85
- },
86
- {
87
- context: "/gwf",
88
- "target": "{{apiHost}}",
89
- "secure": false,
90
- "ws": true
91
- }
92
- ],
93
79
  open,
94
80
  static: {
95
81
  directory: join(__dirname, 'public'),
@@ -89,7 +89,6 @@
89
89
  "lint-staged": "^12.4.1"
90
90
  },
91
91
  "dependencies": {
92
- "@genesislcap/foundation-auth": "{{versions.UI}}",
93
92
  "@genesislcap/foundation-comms": "{{versions.UI}}",
94
93
  "@genesislcap/foundation-entity-management": "{{versions.UI}}",
95
94
  "@genesislcap/foundation-events": "{{versions.UI}}",
@@ -118,7 +117,6 @@
118
117
  "tslib": "^2.3.1"
119
118
  },
120
119
  "overrides": {
121
- "@genesislcap/foundation-auth": "{{versions.UI}}",
122
120
  "@genesislcap/foundation-comms": "{{versions.UI}}",
123
121
  "@genesislcap/foundation-entity-management": "{{versions.UI}}",
124
122
  "@genesislcap/foundation-events": "{{versions.UI}}",
@@ -141,7 +139,6 @@
141
139
  "@genesislcap/g2plot-chart": "{{versions.UI}}",
142
140
  "@genesislcap/rapid-design-system": "{{versions.UI}}",
143
141
  "@genesislcap/rapid-grid-pro": "{{versions.UI}}",
144
- "@genesislcap/web-core": "{{versions.UI}}",
145
- "typescript": "5.6.3"
142
+ "@genesislcap/web-core": "{{versions.UI}}"
146
143
  }
147
144
  }
@@ -1,7 +1,5 @@
1
1
  import { getApp } from '@genesislcap/foundation-shell/app';
2
2
  import type { FoundationRouter } from '@genesislcap/foundation-ui';
3
- import { FoundationRouteNav } from '@genesislcap/foundation-ui';
4
- import { PUBLIC_PATH } from '@genesislcap/foundation-utils';
5
3
  import { css, GenesisElementLayout, html } from '@genesislcap/web-core';
6
4
  import type { Store } from '../store';
7
5
 
@@ -44,8 +42,6 @@ export const defaultLayout = new GenesisElementLayout(
44
42
  <foundation-header
45
43
  show-luminance-toggle-button
46
44
  show-misc-toggle-button
47
- @logout-clicked=${(x) =>
48
- FoundationRouteNav.path.push(`${PUBLIC_PATH}/${x.config.loginPath}/logout`)}
49
45
  :routeNavItems=${(x) => x.config.getNavItems()}
50
46
  ></foundation-header>
51
47
  <div class="content">
@@ -1,14 +1,16 @@
1
- import { getUser, navigateTo } from '@genesislcap/foundation-auth';
2
- import { Auth, Connect } from '@genesislcap/foundation-comms';
1
+ import { Auth, Session } from '@genesislcap/foundation-comms';
2
+ import { defaultLoginConfig, LoginConfig } from '@genesislcap/foundation-login';
3
3
  import { FoundationRouterConfiguration } from '@genesislcap/foundation-ui';
4
- import { GENESIS_SOCKET_URL, PUBLIC_PATH } from '@genesislcap/foundation-utils';
4
+ import { PUBLIC_PATH } from '@genesislcap/foundation-utils';
5
+ import { NavigationPhase, optional, Route } from '@genesislcap/web-core';
5
6
  import { defaultLayout, loginLayout } from '../layouts';
6
- import { NotFound } from './not-found/not-found';
7
- import { defaultNotPermittedRoute, NotPermitted } from './not-permitted/not-permitted';
8
- import { LoginSettings } from './types';
7
+ import { logger } from '../utils';
9
8
  {{#each routes}}
10
9
  import { {{pascalCase this.name}} } from './{{kebabCase this.name}}/{{kebabCase this.name}}';
11
10
  {{/each}}
11
+ import { NotFound } from './not-found/not-found';
12
+ import { defaultNotPermittedRoute, NotPermitted } from './not-permitted/not-permitted';
13
+ import { LoginSettings } from './types';
12
14
 
13
15
  // eslint-disable-next-line
14
16
  declare var ENABLE_SSO: string;
@@ -27,13 +29,17 @@ const ssoSettings =
27
29
  const publicPath = typeof PUBLIC_PATH !== 'undefined' ? PUBLIC_PATH : '';
28
30
 
29
31
  export class MainRouterConfig extends FoundationRouterConfiguration<LoginSettings> {
30
- @Connect private connect: Connect;
31
- @Auth private auth: Auth;
32
+ constructor(
33
+ @Auth private auth: Auth,
34
+ @Session private session: Session,
35
+ @optional(LoginConfig)
36
+ private loginConfig: LoginConfig = { ...defaultLoginConfig, autoAuth: true, autoConnect: true },
37
+ ) {
38
+ super();
39
+ }
32
40
 
33
41
  async configure() {
34
42
  this.configureAnalytics();
35
- this.configureRoutePermittedChecks();
36
- this.configureFallbackRouteDefinition();
37
43
  this.title = '{{capitalCase appName}}';
38
44
  this.defaultLayout = defaultLayout;
39
45
 
@@ -46,31 +52,22 @@ export class MainRouterConfig extends FoundationRouterConfiguration<LoginSetting
46
52
  name: 'login',
47
53
  title: 'Login',
48
54
  element: async () => {
49
- const { configure, defaultAuthConfig } = await import(
50
- '@genesislcap/foundation-auth/config'
55
+ const { configure, define } = await import(
56
+ /* webpackChunkName: "foundation-login" */
57
+ '@genesislcap/foundation-login'
51
58
  );
52
- return configure({
53
- omitRoutes: ['request-account', 'forgot-password'],
54
- fields: {
55
- ...defaultAuthConfig.fields,
56
- username: {
57
- ...defaultAuthConfig.fields.username,
58
- pattern: '^[a-zA-Z0-9.@_:-]*$',
59
- },
60
- },
61
- hostPath: this.loginPath,
62
- postLoginRedirect: async () => {
63
- await this.connect.connect(GENESIS_SOCKET_URL);
64
- navigateTo(getUser().lastPath() ?? publicPath + '{{kebabCase routes.[0].name}}');
65
- },
66
- postLogoutRedirect: () => {
67
- if (this.connect.isConnected) {
68
- this.connect.disconnect();
69
- }
70
- defaultAuthConfig.postLogoutRedirect();
71
- },
59
+ configure(this.container, {
60
+ hostPath: 'login',
61
+ autoConnect: true,
62
+ defaultRedirectUrl: publicPath + '{{kebabCase routes.[0].name}}',
72
63
  ...ssoSettings,
73
64
  });
65
+ return define({
66
+ name: `{{rootElement}}-login`,
67
+ /**
68
+ * You can augment the template and styles here when needed.
69
+ */
70
+ });
74
71
  },
75
72
  layout: loginLayout,
76
73
  settings: { public: true },
@@ -106,22 +103,70 @@ export class MainRouterConfig extends FoundationRouterConfiguration<LoginSetting
106
103
  {{/each}}
107
104
  );
108
105
 
106
+ /**
107
+ * Example of a FallbackRouteDefinition
108
+ */
109
+ this.routes.fallback(() =>
110
+ this.auth.isLoggedIn ? { redirect: 'not-found' } : { redirect: authPath },
111
+ );
112
+
113
+ /**
114
+ * Example of a NavigationContributor
115
+ */
109
116
  this.contributors.push({
110
117
  navigate: async (phase) => {
111
118
  const settings = phase.route.settings;
112
119
 
113
120
  /**
114
- * If the route is public or the user is authenticated don't block
121
+ * If public route don't block
115
122
  */
116
- if (settings?.public || this.user.isAuthenticated) {
123
+ if (settings && settings.public) {
117
124
  return;
118
125
  }
119
126
 
120
127
  /**
121
- * Otherwise route them to login
128
+ * If logged in don't block
122
129
  */
123
- this.navigationPhaseLoginRedirect(phase);
130
+ if (this.auth.isLoggedIn) {
131
+ this.redirectIfNotPermitted(settings, phase);
132
+ return;
133
+ }
134
+
135
+ /**
136
+ * If allowAutoAuth and session is valid try to connect+auto-login
137
+ */
138
+ if (this.loginConfig.autoAuth && (await this.reAuthFromSession(settings, phase))) {
139
+ return;
140
+ }
141
+
142
+ /**
143
+ * Otherwise route them somewhere, like to a login
144
+ */
145
+ phase.cancel(() => {
146
+ this.session.captureReturnUrl();
147
+ Route.name.replace(phase.router, authPath);
148
+ });
124
149
  },
125
150
  });
126
151
  }
152
+
153
+ private async reAuthFromSession(settings: LoginSettings, phase: NavigationPhase) {
154
+ return this.auth.reAuthFromSession().then((authenticated) => {
155
+ logger.info(`reAuthFromSession. authenticated: ${authenticated}`);
156
+ if (authenticated) {
157
+ this.redirectIfNotPermitted(settings, phase);
158
+ }
159
+ return authenticated;
160
+ });
161
+ }
162
+
163
+ private redirectIfNotPermitted(settings: LoginSettings, phase: NavigationPhase) {
164
+ const { path } = phase.route.endpoint;
165
+ if (settings?.isPermitted && !settings.isPermitted()) {
166
+ logger.warn(`Not permitted - Redirecting URL from ${path} to ${defaultNotPermittedRoute}.`);
167
+ phase.cancel(() => {
168
+ Route.name.replace(phase.router, defaultNotPermittedRoute);
169
+ });
170
+ }
171
+ }
127
172
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/blank-app-seed",
3
3
  "description": "Genesis Blank App Seed",
4
- "version": "3.41.0",
4
+ "version": "3.41.1",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
7
7
  "release": "semantic-release"
@@ -1,12 +0,0 @@
1
- {
2
- "/sm": {
3
- "target": "{{apiHost}}",
4
- "secure": false,
5
- "pathRewrite": { "^/sm": "" }
6
- },
7
- "/gwf": {
8
- "target": "{{apiHost}}",
9
- "secure": false,
10
- "ws": true
11
- }
12
- }
@@ -1,13 +0,0 @@
1
- package scripts
2
-
3
- router {
4
- webPort = 9064
5
- socketPort = 9065
6
-
7
- cookieAuthentication {
8
- enabled = true
9
- httpOnly = true
10
- secure = false
11
- sameSite = SameSite.Lax
12
- }
13
- }