@genesislcap/foundation-auth 15.19.3 → 15.19.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/dist/dts/routes/config.d.ts.map +1 -1
- package/dist/dts/routes/utils.d.ts +16 -0
- package/dist/dts/routes/utils.d.ts.map +1 -1
- package/dist/dts/routes/utils.test.d.ts +2 -0
- package/dist/dts/routes/utils.test.d.ts.map +1 -0
- package/dist/esm/routes/config.js +15 -1
- package/dist/esm/routes/utils.js +31 -0
- package/dist/esm/routes/utils.test.js +33 -0
- package/dist/foundation-auth.api.json +61 -0
- package/dist/foundation-auth.d.ts +17 -0
- package/package.json +18 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/routes/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/routes/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAGL,mBAAmB,EAEpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAS9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAKxC;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,mBAAmB,CAAC,QAAQ,CAAC;IAEzD,OAAO,CAAC,IAAI;IACP,OAAO,CAAC,SAAS;IAChB,OAAO,CAAC,UAAU;IACjB,OAAO,CAAC,WAAW;gBAHlB,IAAI,EAAE,IAAI,EACL,SAAS,EAAE,SAAS,EACnB,UAAU,EAAE,UAAU,EACrB,WAAW,EAAE,WAAW;IAK/C,SAAS;IA0JT,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC;CAGxC"}
|
|
@@ -27,4 +27,20 @@ export declare function navigateTo(route: AuthRoutes | string): void;
|
|
|
27
27
|
* @public
|
|
28
28
|
*/
|
|
29
29
|
export declare function getRoutePath(route: AuthRoutes | string, hostPath?: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Whether `pathname` lies outside this micro frontend's host path — i.e. it belongs to the
|
|
32
|
+
* HOST application, not to us. Only meaningful for a scoping `hostPath` (embedded use);
|
|
33
|
+
* standalone — `hostPath` empty or `/` — the micro frontend owns every path and this is
|
|
34
|
+
* always false. Both sides are normalised (leading slash on, trailing slash off) before
|
|
35
|
+
* comparing, because `hostPath` is commonly configured without a leading slash
|
|
36
|
+
* (`hostPath: 'auth'` — the documented example) and must scope the same either way.
|
|
37
|
+
* Matching is on segment boundaries, so `/login-history` is outside `/login` while
|
|
38
|
+
* `/login/not-found` is in.
|
|
39
|
+
*
|
|
40
|
+
* @param pathname - The pathname to classify, typically `location.pathname`.
|
|
41
|
+
* @param hostPath - The configured host path, e.g. `/login` or `login`.
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export declare function isOutsideHostPath(pathname: string, hostPath: string): boolean;
|
|
30
46
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/routes/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,QAAQ,GAAE,MAA0B,GAAG,OAAO,CAKvE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,QAGpD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,QAAQ,GAAE,MAAW,GAAG,MAAM,CAQtF"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/routes/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,QAAQ,GAAE,MAA0B,GAAG,OAAO,CAKvE;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,QAGpD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,EAAE,QAAQ,GAAE,MAAW,GAAG,MAAM,CAQtF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAO7E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.test.d.ts","sourceRoot":"","sources":["../../../src/routes/utils.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __awaiter, __decorate, __param } from "tslib";
|
|
2
2
|
import { User } from '@genesislcap/foundation-user';
|
|
3
3
|
import { Container } from '@microsoft/fast-foundation';
|
|
4
|
-
import { RouterConfiguration, Route } from '@microsoft/fast-router';
|
|
4
|
+
import { Ignore, RouterConfiguration, Route, } from '@microsoft/fast-router';
|
|
5
5
|
import { AuthConfig } from '../config/config';
|
|
6
6
|
import { defaultLayout } from '../layouts';
|
|
7
7
|
import { logger } from '../utils';
|
|
@@ -13,6 +13,7 @@ import { RequestAccount } from './request-account/request-account';
|
|
|
13
13
|
import { ResetPassword } from './reset-password/reset-password';
|
|
14
14
|
import { AuthRouting } from './routing';
|
|
15
15
|
import { TermsConditions } from './terms-conditions/terms-conditions';
|
|
16
|
+
import { isOutsideHostPath } from './utils';
|
|
16
17
|
import { Verify } from './verify/verify';
|
|
17
18
|
/**
|
|
18
19
|
* Base implementation of a routing used with the Auth class
|
|
@@ -117,6 +118,19 @@ let AuthRouterConfig = class AuthRouterConfig extends RouterConfiguration {
|
|
|
117
118
|
* Example of a FallbackRouteDefinition
|
|
118
119
|
*/
|
|
119
120
|
this.routes.fallback(() => {
|
|
121
|
+
// The router hears every app-wide URL change, so an unmatched path is not necessarily
|
|
122
|
+
// ours to handle. Embedded in a host application (a non-empty hostPath, e.g. '/login'
|
|
123
|
+
// inside a react-router app), the host's own routes land in this fallback too — most
|
|
124
|
+
// visibly right after a successful login, when the host's post-login navigation races
|
|
125
|
+
// this micro frontend's teardown: an authenticated fallback then rewrote the host's
|
|
126
|
+
// URL to `<hostPath>/not-found`, and the app was stranded on that poisoned URL at its
|
|
127
|
+
// next full reload. A path outside the host path is the host application's business —
|
|
128
|
+
// stand down and navigate nowhere. Standalone (hostPath '') keeps the old behaviour:
|
|
129
|
+
// this micro frontend owns every path there.
|
|
130
|
+
if (!this.parent && isOutsideHostPath(location.pathname, this.authConfig.hostPath)) {
|
|
131
|
+
logger.debug('AuthRouterConfig.routes.fallback. Path outside hostPath, ignoring:', location.pathname);
|
|
132
|
+
return { command: new Ignore() };
|
|
133
|
+
}
|
|
120
134
|
this.user.trackPath();
|
|
121
135
|
const result = this.user.isAuthenticated
|
|
122
136
|
? { redirect: getRoutePath('not-found') }
|
package/dist/esm/routes/utils.js
CHANGED
|
@@ -44,3 +44,34 @@ export function getRoutePath(route, hostPath = '') {
|
|
|
44
44
|
}
|
|
45
45
|
return hostPath ? `${hostPath}/${route}` : route;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Whether `pathname` lies outside this micro frontend's host path — i.e. it belongs to the
|
|
49
|
+
* HOST application, not to us. Only meaningful for a scoping `hostPath` (embedded use);
|
|
50
|
+
* standalone — `hostPath` empty or `/` — the micro frontend owns every path and this is
|
|
51
|
+
* always false. Both sides are normalised (leading slash on, trailing slash off) before
|
|
52
|
+
* comparing, because `hostPath` is commonly configured without a leading slash
|
|
53
|
+
* (`hostPath: 'auth'` — the documented example) and must scope the same either way.
|
|
54
|
+
* Matching is on segment boundaries, so `/login-history` is outside `/login` while
|
|
55
|
+
* `/login/not-found` is in.
|
|
56
|
+
*
|
|
57
|
+
* @param pathname - The pathname to classify, typically `location.pathname`.
|
|
58
|
+
* @param hostPath - The configured host path, e.g. `/login` or `login`.
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
export function isOutsideHostPath(pathname, hostPath) {
|
|
63
|
+
const host = normalizePathname(hostPath);
|
|
64
|
+
if (!host || host === '/') {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const path = normalizePathname(pathname);
|
|
68
|
+
return path !== host && !path.startsWith(`${host}/`);
|
|
69
|
+
}
|
|
70
|
+
/** Leading slash on, trailing slash off; `''` stays `''` so an unset hostPath keeps meaning "owns everything". */
|
|
71
|
+
function normalizePathname(value) {
|
|
72
|
+
if (!value) {
|
|
73
|
+
return '';
|
|
74
|
+
}
|
|
75
|
+
const led = value.startsWith('/') ? value : `/${value}`;
|
|
76
|
+
return led.length > 1 && led.endsWith('/') ? led.slice(0, -1) : led;
|
|
77
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { assert, createLogicSuite } from '@genesislcap/foundation-testing';
|
|
2
|
+
import { isOutsideHostPath } from './utils';
|
|
3
|
+
const Suite = createLogicSuite('isOutsideHostPath');
|
|
4
|
+
Suite('standalone (empty hostPath) owns every path', () => {
|
|
5
|
+
assert.is(isOutsideHostPath('/anything', ''), false);
|
|
6
|
+
assert.is(isOutsideHostPath('/', ''), false);
|
|
7
|
+
});
|
|
8
|
+
Suite('the host path itself and its sub routes are inside', () => {
|
|
9
|
+
assert.is(isOutsideHostPath('/login', '/login'), false);
|
|
10
|
+
assert.is(isOutsideHostPath('/login/not-found', '/login'), false);
|
|
11
|
+
assert.is(isOutsideHostPath('/login/reset-password', '/login'), false);
|
|
12
|
+
});
|
|
13
|
+
Suite('the host application routes are outside', () => {
|
|
14
|
+
// The teardown race this classifier exists for: the host app navigates to its own route
|
|
15
|
+
// right after login, and the fallback must NOT rewrite it to `<hostPath>/not-found`.
|
|
16
|
+
assert.is(isOutsideHostPath('/home', '/login'), true);
|
|
17
|
+
assert.is(isOutsideHostPath('/', '/login'), true);
|
|
18
|
+
});
|
|
19
|
+
Suite('matching is on segment boundaries, not string prefixes', () => {
|
|
20
|
+
assert.is(isOutsideHostPath('/login-history', '/login'), true);
|
|
21
|
+
});
|
|
22
|
+
Suite('hostPath and pathname are normalized (leading/trailing slashes)', () => {
|
|
23
|
+
// The documented configuration style omits the leading slash (`hostPath: 'auth'`) — it
|
|
24
|
+
// must scope identically to `/auth`, or the fallback would ignore its own routes.
|
|
25
|
+
assert.is(isOutsideHostPath('/login', 'login'), false);
|
|
26
|
+
assert.is(isOutsideHostPath('/login/', '/login'), false);
|
|
27
|
+
assert.is(isOutsideHostPath('/login/not-found', 'login/'), false);
|
|
28
|
+
assert.is(isOutsideHostPath('/home', 'login'), true);
|
|
29
|
+
});
|
|
30
|
+
Suite('a root hostPath owns every path, like an empty one', () => {
|
|
31
|
+
assert.is(isOutsideHostPath('/anything', '/'), false);
|
|
32
|
+
});
|
|
33
|
+
Suite.run();
|
|
@@ -11286,6 +11286,67 @@
|
|
|
11286
11286
|
],
|
|
11287
11287
|
"name": "isNackEntity"
|
|
11288
11288
|
},
|
|
11289
|
+
{
|
|
11290
|
+
"kind": "Function",
|
|
11291
|
+
"canonicalReference": "@genesislcap/foundation-auth!isOutsideHostPath:function(1)",
|
|
11292
|
+
"docComment": "/**\n * Whether `pathname` lies outside this micro frontend's host path — i.e. it belongs to the HOST application, not to us. Only meaningful for a scoping `hostPath` (embedded use); standalone — `hostPath` empty or `/` — the micro frontend owns every path and this is always false. Both sides are normalised (leading slash on, trailing slash off) before comparing, because `hostPath` is commonly configured without a leading slash (`hostPath: 'auth'` — the documented example) and must scope the same either way. Matching is on segment boundaries, so `/login-history` is outside `/login` while `/login/not-found` is in.\n *\n * @param pathname - The pathname to classify, typically `location.pathname`.\n *\n * @param hostPath - The configured host path, e.g. `/login` or `login`.\n *\n * @public\n */\n",
|
|
11293
|
+
"excerptTokens": [
|
|
11294
|
+
{
|
|
11295
|
+
"kind": "Content",
|
|
11296
|
+
"text": "export declare function isOutsideHostPath(pathname: "
|
|
11297
|
+
},
|
|
11298
|
+
{
|
|
11299
|
+
"kind": "Content",
|
|
11300
|
+
"text": "string"
|
|
11301
|
+
},
|
|
11302
|
+
{
|
|
11303
|
+
"kind": "Content",
|
|
11304
|
+
"text": ", hostPath: "
|
|
11305
|
+
},
|
|
11306
|
+
{
|
|
11307
|
+
"kind": "Content",
|
|
11308
|
+
"text": "string"
|
|
11309
|
+
},
|
|
11310
|
+
{
|
|
11311
|
+
"kind": "Content",
|
|
11312
|
+
"text": "): "
|
|
11313
|
+
},
|
|
11314
|
+
{
|
|
11315
|
+
"kind": "Content",
|
|
11316
|
+
"text": "boolean"
|
|
11317
|
+
},
|
|
11318
|
+
{
|
|
11319
|
+
"kind": "Content",
|
|
11320
|
+
"text": ";"
|
|
11321
|
+
}
|
|
11322
|
+
],
|
|
11323
|
+
"fileUrlPath": "src/routes/utils.ts",
|
|
11324
|
+
"returnTypeTokenRange": {
|
|
11325
|
+
"startIndex": 5,
|
|
11326
|
+
"endIndex": 6
|
|
11327
|
+
},
|
|
11328
|
+
"releaseTag": "Public",
|
|
11329
|
+
"overloadIndex": 1,
|
|
11330
|
+
"parameters": [
|
|
11331
|
+
{
|
|
11332
|
+
"parameterName": "pathname",
|
|
11333
|
+
"parameterTypeTokenRange": {
|
|
11334
|
+
"startIndex": 1,
|
|
11335
|
+
"endIndex": 2
|
|
11336
|
+
},
|
|
11337
|
+
"isOptional": false
|
|
11338
|
+
},
|
|
11339
|
+
{
|
|
11340
|
+
"parameterName": "hostPath",
|
|
11341
|
+
"parameterTypeTokenRange": {
|
|
11342
|
+
"startIndex": 3,
|
|
11343
|
+
"endIndex": 4
|
|
11344
|
+
},
|
|
11345
|
+
"isOptional": false
|
|
11346
|
+
}
|
|
11347
|
+
],
|
|
11348
|
+
"name": "isOutsideHostPath"
|
|
11349
|
+
},
|
|
11289
11350
|
{
|
|
11290
11351
|
"kind": "Function",
|
|
11291
11352
|
"canonicalReference": "@genesislcap/foundation-auth!isQueryParams:function(1)",
|
|
@@ -2143,6 +2143,23 @@ export declare function isNackDTO(dto: unknown): dto is NACK;
|
|
|
2143
2143
|
*/
|
|
2144
2144
|
export declare function isNackEntity(entity: unknown): entity is Nack;
|
|
2145
2145
|
|
|
2146
|
+
/**
|
|
2147
|
+
* Whether `pathname` lies outside this micro frontend's host path — i.e. it belongs to the
|
|
2148
|
+
* HOST application, not to us. Only meaningful for a scoping `hostPath` (embedded use);
|
|
2149
|
+
* standalone — `hostPath` empty or `/` — the micro frontend owns every path and this is
|
|
2150
|
+
* always false. Both sides are normalised (leading slash on, trailing slash off) before
|
|
2151
|
+
* comparing, because `hostPath` is commonly configured without a leading slash
|
|
2152
|
+
* (`hostPath: 'auth'` — the documented example) and must scope the same either way.
|
|
2153
|
+
* Matching is on segment boundaries, so `/login-history` is outside `/login` while
|
|
2154
|
+
* `/login/not-found` is in.
|
|
2155
|
+
*
|
|
2156
|
+
* @param pathname - The pathname to classify, typically `location.pathname`.
|
|
2157
|
+
* @param hostPath - The configured host path, e.g. `/login` or `login`.
|
|
2158
|
+
*
|
|
2159
|
+
* @public
|
|
2160
|
+
*/
|
|
2161
|
+
export declare function isOutsideHostPath(pathname: string, hostPath: string): boolean;
|
|
2162
|
+
|
|
2146
2163
|
/**
|
|
2147
2164
|
* isQueryParams.
|
|
2148
2165
|
* @param params - Potential QueryParams.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genesislcap/foundation-auth",
|
|
3
3
|
"description": "Genesis Foundation Auth",
|
|
4
|
-
"version": "15.19.
|
|
4
|
+
"version": "15.19.4",
|
|
5
5
|
"license": "SEE LICENSE IN license.txt",
|
|
6
6
|
"main": "dist/esm/index.js",
|
|
7
7
|
"types": "dist/foundation-auth.d.ts",
|
|
@@ -134,25 +134,25 @@
|
|
|
134
134
|
}
|
|
135
135
|
},
|
|
136
136
|
"devDependencies": {
|
|
137
|
-
"@genesislcap/foundation-testing": "15.19.
|
|
138
|
-
"@genesislcap/genx": "15.19.
|
|
139
|
-
"@genesislcap/rollup-builder": "15.19.
|
|
140
|
-
"@genesislcap/ts-builder": "15.19.
|
|
141
|
-
"@genesislcap/uvu-playwright-builder": "15.19.
|
|
142
|
-
"@genesislcap/vite-builder": "15.19.
|
|
143
|
-
"@genesislcap/webpack-builder": "15.19.
|
|
137
|
+
"@genesislcap/foundation-testing": "15.19.4",
|
|
138
|
+
"@genesislcap/genx": "15.19.4",
|
|
139
|
+
"@genesislcap/rollup-builder": "15.19.4",
|
|
140
|
+
"@genesislcap/ts-builder": "15.19.4",
|
|
141
|
+
"@genesislcap/uvu-playwright-builder": "15.19.4",
|
|
142
|
+
"@genesislcap/vite-builder": "15.19.4",
|
|
143
|
+
"@genesislcap/webpack-builder": "15.19.4"
|
|
144
144
|
},
|
|
145
145
|
"dependencies": {
|
|
146
|
-
"@genesislcap/foundation-comms": "15.19.
|
|
147
|
-
"@genesislcap/foundation-events": "15.19.
|
|
148
|
-
"@genesislcap/foundation-i18n": "15.19.
|
|
149
|
-
"@genesislcap/foundation-logger": "15.19.
|
|
150
|
-
"@genesislcap/foundation-state-machine": "15.19.
|
|
151
|
-
"@genesislcap/foundation-store": "15.19.
|
|
152
|
-
"@genesislcap/foundation-ui": "15.19.
|
|
153
|
-
"@genesislcap/foundation-user": "15.19.
|
|
154
|
-
"@genesislcap/foundation-utils": "15.19.
|
|
155
|
-
"@genesislcap/foundation-zero": "15.19.
|
|
146
|
+
"@genesislcap/foundation-comms": "15.19.4",
|
|
147
|
+
"@genesislcap/foundation-events": "15.19.4",
|
|
148
|
+
"@genesislcap/foundation-i18n": "15.19.4",
|
|
149
|
+
"@genesislcap/foundation-logger": "15.19.4",
|
|
150
|
+
"@genesislcap/foundation-state-machine": "15.19.4",
|
|
151
|
+
"@genesislcap/foundation-store": "15.19.4",
|
|
152
|
+
"@genesislcap/foundation-ui": "15.19.4",
|
|
153
|
+
"@genesislcap/foundation-user": "15.19.4",
|
|
154
|
+
"@genesislcap/foundation-utils": "15.19.4",
|
|
155
|
+
"@genesislcap/foundation-zero": "15.19.4",
|
|
156
156
|
"@microsoft/fast-components": "2.30.6",
|
|
157
157
|
"@microsoft/fast-element": "1.14.0",
|
|
158
158
|
"@microsoft/fast-foundation": "2.50.0",
|